2

As per my requirement, I want to import CSV into my custom table, for that i have reviewed the following URL http://www.blogtreat.com/how-to-import-csv-file-to-custom-module-table-in-magento-2/

In this, while uploading the CSV file and hit the check data, the file is validating after that it's showing an import button, but when i hit the import button, nothing is happening.

enter image description here

class Imageimport extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
{
    const ID = 'id';
    const PRODUCT_SKU = 'product_sku';
    const PRODUCT_MAIN_IMAGE = 'product_main_image';
    const TIME = 'time';
    const TABLE_ENTITY = 'product_image_import';
    /**
     * Validation failure message template definitions
     *
     * @var array
     */
    protected $_messageTemplates = [
        ValidatorInterface::ERROR_ID_IS_EMPTY => 'Empty',
    ];

    protected $_permanentAttributes = [self::ID];

    /**
     * If we should check column names
     *
     * @var bool
     */
    protected $needColumnCheck = true;

    /**
     * Valid column names
     *
     * @array
     */
    protected $validColumnNames = [
        self::ID,
        self::PRODUCT_SKU,
        self::PRODUCT_MAIN_IMAGE,
    ];

    /**
     * Need to log in import history
     *
     * @var bool
     */
    protected $logInHistory = true;

    protected $_validators = [];

    /**
     * @var \Magento\Framework\Stdlib\DateTime\DateTime
     */
    protected $_connection;

    protected $_resource;

    /**
     * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
     */
    public function __construct(
        \Magento\Framework\Json\Helper\Data $jsonHelper,
        \Magento\ImportExport\Helper\Data $importExportData,
        \Magento\ImportExport\Model\ResourceModel\Import\Data $importData,
        \Magento\Framework\App\ResourceConnection $resource,
        \Magento\ImportExport\Model\ResourceModel\Helper $resourceHelper,
        \Magento\Framework\Stdlib\StringUtils $string,
        ProcessingErrorAggregatorInterface $errorAggregator
    ) {
        $this->jsonHelper = $jsonHelper;
        $this->_importExportData = $importExportData;
        $this->_resourceHelper = $resourceHelper;
        $this->_dataSourceModel = $importData;
        $this->_resource = $resource;
        $this->_connection = $resource->getConnection(\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION);
        $this->errorAggregator = $errorAggregator;
    }

    public function getValidColumnNames() {
        return $this->validColumnNames;
    }

    /**
     * Entity type code getter.
     *
     * @return string
     */
    public function getEntityTypeCode() {
        return 'product_image_import';
    }

    /**
     * Row validation.
     *
     * @param array $rowData
     * @param int $rowNum
     * @return bool
     */
    public function validateRow(array $rowData, $rowNum) {
        $title = false;
        if (isset($this->_validatedRows[$rowNum])) {
            return !$this->getErrorAggregator()->isRowInvalid($rowNum);
        }

        $this->_validatedRows[$rowNum] = true;

        if (!isset($rowData[self::ID]) || empty($rowData[self::ID])) {
            $this->addRowError(ValidatorInterface::ERROR_MESSAGE_IS_EMPTY, $rowNum);
            return false;
        }
        return !$this->getErrorAggregator()->isRowInvalid($rowNum);
    }

    /**
     * Create advanced question data from raw data.
     *
     * @throws \Exception
     * @return bool Result of operation.
     */
    protected function _importData() {
        if (\Magento\ImportExport\Model\Import::BEHAVIOR_DELETE == $this->getBehavior()) {
            $this->deleteEntity();
        } elseif (\Magento\ImportExport\Model\Import::BEHAVIOR_REPLACE == $this->getBehavior()) {
            $this->replaceEntity();
        } elseif (\Magento\ImportExport\Model\Import::BEHAVIOR_APPEND == $this->getBehavior()) {
            $this->saveEntity();
        }
        return true;
    }

    /**
     * Save question
     *
     * @return $this
     */
    public function saveEntity() {
        $this->saveAndReplaceEntity();
        return $this;
    }

    /**
     * Replace question
     *
     * @return $this
     */
    public function replaceEntity() {
        $this->saveAndReplaceEntity();
        return $this;
    }

