In this guide, we'll walk you through a simple 3-step process to export orders from Magento 2 into a CSV file programmatically.
Yes! You can programmatically export orders in .csv format using Magento 2's order repository and a small custom module — in just a few easy-to-follow steps.
Let's get started!
Why Export Orders Programmatically?
Before we jump into the steps, here's a quick look at why you might want to export orders using code:
- Automate order reporting or backups.
- Feed order data into third-party tools like accounting or fulfillment systems.
- Customize exports beyond what the built-in admin grid export offers.
Now, onto the how. Here are the steps to programmatically export orders to CSV in Magento 2.
3 Steps to Export Orders to CSV Programmatically in Magento 2
Step 1: Set Up a Custom Module
First, we'll create a basic module that Magento can recognize.
Create module.xml
Path: app/code/Custom/Module/etc/module.xml
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Custom_Module" setup_version="1.0.0"/>
</config>
|
Create registration.php
Path: app/code/Custom/Module/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Custom_Module',
__DIR__
);
|
With that, your module is now registered. Don't forget to run:
php bin/magento module:enable Custom_Module php bin/magento setup:upgrade |
Step 2: Set Up a Route for the Module
Next, let's define a custom route so you can trigger the export from your browser.
Create routes.xml
Path: app/code/Custom/Module/etc/frontend/routes.xml
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route frontName="custom" id="custom">
<module name="Custom_Module"/>
</route>
</router>
</config>
|
Now, when you access yourstore.com/custom/index/exportorders, Magento knows what to do.
Important — read before you deploy this anywhere public: a frontend route like this has no authentication. Anyone who discovers the URL can download your entire order history, customer emails included. Treat this setup as a local/development convenience only. For anything production-facing, put the controller behind the admin (an adminhtml route with an ACL resource, like any admin controller), or remove the module once you've pulled your export.
Step 3: Create a Controller That Generates the CSV File
We'll fetch the order data through the order repository and stream it into a CSV file.
Create ExportOrders.php
Path: app/code/Custom/Module/Controller/Index/ExportOrders.php
<?php
namespace Custom\Module\Controller\Index;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\Response\Http\FileFactory;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
class ExportOrders extends Action
{
protected $fileFactory;
protected $orderRepository;
protected $searchCriteriaBuilder;
protected $_filesystem;
public function __construct(
Context $context,
FileFactory $fileFactory,
OrderRepositoryInterface $orderRepository,
SearchCriteriaBuilder $searchCriteriaBuilder,
\Magento\Framework\Filesystem $filesystem
) {
$this->fileFactory = $fileFactory;
$this->orderRepository = $orderRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->_filesystem = $filesystem;
parent::__construct($context);
}
public function execute()
{
$searchCriteria = $this->searchCriteriaBuilder->create();
$orders = $this->orderRepository->getList($searchCriteria)->getItems();
$csvData = [];
$csvData[] = ['Order ID', 'Customer Email', 'Order Total'];
foreach ($orders as $order) {
$csvData[] = [
$order->getEntityId(),
$order->getCustomerEmail(),
$order->getGrandTotal()
];
}
$fileName = 'orders.csv';
$filePath = 'export/' . $fileName;
$directory = $this->_filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
$stream = $directory->openFile($filePath, 'w+');
foreach ($csvData as $rowData) {
$stream->writeCsv($rowData);
}
$stream->close();
$content = [
'type' => 'filename',
'value' => $filePath,
'rm' => true // delete the file from var/ after it's sent
];
return $this->fileFactory->create($fileName, $content, DirectoryList::VAR_DIR);
}
}
|
How to Export Additional Order Data in the CSV
Let's say you also want to include the order status in the export. Easy fix — just tweak this part:
$csvData = [];
$csvData[] = ['Order ID', 'Customer Email', 'Order Total', 'Order Status'];
foreach ($orders as $order) {
$csvData[] = [
$order->getEntityId(),
$order->getCustomerEmail(),
$order->getGrandTotal(),
$order->getStatus()
];
}
|
You can customize the CSV columns however you like: billing info, shipping address, payment method, and more.
How to Export Only a Date Range (Recommended on Real Stores)
As written, the empty search criteria fetches every order in the database — on a store with tens of thousands of orders, that's a slow request and a lot of memory. Filter the criteria instead; for example, only orders placed since June 1st:
$searchCriteria = $this->searchCriteriaBuilder
->addFilter('created_at', '2026-06-01 00:00:00', 'gteq')
->create();
$orders = $this->orderRepository->getList($searchCriteria)->getItems();
|
The same pattern works for any order field — filter by status, store_id, or a from/to pair of created_at filters for a fixed window.
How to Access the Exported Orders CSV
Once everything is set (finish with php bin/magento cache:flush), simply visit: {your-base-url}/custom/index/exportorders
Your CSV file downloads automatically with all the order data.
Need an Easier Way?
The controller above is a solid starting point, but real export workflows grow fast: more fields, custom filters per export, scheduled runs, sending files to FTP or email instead of a browser download — and each of those is more custom code to write and secure. If you'd rather have all of it from the admin panel, the Export Order extension for Magento 2 is built exactly for that: flexible field selection, filtering, scheduled automatic exports, and no unauthenticated routes to worry about.
Wrapping Up!
We hope this guide gave you a clear and actionable way to export orders programmatically in Magento 2 to a .csv file — and the two guardrails that matter on a live store: filter your criteria, and never leave the export route publicly reachable. If you're stuck or need help customizing the export, our Magento experts are just a message away.