4

I need to create a file in mangento 2 admin.

I'm using a button to get in a controller route.

My form ui component:

<item name="buttons" xsi:type="array">
            <item name="save" xsi:type="string">Vendor\Module\Block\Adminhtml\Report\Edit\ExportButton</item>
</item>

I used a dummy data provider just for use the submit url:

<dataSource name="bvz_report_specifier_form_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Vendor\Module\Ui\Component\Form\DummyDataProvider</argument>
            <argument name="name" xsi:type="string">bvz_report_specifier_form_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">entity_id</argument>
            <argument name="requestFieldName" xsi:type="string">entity_id</argument>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="submit_url" xsi:type="url" path="*/*/export"/>
                </item>
            </argument>
        </argument>
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
            </item>
        </argument>
    </dataSource>

In Vendor/Module/Controller/Adminhtml/Index/Export I creat an csv file and save it and put the name of file in URL.

Now I need to download this file when the page refresh.

In the index controller I have this code to make the download:

if($fileName = $this->getRequest()->getParam('file')){

            $url = $mediaUrl = $this ->_storeManager-> getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA );
            $resultRedirect = $this->resultRedirectFactory->create();
            return $resultRedirect->setUrl($url.$fileName);
        }

The download happens but my page goes to infinite load. enter image description here

2 Answers 2

2

So I think this is caused by the response body being empty when it contains a downloadable link. However, when I added dummy content to the response the spinner still wouldn't disappear 🤷

I did manage to resolve this by returning \Magento\Framework\App\Response\Http\FileFactory::create in my admin controller:

return $this->fileFactory->create(
    $fileName,
    [
        'type' => 'filename',
        'value' => $filePath,
        'rm' => true  // can delete file after use
    ],
    DirectoryList::VAR_DIR,
    'text/csv'
);

Then implementing a bit of JS in app/code/MyTestProject/Ui/view/base/requirejs-config.js:

var config = {
    config: {
        mixins: {
            'Magento_Ui/js/form/client': {
                'MyTestProject_Ui/js/form/client-mixin': true
            },
        }
    }
};

And app/code/MyTestProject/Ui/view/base/web/js/form/client-mixin.js:

define([
    'jquery',
    'underscore',
    'mageUtils',
], function ($, _, utils) {
    'use strict';

    return function (OriginalClient) {
        return OriginalClient.extend({
            /**
             * Save data.
             *
             * @param {Object} data
             * @param {Object} options
             * @returns {Object}
             * @private
             */
            _save: function(data, options) {
                var url = this.urls.save;

                $('body').trigger('processStart');
                options = options || {};

                if (!options.redirect) {
                    url += 'back/edit';
                }

                if (options.ajaxSave) {
                    utils.ajaxSubmit({
                        url: url,
                        data: data
                    }, options);

                    return this;
                }

                utils.submit({
                    url: url,
                    data: data
                }, options.attributes);

                // CUSTOMISATION BEGINS HERE
                if (options.attributes.id === "test_csv_generating_form") {
                    $('body').trigger('processStop');
                }
                // CUSTOMISATION ENDS HERE

                return this;
            }
        });
    }
});

You'll have to replace "test_csv_generating_form" in the example above with the name of your UI component XML file.

This has been tested and works in Magento 2.4.3-p1.

0

I crate a Admin Grid using Ui-Component.

You want all Data you have create a Custom Export Button that export your all data.

edit in your Ui-Component file where Admin Grid Show

[vendor_name] \ [module_name] \view\adminhtml\ui_component

Add this code to add Button into Admin Grid

Ui-ComponentFIleName.xml

<item name="import" xsi:type="array">
    <item name="name" xsi:type="string">import</item>
    <item name="label" xsi:type="string" translate="true">Import</item>
    <item name="class" xsi:type="string">secondary</item>
    <item name="url" xsi:type="string">*/*/importdata</item>
    <item name="sortOrder" xsi:type="number">20</item>
</item>

<item name="export" xsi:type="array">
    <item name="name" xsi:type="string">export</item>
    <item name="label" xsi:type="string" translate="true">Export</item>
    <item name="class" xsi:type="string">secondary</item>
    <item name="url" xsi:type="string">*/*/exportdata</item>
    <item name="sortOrder" xsi:type="number">30</item>
</item>

Now create a File that Export or Import Data. File Name must be same as you define in Ui-Component file

  <item name="url" xsi:type="string">*/*/exportdata</item>

  <item name="url" xsi:type="string">*/*/importdata</item>

File path must be like this

[vendor_name] \ [module_name] \ Controller \ Adminhtml \ [Controller_name] \ Exportdata.php

Exportdata.php

<?php

namespace [vendor_name]\[module_name]\Controller\Adminhtml\[Controller_name];

use Magento\Framework\App\Filesystem\DirectoryList;


class Exportdata extends \Magento\Backend\App\Action
{
    protected $uploaderFactory;

    protected $_locationFactory; 

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
        \Magento\Framework\Filesystem $filesystem,
        \[vendor_name]\[module_name]\Model\locatorFactory $locationFactory // This is returns Collaction of Data

    ) {
       parent::__construct($context);
       $this->_fileFactory = $fileFactory;
       $this->_locationFactory = $locationFactory;
       $this->directory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR); // VAR Directory Path
       parent::__construct($context);
    }

    public function execute()
    {   
        $name = date('m-d-Y-H-i-s');
        $filepath = 'export/export-data-' .$name. '.csv'; // at Directory path Create a Folder Export and FIle
        $this->directory->create('export');

        $stream = $this->directory->openFile($filepath, 'w+');
        $stream->lock();

        //column name dispay in your CSV 

        $columns = ['Col-1-name','Col-2-name','Col-3-name','Col-4-name','Col-5-name','Col-6-name','Col-7-name','Col-8-name','Col-9-name',];

            foreach ($columns as $column) 
            {
                $header[] = $column; //storecolumn in Header array
            }

        $stream->writeCsv($header);

        $location = $this->_locationFactory->create();
        $location_collection = $location->getCollection(); // get Collection of Table data 

        foreach($location_collection as $item){

            $itemData = [];

            // column name must same as in your Database Table 

            $itemData[] = $item->getData('col-1-name');
            $itemData[] = $item->getData('col-2-name');
            $itemData[] = $item->getData('col-3-name');
            $itemData[] = $item->getData('col-4-name');
            $itemData[] = $item->getData('col-5-name');
            $itemData[] = $item->getData('col-6-name');
            $itemData[] = $item->getData('col-7-name');
            $itemData[] = $item->getData('col-8-name');
            $itemData[] = $item->getData('col-9-name');

            $stream->writeCsv($itemData);

        }

        $content = [];
        $content['type'] = 'filename'; // must keep filename
        $content['value'] = $filepath;
        $content['rm'] = '1'; //remove csv from var folder

        $csvfilename = 'locator-import-'.$name.'.csv';
        return $this->_fileFactory->create($csvfilename, $content, DirectoryList::VAR_DIR);

    }


}

Now you can Click on the Export Button and See your .csv file Downloaded below.

I Hope This Helps You.

1
  • he asks about the loading infinitive not about the download part so your answer doesn't help
    – Tiikeri
    Commented Mar 8, 2021 at 13:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.