    /**
     * Deletes question data from raw data.
     *
     * @return $this
     */
    public function deleteEntity() {
        $ids = [];
        while ($bunch = $this->_dataSourceModel->getNextBunch()) {
            foreach ($bunch as $rowNum => $rowData) {
                $this->validateRow($rowData, $rowNum);
                if (!$this->getErrorAggregator()->isRowInvalid($rowNum)) {
                    $rowId = $rowData[self::ID];
                    $ids[] = $rowId;
                }
                if ($this->getErrorAggregator()->hasToBeTerminated()) {
                    $this->getErrorAggregator()->addRowToSkip($rowNum);
                }
            }
        }
        if ($ids) {
            $this->deleteEntityFinish(array_unique($ids),self::TABLE_ENTITY);
        }
        return $this;
    }

    /**
     * Save and replace question
     *
     * @return $this
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    protected function saveAndReplaceEntity() {
        $behavior = $this->getBehavior();
        $ids = [];
        while ($bunch = $this->_dataSourceModel->getNextBunch()) {
            $entityList = [];
            $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/templog.log');
            $logger = new \Zend\Log\Logger();
            $logger->addWriter($writer);

            $logger->info(print_r($bunch,1));
            foreach ($bunch as $rowNum => $rowData) {
                if (!$this->validateRow($rowData, $rowNum)) {
                    $this->addRowError(ValidatorInterface::ERROR_MESSAGE_IS_EMPTY, $rowNum);
                    continue;
                }
                if ($this->getErrorAggregator()->hasToBeTerminated()) {
                    $this->getErrorAggregator()->addRowToSkip($rowNum);
                    continue;
                }
                $rowId= $rowData[self::ID];
                $ids[] = $rowId;
                $entityList[$rowId][] = [
                  self::ID => $rowData[self::ID],
                  self::PRODUCT_SKU => $rowData[self::PRODUCT_SKU],
                  self::PRODUCT_MAIN_IMAGE => $rowData[self::PRODUCT_MAIN_IMAGE],
                ];
            }
            $logger->info(print_r($entityList,1));
            if (\Magento\ImportExport\Model\Import::BEHAVIOR_REPLACE == $behavior) {
                if ($ids) {
                    if ($this->deleteEntityFinish(array_unique(  $ids), self::TABLE_ENTITY)) {
                        $this->saveEntityFinish($entityList, self::TABLE_ENTITY);
                    }
                }
            } elseif (\Magento\ImportExport\Model\Import::BEHAVIOR_APPEND == $behavior) {
                $this->saveEntityFinish($entityList, self::TABLE_ENTITY);
            }

        }
        return $this;
    }

    /**
     * Save question
     *
     * @param array $priceData
     * @param string $table
     * @return $this
     */
    protected function saveEntityFinish(array $entityData, $table) {
        if ($entityData) {
            $tableName = $this->_connection->getTableName($table);
            $entityIn = [];
            foreach ($entityData as $id => $entityRows) {
                    foreach ($entityRows as $row) {
                        $entityIn[] = $row;
                    }
            }
            if ($entityIn) {
                $this->_connection->insertOnDuplicate($tableName, $entityIn,[
                self::ID,
                self::PRODUCT_SKU,
                self::PRODUCT_MAIN_IMAGE
            ]);
            }
        }
        return $this;
    }

    protected function deleteEntityFinish(array $ids, $table) {

        if ($table && $ids) {
            try {
                $this->countItemsDeleted += $this->_connection->delete(
                    $this->_connection->getTableName($table),
                    $this->_connection->quoteInto('id IN (?)', $ids)
                );
                return true;
            } catch (\Exception $e) {
                return false;
            }
        } else {
            return false;
        }
    }

Kindly check and let me know your thoughts and ideab, it will help me to resolve the issue

