Today i had to create a file download from a Magento 2 controller. I turnes out that this is quite simple. Now, it's good to know that there are 2 options here:
You have the file contents available. This is the case when you created an CSV with data for example.
The file you want to offer to download is already somewhere on disk. This can be something the user uploaded before.
Hey, I'm running a newsletter called Mage Dispatch, which is for the community and by the community. Here you can share links that you think that the community should know about. If you like this kind of technical content you will like this newsletter too.
Dynamic file contents
First, we need the \Magento\Framework\App\Response\Http\FileFactory
class:
use Magento\Framework\App\Response\Http\FileFactory; public function __construct( Action\Context $context, FileFactory $fileFactory ) { parent::__construct($context); $this->fileFactory = $fileFactory; }
Then in our execute
method we return the result of the create
method:
public function execute() { $contents = $this->orderExport->generateCsv(); return $this->fileFactory->create('order-export.csv', $contents); }
And that's it, when you visit this endpoint you will get a file download called order-export.csv
.
Existing file
Now this requires an extra dependency as we need to get the path to our file:
use Magento\Framework\Filesystem\DirectoryList; use Magento\Framework\App\Response\Http\FileFactory; public function __construct( Action\Context $context, FileFactory $fileFactory, DirectoryList $directory ) { parent::__construct($context); $this->fileFactory = $fileFactory; $this->directory = $directory; }
Next we calculate the full path and instead of a string with contents, pass an array as contents:
public function execute() { $path = $this->directory->getPath(\Magento\Framework\App\Filesystem\DirectoryList::PUB) . '/uploads/' . $this->getFilename(); return $this->fileFactory->create($model->getValue(), [ 'type' => 'filename', 'value' => $path, ]); }
In this case the file must be present in the pub/uploads
folder. You can check this file for all folders available by default in Magento.
Remove the file after download
Do you need to remove the file when the download is done? Magento has got your back, just add the rm
key:
return $this->fileFactory->create($model->getValue(), [ 'type' => 'filename', 'value' => $path, 'rm' => true, ]);
Now your file is deleted after the download is complete.
Want to respond?