Bhaveshpp

Professional Magento Developr - Healp eachother to grow

Magento2: How to add custom export button on product grid

21 Jul 2021 » magento2

app\code\Bhaveshpp\Export\view\adminhtml\ui_component\product_listing.xml


<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <listingToolbar name="listing_top">
        <exportButton class="Bhaveshpp\Export\Component\Export" name="export_button"/>
    </listingToolbar>
</listing>


\app\code\Bhaveshpp\Export\Component\Export.php


namespace Tecksky\Export\Component;
use Magento\Ui\Component\ExportButton;

/**
 * Class Export
 */
class Export extends ExportButton
{
    /**
     * Overwrite prepare method of class ExportButton
     * to prepare Export
     *
     * @return void
     */
    public function prepare()
    {
        $context = $this->getContext();
        $config = $this->getData('config');
        $config['options'] = [
            [
                'value' => 'nivoda',
                'label' => __('Nivoda CSV'),
                'url' => $this->urlBuilder->getUrl('export_product/export',['type'=>"nivoda"])
            ],
            [
                'value' => 'vdb',
                'label' => __('Vdb CSV'),
                'url' => $this->urlBuilder->getUrl('export_product/export',['type'=>"vdb"])
            ]
        ];
        $this->setData('config', $config);
        parent::prepare();
    }
}



namespace Bhaveshpp\Export\Controller\Adminhtml\Export;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Bhaveshpp\Export\Model\Export\ConvertToCsv;
use Magento\Framework\App\Response\Http\FileFactory;


class Index extends Action
{

    /**
     * @var ConvertToCsv
     */
    protected $converter;

    /**
     * @var FileFactory
     */
    protected $fileFactory;


    /**
     * @param Context $context
     * @param ConvertToCsv $converter
     * @param FileFactory $fileFactory
     */
    public function __construct(
        Context $context,
        ConvertToCsv $converter,
        FileFactory $fileFactory
    ) {
        parent::__construct($context);
        $this->converter = $converter;
        $this->fileFactory = $fileFactory;
    }


    /**
     * Authorization level of a basic admin session
     *
     * @see _isAllowed()
     */
    const ADMIN_RESOURCE = 'Tecksky_Export::export';  
    
    /**
     * Export data provider to CSV
     *
     * @throws \Magento\Framework\Exception\LocalizedException
     * @return \Magento\Framework\App\ResponseInterface
     */
    public function execute()
    {
        $type = $this->_request->getParam('type');
        $fileName = ($type)?$type.'.csv':'export.csv';
        return $this->fileFactory->create($fileName, $this->converter->getCsvFile($type), 'var');
    }
}



/**
 * Model for export all product to csv 
 */
namespace Bhaveshpp\Export\Model\Export;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Filesystem;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Catalog\Model\ProductRepository;
use Magento\Catalog\Model\Product\Media\Config as MediaConfig;

/**
 * Class ConvertToCsv
 */
class ConvertToCsv
{
    /**
     * @var CollectionFactory
     */
    protected $prodCollFactory;

    /**
     * @var DirectoryList
     */
    protected $directory;

    /**
     * @var 
     */
    protected $_product;

    /**
     * @var ProductRepository
     */
    protected $productRepository;
    
    /**
     * @var MediaConfig
     */
    protected $media;

    /**
     * @param Filesystem $filesystem
     * @param CollectionFactory $prodCollFactory
     * @param ProductRepository $productRepository
     * @param MediaConfig $media
     * @throws FileSystemException
     */
    public function __construct(
        Filesystem $filesystem,
        CollectionFactory $prodCollFactory,
        ProductRepository $productRepository,
        MediaConfig $media
    ) {
        $this->media = $media;
        $this->productRepository = $productRepository;
        $this->prodCollFactory = $prodCollFactory;
        $this->directory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
    }