  • will it be able to reach your import controller. Check that first, to do so, go to your import controller file and print something and exit or die it. – John Oct 17 '18 at 11:32
  • @John, There is no request sending to a controller and anywhere, i followed the above mentioned link, kindly check and share your idea – senthil Oct 17 '18 at 11:34
  • in your customimport.php file, have you change these data ? const ID = 'entity_id'; const QUESTION = 'question'; const DATE = 'create_at'; const TABLE_ENTITY = 'faq'; – John Oct 17 '18 at 11:40
  • Yes, I have changed as follows const ID = 'id'; const PRODUCT_SKU = 'product_sku'; const PRODUCT_MAIN_IMAGE = 'product_main_image'; const TABLE_Entity = 'product_image_import'; and changed everywhere in that file – senthil Oct 17 '18 at 11:43
  • on the same file, check if the data passed correctly to this function saveAndReplaceEntity() – John Oct 17 '18 at 11:49
2

First create a Import Button in your Ui-component File

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

uiComponenetFileName.xml

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Ui/etc/ui_configuration.xsd">

            <!-- main part of the grid -->
                <argument name="data" xsi:type="array">
                   <!-- define  date source -->
                <item name="js_config" xsi:type="array">
                    <item name="provider" xsi:type="string">locator_record_locator_list.locator_record_locator_list_data_source</item>
                    <item name="deps" xsi:type="string">locator_record_locator_list.locator_record_locator_list_data_source</item>
                </item>
                <!-- for columns -->
                <item name="spinner" xsi:type="string">locator_records_columns</item>
                <!--  for Add new record button  -->
                <item name="buttons" xsi:type="array">
                    <item name="add" xsi:type="array">
                        <item name="name" xsi:type="string">add</item>
                        <item name="label" xsi:type="string" translate="true">Add New Location</item>
                        <item name="class" xsi:type="string">primary</item>
                        <item name="url" xsi:type="string">*/*/addlocation</item>
                        <item name="sortOrder" xsi:type="number">10</item>
                    </item>
                    <item name="import" xsi:type="array">
                        <item name="name" xsi:type="string">import</item>
                        <item name="label" xsi:type="string" translate="true">Import Locatore</item>
                        <item name="class" xsi:type="string">secondary</item>
                        <item name="url" xsi:type="string">*/dataimport/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 locatore</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>
                </item>
            </argument>
.........................
.........................
.........................

Now this Import Button Call Import Data Form

[vendor_name] \ [module_name] \Controller\Adminhtml\Dataimport

Importdata.php

<?php

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

use Magento\Framework\Controller\ResultFactory;

class Importdata extends \Magento\Backend\App\Action
{
    private $coreRegistry;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\Registry $coreRegistry
    ) {                                 

       parent::__construct($context);
       $this->coreRegistry = $coreRegistry;
    }

    public function execute()
    {
        $rowData = $this->_objectManager->create('[vendor_name] \ [module_name] \Model\Locator');
        $this->coreRegistry->register('row_data', $rowData);
        $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
        $resultPage->getConfig()->getTitle()->prepend(__('Import Locator Data'));
        return $resultPage;
    }

    // used for acl.xml
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('[vendor_name]_[module_name]::add_datalocation');
    }
}

create a Layout File which Call your Block File

[vendor_name] \ [module_name] \view\adminhtml\layout

[controller_name]_dataimport_importdata.xml

<?xml version="1.0"?>

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
           <block class="[vendor_name] \ [module_name] \Block\Adminhtml\Dataimport\Importdata" name="importdata_locator" />
        </referenceContainer>
    </body>
</page>

create a block File for Import Data Form

[vendor_name] \ [module_name] \Block\Adminhtml\Dataimport

Importdata.php

<?php 

namespace [vendor_name] \ [module_name] \Block\Adminhtml\Dataimport;

class Importdata extends \Magento\Backend\Block\Widget\Form\Container
{
    protected $_coreRegistry = null;

    public function __construct(
        \Magento\Backend\Block\Widget\Context $context,
        \Magento\Framework\Registry $registry,
        array $data = []
    ) {
        $this->_coreRegistry = $registry;
        parent::__construct($context, $data);
    }

