Ok so I'm trying to implement a simple export to CSV massaction on the Magento 2 Catalog products grid.

I've successfully created the mass action item, as well as the admin controller.

I am able to retrieve a CSV, however, it is missing the following fields from the original catalog products grid, I do not understand why:

  • Product name
  • Price
  • Special Price

Basically I want to be able to retrieve the product collection generated in app\code\Magento\Catalog\Block\Adminhtml\Product\Grid.php and to use it in my controller.

I've based my controller development on another massaction controller thinking it would do the trick but it does not.

Here is my admin controller:

namespace DigitalPianism\ProductExport\Controller\Adminhtml\Productexport;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\Response\Http\FileFactory;
use Magento\Framework\Controller\ResultFactory;
use Magento\Catalog\Controller\Adminhtml\Product\Builder;
use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;

class ExportCsv extends \Magento\Catalog\Controller\Adminhtml\Product
     * Massactions filter
     * @var Filter
    protected $filter;

     * @var CollectionFactory
    protected $collectionFactory;

     * @var \Magento\Framework\App\Response\Http\FileFactory
    protected $_fileFactory;

     * @param Context $context
     * @param Builder $productBuilder
     * @param Filter $filter
     * @param CollectionFactory $collectionFactory
    public function __construct(
        Context $context,
        Builder $productBuilder,
        Filter $filter,
        CollectionFactory $collectionFactory,
        FileFactory $fileFactory
    ) {
        $this->filter = $filter;
        $this->collectionFactory = $collectionFactory;
        $this->_fileFactory = $fileFactory;
        parent::__construct($context, $productBuilder);

     * @return \Magento\Backend\Model\View\Result\Redirect
    public function execute()
        $collection = $this->filter->getCollection($this->collectionFactory->create());
        // Write headers to the csv file
        $content = "id,name,url,sku,price,special_price\n";
        foreach ($collection->getItems() as $product) {
            $content .= "\"{$product->getId()}\",\"{$product->getName()}\",\"{$product->getProductUrl()}\",\"{$product->getSku()}\",\"{$product->getPrice()}\",\"{$product->getSpecialPrice()}\"\n";
        // Return the CSV file
        $fileName = 'products.csv';
        return $this->_fileFactory->create(

     * Customer access rights checking
     * @return bool
    protected function _isAllowed()
        return $this->_authorization->isAllowed('Magento_Catalog::manage');

4 Answers 4


I was using \Magento\Catalog\Api\ProductRepositoryInterface to get all the list of my products. Try this instead.

protected $productRepository;

protected $searchCriteriaBuilder;

public function __construct(
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
    \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
) {
    $this->productRepository = $productRepository;
    $this->searchCriteriaBuilder = $searchCriteriaBuilder;

public function execute()
    // *** You may add filter rules for your query.
    $searchCriteria = $this->searchCriteriaBuilder->create();

    // *** Retrieve all products based on search criteria
    $list = $this->productRepository->getList($searchCriteria);

    foreach ($list->getItems() as $item) {
        var_dump($item->getName(), $item->getPrice(), $item->getSpecialPrice());

try this.

    $collection = $this->productCollectionFactory->create();
    $collection->addAttributeToSelect('*'); // you can optimize


$productCollection = $objectManager->get('Magento\Catalog\Model\ResourceModel\Product\CollectionFactory')->create();

It doesn't have price, special_price, Now you have to using addAttributeToSelect(), and add left as second parameter otherwise can't get that field.


Now you add two extra field to the collection


Try to use collectionFactory instead

public function execute() { $collection = $this->collectionFactory->create(); ...

  • Nope I'm already doing this in my first line of the execute function. Commented Jan 20, 2016 at 16:44

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.