    /**
     * Returns CSV file
     *
     * @return array
     * @throws LocalizedException
     */
    public function getCsvFile($type)
    {
        $name = md5(microtime());
        $file = 'export/product_data'. $name . '.csv';

        $this->directory->create('export');
        $stream = $this->directory->openFile($file, 'w+');
        $stream->lock();
        $stream->writeCsv($this->getHeader($type));
        $collection = $this->prodCollFactory->create();
        $collection->addAttributeToFilter('status',\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
        $collection->getSelect()->joinLeft(
            array('_inv' => $collection->getResource()->getTable('cataloginventory_stock_status')),
            "_inv.product_id = e.entity_id",
            array('stock_status')
        );
        $collection->addExpressionAttributeToSelect('in_stock', 'IFNULL(_inv.stock_status,0)', array());
        
        $items = $collection->getData();
        foreach ($items as $item) {
            $_product = $this->getProduct($item);
            if ($item['stock_status'] == 1) {
                $stream->writeCsv(
                    $this->getRow($_product,$type)
                );
            }
        }
        
        $stream->unlock();
        $stream->close();

        return [
            'type' => 'filename',
            'value' => $file,
            'rm' => true  // can delete file after use
        ];
    }

    /**
     * get Product object
     *
     * @param array $item
     * @return Magento\Catalog\Model\Product
     */
    public function getProduct($item)
    {
        return $this->productRepository->getById($item['entity_id']);
    }

    /**
     * Get product frontend value
     *
     * @param Magento\Catalog\Model\Product $_product
     * @param string $code
     * @return string
     */
    public function getVal($_product, $code)
    {
        if ($_product == null) {
            return "";
        }

        $val = $_product->getResource()->getAttribute($code)->getFrontend()->getValue($_product);
        if ($val == 'Select...') {
            return "";
        }       

        return $val;
    }

    /**
     * Get Country value
     *
     * @param string $country
     * @return string
     */
    public function getCountry($country)
    {
        if ($country && $country == 'United States') {
            return "USA";
        } 
        return $country;
    }

    /**
     * Get state value
     *
     * @param string $country
     * @return string
     */
    public function getState($country)
    {
        if ($country && $country == 'United States') {
            return "New York";
        }
        if ($country && $country == 'India') {
            return "Gujarat";
        }
        return "";
    }

    /**
     * Get city value
     *
     * @param string $country
     * @return string
     */
    public function getCity($country)
    {
        if ($country && $country == 'United States') {
            return "New York";
        }
        if ($country && $country == 'India') {
            return "Surat";
        }
        return "";
    }

    /**
     * Get product price
     *
     * @param Magento\Catalog\Model\Product $_product
     * @param boolean $isFinal
     * @return string
     */
    public function getPrice($_product = null, $isFinal = false)
    {
        if ($_product == null) {
            return "";
        }

        if ($isFinal) {
            return $_product->getFinalPrice();
        }else{
            return $_product->getPrice();
        }
    }

    /**
     * Get product image url
     *
     * @param Magento\Catalog\Model\Product $_product
     * @return string
     */
    public function getProductImage($_product = null)
    {
        if ($_product == null) {
            return "";
        }
        if (!empty($_product->getImage())) {
            return $this->media->getMediaUrl($_product->getImage());
        }
        return "";

    }

    /**
     * @param Magento\Catalog\Model\Product $_product
     * @return array
     */
    public function getRow($_product,$type)
    {
        return array_values($this->prepare($type,$_product));
    }

    /**
     * Get CSV header
     *
     * @param string $type
     * @return array
     */
    public function getHeader($type)
    {
        return array_keys($this->prepare($type));
    }

    /**
     * Prepare CSV Data
     *
     * @param string $type
     * @param Magento\Catalog\Model\Product $_product
     * @return array
     */
    public function prepare($type = "nivoda", $_product = null)
    {
        if ($type == "nivoda") {
            return [
                "Stock #" => $this->getVal($_product, 'sku'), 
                "Availability" => $this->getVal($_product, 'diamond_hold_status'), 
                "Shape" => $this->getVal($_product, 'diamond_shape'), 
                "Weight" => $this->getVal($_product, 'diamond_size'), 
                "Color" => $this->getVal($_product, 'diamond_color'), 
                "Clarity" => $this->getVal($_product, 'diamond_clarity'), 
                "Cut" => $this->getVal($_product, 'diamond_cut'), 
                "Polish" => $this->getVal($_product, 'diamond_polish'), 
                "Symmetry" => $this->getVal($_product, 'diamond_symmetry'), 
                "Fluorescence Intensity" => $this->getVal($_product, 'diamond_fluorescence_intensity'), 
                "Fluorescence Color" => "", 
                "Measurements" => $this->getVal($_product, 'diamond_measurement'), 
                "Shade" => "", 
                "Milky" => "", 
                "Eye Clean" => "", 
                "Lab" => $this->getVal($_product, 'diamond_certificate_type'), 
                "Report #" => "", 
                "Location" => $this->getCountry($this->getVal($_product, 'diamond_current_country')), 
                "Treatment" => "", 
                "Price Per Carat" => $this->getVal($_product, 'diamond_price_per_carat'), 
                "Final Price" => $this->getPrice($_product,true), 
                "Depth %" => $this->getVal($_product, 'diamond_depth'), 
                "Table %" => $this->getVal($_product, 'diamond_table'), 
                "Girdle Thin" => $this->getVal($_product, 'diamond_girdle_thin'), 
                "Girdle Thick" => $this->getVal($_product, 'diamond_girdle_thick'), 
                "Girdle %" => "", 
                "Girdle Condition" => $this->getVal($_product, 'diamond_girdle_condition'), 
                "Culet Size" => "", 
                "Culet Condition" => $this->getVal($_product, 'diamond_culet_condition'), 
                "Crown Height" => $this->getVal($_product, 'diamond_crown_height'), 
                "Crown Angle" => $this->getVal($_product, 'diamond_crown_angle'), 
                "Pavilion Depth" => $this->getVal($_product, 'diamond_pavilion_depth'), 
                "Pavilion Angle" => $this->getVal($_product, 'diamond_pavilion_angle'), 
                "Inscription" => "", 
                "Cert comment" => "", 
                "KeyToSymbols" => "", 
                "White Inclusion" => "", 
                "Black Inclusion" => "", 
                "Open Inclusion" => "", 
                "Fancy Color" => $this->getVal($_product, 'diamond_fancy_color'), 
                "Fancy Color Intensity" => $this->getVal($_product, 'diamond_fancy_color_intensity'), 
                "Fancy Color Overtone" => $this->getVal($_product, 'diamond_fancy_color_overtone'), 
                "Country" => $this->getCountry($this->getVal($_product, 'diamond_current_country')), 
                "State" => $this->getState($this->getVal($_product, 'diamond_current_country')), 
                "City" => $this->getCity($this->getVal($_product, 'diamond_current_country')), 
                "CertFile" => "", 
                "Diamond Video" => $this->getVal($_product, 'diamond_video'), 
                "Diamond Image" => $this->getProductImage($_product)
            ];   
        }
        else{
            return [
                "Stock #" => $this->getVal($_product, 'sku'), 
                "Availability" => $this->getVal($_product, 'diamond_hold_status'),
                "Shape" => $this->getVal($_product, 'diamond_shape'),
                "Weight" => $this->getVal($_product, 'diamond_size'),
                "Clarity" => $this->getVal($_product, 'diamond_clarity'),
                "Color" => $this->getVal($_product, 'diamond_color'),
                "Fancy Color" => $this->getVal($_product, 'diamond_fancy_color'),
                "Fancy Color Intensity" => $this->getVal($_product, 'diamond_fancy_color_intensity'),
                "Fancy Color Overtone" => $this->getVal($_product, 'diamond_fancy_color_overtone'),
                "Price" => $this->getPrice($_product),
                "Total Price" => $this->getPrice($_product,true),
                "Discount Percent" => "",
                "Image Link" => $this->getProductImage($_product),
                "Video Link" => $this->getVal($_product, 'diamond_video'),
                "Cut Grade" => $this->getVal($_product, 'diamond_cut'),
                "Polish" => $this->getVal($_product, 'diamond_polish'),
                "Symmetry" => $this->getVal($_product, 'diamond_symmetry'),
                "Depth Percent" => $this->getVal($_product, 'diamond_depth'),
                "Table Percent" => $this->getVal($_product, 'diamond_table'),
                "Fluorescence Intensity" => $this->getVal($_product, 'diamond_fluorescence_intensity'),
                "Fluorescence Color" => "",
                "Lab" => $this->getVal($_product, 'diamond_certificate_type'),
                "Certificate #" => $this->getVal($_product, 'diamond_certificate_id'),
                "Certificate Url" => $this->getVal($_product, 'diamond_certificate_file_url'),
                "Cert Comment" => "",
                "Culet Size" => "",
                "Girdle Percent" => "",
                "Girdle Condition" => $this->getVal($_product, 'diamond_girdle_condition'),
                "Girdle Thick" => $this->getVal($_product, 'diamond_girdle_thick'),
                "Girdle Thin" => $this->getVal($_product, 'diamond_girdle_thin'),
                "Measurements" => $this->getVal($_product, 'diamond_measurement'),
                "Milky" => "",
                "Pavilion Depth" => $this->getVal($_product, 'diamond_pavilion_depth'),
                "BGM" => "",
                "Crown Height" => $this->getVal($_product, 'diamond_crown_height'),
                "Crown Angle" => $this->getVal($_product, 'diamond_crown_angle'),
                "Pavilion Angle" => $this->getVal($_product, 'diamond_pavilion_angle'),
                "Laser Inscription" => "",
                "Member Comments" => "",
                "Pair" => "",
                "H&A" => "",
                "City" => $this->getCity($this->getVal($_product, 'diamond_current_country')),
                "State" => $this->getState($this->getVal($_product, 'diamond_current_country')),
                "Country" => $this->getCountry($this->getVal($_product, 'diamond_current_country')),
                "Stock Number for Matching Pair" => "",
                "Share Access" => "",
                "Eye Clean" => "",
                "Growth Type" => ""
            ];
        }
    }
}