    protected function _construct()
    {
        $this->_objectId = 'row_id';
        $this->_blockGroup = '[module_name]_[vendor_name]';
        $this->_controller = 'adminhtml_dataimport';
        parent::_construct();
        $this->buttonList->remove('back');
        $this->buttonList->update('save', 'label', __('Import'));
        $this->buttonList->remove('reset');

        $this->addButton(
                    'backhome',
                    [
                        'label' => __('Back'),
                        'on_click' => sprintf("location.href = '%s';", $this->getUrl('[route_name] / [controller_name] /index')),
                        'class' => 'back',
                        'level' => -2
                    ]
                );


    }


    public function getHeaderText()
    {
        return __('Import Location Data');
    }

    protected function _isAllowedAction($resourceId)
    {
        return $this->_authorization->isAllowed($resourceId);
    }


    public function getFormActionUrl()
    {
        if ($this->hasFormActionUrl()) {
            return $this->getData('form_action_url');
        }
        return $this->getUrl('[route_name] / dataimport/save');
    }
}

the above file call import form

[vendor_name] \ [module_name] \Block\Adminhtml\Dataimport\Edit

Form.php

<?php

namespace [vendor_name] \ [module_name] \Block\Adminhtml\Dataimport\Edit;

use Magento\Framework\View\Asset\Repository; 

class Form extends \Magento\Backend\Block\Widget\Form\Generic
{
    protected $_assetRepo;

    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Data\FormFactory $formFactory,
        \Magento\Framework\View\Asset\Repository $assetRepo,
        array $data = []
    ) {   
        parent::__construct($context, $registry, $formFactory, $data);
    }


    protected function _prepareForm()
    {   
        $path = $this->_assetRepo->getUrl("[vendor_name]_[module_name]::img/[vendor_name]_[module_name]_Sample_File.csv");

        $model = $this->_coreRegistry->registry('row_data');

        $form = $this->_formFactory->create(
            ['data' => [
                            'id' => 'edit_form',
                            'enctype' => 'multipart/form-data',
                            'action' => $this->getData('action'),
                            'method' => 'post'
                        ]
            ]
        );

        $form->setHtmlIdPrefix('datalocation_');

           $fieldset = $form->addFieldset(
                'base_fieldset',
                ['legend' => __('Import Location '), 'class' => 'fieldset-wide']
            );

       $importdata_script =  $fieldset->addField(
            'importdata',
            'file', 
                array(
                        'label'     => 'Upload File',
                        'required'  => true,
                        'name'      => 'importdata',  
                        'note' => 'Allow File type: .csv and .xls', 
                     )
        );

        $importdata_script->setAfterElementHtml("   

        <span id='sample-file-span' ><a id='sample-file-link' href='".$path."'  >Download Sample File</a></span>

            <script type=\"text/javascript\">

            document.getElementById('[route_name]_importdata').onchange = function () { 

                var fileInput = document.getElementById('[route_name]_importdata');

                var filePath = fileInput.value;

                var allowedExtensions = /(\.csv|\.xls)$/i; 

                if(!allowedExtensions.exec(filePath))
                {
                    alert('Please upload file having extensions .csv or .xls only.');
                    fileInput.value = '';
                }

            };

            </script>"
        );


        $form->setValues($model->getData());
        $form->setUseContainer(true);
        $this->setForm($form);

        return parent::_prepareForm();
    }

}

this import form check whether file is valid or not, now create file which read your uploaded file and insert into table .

[vendor_name] \ [module_name] \Controller\Adminhtml\Dataimport*

Save.php

<?php

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

use Magento\Backend\App\Action;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Filesystem;
use Magento\MediaStorage\Model\File\UploaderFactory;
use Magento\Framework\Image\AdapterFactory;
use Magento\Store\Model\ScopeInterface; 


class Save extends \Magento\Backend\App\Action
{

    protected $fileSystem;

    protected $uploaderFactory;

    protected $request;

    protected $adapterFactory;


    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\Filesystem $fileSystem,
        \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory,
        \Magento\Framework\App\RequestInterface $request,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        AdapterFactory $adapterFactory

    ) {
        parent::__construct($context);
        $this->fileSystem = $fileSystem;
        $this->request = $request;
        $this->scopeConfig = $scopeConfig;
        $this->adapterFactory = $adapterFactory;
        $this->uploaderFactory = $uploaderFactory;
    }

    public function execute()
    { 

         if ( (isset($_FILES['importdata']['name'])) && ($_FILES['importdata']['name'] != '') ) 
         {
            try 
           {    
                $uploaderFactory = $this->uploaderFactory->create(['fileId' => 'importdata']);
                $uploaderFactory->setAllowedExtensions(['csv', 'xls']);
                $uploaderFactory->setAllowRenameFiles(true);
                $uploaderFactory->setFilesDispersion(true);

                $mediaDirectory = $this->fileSystem->getDirectoryRead(DirectoryList::MEDIA);
                $destinationPath = $mediaDirectory->getAbsolutePath('[vendor_name]_[module_name]_IMPORTDATA');

                $result = $uploaderFactory->save($destinationPath);

                if (!$result) 
                   {
                     throw new LocalizedException
                     (
                        __('File cannot be saved to path: $1', $destinationPath)
                     );

                   }
                else
                    {   
                        $imagePath = '[vendor_name]_[module_name]_IMPORTDATA'.$result['file'];

                        $mediaDirectory = $this->fileSystem->getDirectoryRead(DirectoryList::MEDIA);

                        $destinationfilePath = $mediaDirectory->getAbsolutePath($imagePath);

                        /* file read operation */

                        $f_object = fopen($destinationfilePath, "r");

                        $column = fgetcsv($f_object);

                        // column name must be same as the Sample file name 

                        if($f_object)
                        {
                            if( ($column[0] == 'Col_name_1') && ($column[1] == 'Col_name_2') && ($column[2] == 'Col_name_3') && ($column[3] == 'Col_name_4') && ($column[4] == 'Col_name_5') )
                            {   

                                $count = 0;

                                while (($columns = fgetcsv($f_object)) !== FALSE) 
                                {

                                    $rowData = $this->_objectManager->create('Dolphin\Storelocator\Model\Storelocator');

                                    if($columns[0] != 'Col_name_1')// unique Name like Primary key
                                    {   
                                        $count++;

                                    /// here this are all the Getter Setter Method which are call to set value 
                                    // the auto increment column name not used to set value 

                                        $rowData->setCol_name_1($columns[1]);

                                        $rowData->setCol_name_2($columns[2]);

                                        $rowData->setCol_name_3($columns[3]);

                                        $rowData->setCol_name_4($columns[4]);

                                        $rowData->setCol_name_5($columns[5]);

                                        $rowData->save();   

                                    }

                                } 

                            $this->messageManager->addSuccess(__('A total of %1 record(s) have been Added.', $count));
                            $this->_redirect('[route_name]/[controller_name]/index');
                            }
                            else
                            {
                                $this->messageManager->addError(__("invalid Formated File"));
                                $this->_redirect('[route_name]/dataimport/importdata');
                            }

                        } 
                        else
                        {
                            $this->messageManager->addError(__("File hase been empty"));
                            $this->_redirect('[route_name]/dataimport/importdata');
                        }

                    }                   

           } 
           catch (\Exception $e) 
          {   
               $this->messageManager->addError(__($e->getMessage()));
               $this->_redirect('[controller_name]/dataimport/importdata');
          }

         }
         else
         {
            $this->messageManager->addError(__("Please try again."));
            $this->_redirect('[controller_name]/dataimport/importdata');
         }
    }
}

Now you can Click on the Import Button and upload .csv file and import data.

I Hope This Helps You.

| improve this answer | |
  • if anyone have any doubt please ask here I will give you right Solution – Msquare Oct 13 '19 at 5:58
  • where do you put the XML in your first step? – AdRock Nov 15 '19 at 13:50
  • @AdRock I put remaining XML. If you have a any other doubt you can ask me. – Msquare Nov 15 '19 at 17:54
  • will you please help me please where to look that import button in admin @Msquare – Prits Aug 19 at 13:42
  • yes that is process of putting import button in admin in this post. please follow – Msquare Aug 19 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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