Custom Bitrix Data Export Module Development
A client recently came to us with a catalog of 500,000 products requiring daily stock uploads to Ozon and Wildberries. Standard 'load everything into array' solutions crashed with Out of Memory errors, even with increased limits. The admin page load took 40 seconds, and synchronous export paused the site for 10 minutes. They needed a module that streams data without blocking the admin and generates files asynchronously. We designed a three-layer architecture: Collector, Transformer, Formatter. It proved so flexible that we now use it as a foundation for all export tasks.
Typical scenarios the module covers
- Catalog uploads to marketplaces (Ozon, Wildberries) in specific XML or JSON
- Order export to 1C:Enterprise via CommerceML or CSV
- Regular lead export to Google Sheets or BI systems
- User data transfer to ESP (UniSender, SendGrid)
- Backup data export for migration to another platform
Each scenario has its own field mapping and format. A single module lets you configure all exports in one place, with access rights and logging.
How asynchronous generation works
The admin clicks 'Run export', a job is created in the b_vendor_exporter_job table with status queued. The agent ExportAgent::run() fires every minute and processes one job at a time. The file is written directly to disk without buffering in memory. Upon completion, status changes to done and the file can be downloaded, emailed, or sent via FTP. Compare: a synchronous 'request-response' approach would freeze for 5–10 minutes for 100,000 records — async lets the user walk away while the file is ready in a minute. Based on our projects, async export is 3x faster than standard component-based solutions.
Why asynchronous generation beats synchronous
Synchronous export blocks the HTTP request and consumes RAM proportional to data size. For 500,000 products, even the ID array takes 50 MB, full data with prices and properties up to 1 GB. Async generation via PHP generators uses less than 10 MB peak memory, even for millions of records. Learn more about generators in the PHP documentation.
Module structure
The vendor.exporter module has three layers:
- Collector — fetches data from the source (ORM queries to Bitrix tables)
- Transformer — transforms raw data into the required structure
- Formatter — produces the final file in the required format
Module tables:
| Table | Purpose |
|---|---|
b_vendor_exporter_profile |
Export profiles: name, source_config (JSON), format, schedule, last_run, last_file |
b_vendor_exporter_job |
Jobs: profile_id, status, started_at, finished_at, file_path, rows_count, error |
b_vendor_exporter_field |
Field mapping: profile_id, source_field, target_field, transform_rule |
Data collectors
class CatalogProductCollector implements CollectorInterface { public function collect(array $filter, array $select): \Generator { $query = \Bitrix\Iblock\Elements\ElementTable::query() ->setFilter($filter) ->setSelect($select); foreach ($query->fetchAll() as $row) { // JOIN with prices $prices = \Bitrix\Catalog\PriceTable::getList([ 'filter' => ['=PRODUCT_ID' => $row['ID']], 'select' => ['PRICE', 'CURRENCY', 'CATALOG_GROUP_NAME'], ])->fetchAll(); $row['PRICES'] = $prices; yield $row; } } } Using Generator instead of an array is critical for exporting 100,000+ records — data is not accumulated in memory.
Formatters
CSV with delimiter and encoding support:
class CsvFormatter implements FormatterInterface { public function format(\Generator $data, array $columns, string $outputPath): void { $handle = fopen($outputPath, 'w'); fputs($handle, "\xEF\xBB\xBF"); // UTF-8 BOM for Excel fputcsv($handle, array_column($columns, 'label'), $this->delimiter); foreach ($data as $row) { fputcsv($handle, $this->extractValues($row, $columns), $this->delimiter); } fclose($handle); } } The CSV format is defined in RFC 4180 and widely used for tabular data exchange (see Wikipedia on CSV).
XML formatter for arbitrary schemas — configurable via XSD or XSLT templates. XLSX via PhpSpreadsheet with cell formatting. JSON with structure options: flat array or nested objects. Each formatter can be extended for specific marketplace requirements.
Filtering and partial export
Each profile has a base filter. On manual run, the admin can add extra filters through a form: date range, statuses, specific IDs. The filter is passed to the collector via filter_override:
$collector->collect( array_merge($profile->getBaseFilter(), $job->getFilterOverride()), $profile->getSelect() ); Security and audit
Export of personal data (users, orders) is available only to groups with explicit permissions in the module settings. Every run is logged: who, when, how many records, file path. The log is stored in b_vendor_exporter_audit. This ensures compliance with data protection regulations.
How to set up an export profile
Setup consists of four steps:
- Select the Bitrix entity (catalog, orders, leads) and data source (info block, HL-block, table).
- Configure field mapping: map source fields to export fields. Transform rules available: concatenation, format conversion, value substitution.
- Define file format (CSV, XML, XLSX, JSON) and additional parameters (delimiter, encoding, schema).
- Specify schedule (cron expression) and delivery method (email, FTP, POST webhook).
All settings are available in the module's administrative interface.
What's included in the work
- Module architecture: profiles, collectors, formatters
- Async queue implementation with agent
- Administrative interface for profiles and jobs
- Schedule (cron) and auto-delivery (email, FTP, POST) setup
- Testing on your data (up to 1 million records)
- Installation and configuration documentation
- 1-month warranty for revisions within the agreed scope
Development timeline
| Stage | Duration |
|---|---|
| Architecture, interfaces, tables | 1 day |
| Collectors for required Bitrix entities | 2 days |
| Formatters (CSV, XML, XLSX, JSON) | 2 days |
| Async generation, agent | 1 day |
| Schedule, auto-delivery (email, FTP) | 2 days |
| Administrative interface | 2 days |
| Filtering, permissions, audit log | 1 day |
| Testing on large datasets | 1 day |
Total: 12 working days for a standard set of formats and sources. Specific marketplace formats (especially with mandatory certification fields) add 1-2 days each.
Why choose us?
We are a team with 5+ years of Bitrix and Bitrix24 experience, having completed over 50 integration and data export projects. We use modern PHP 8.1, ORM, and tagged caching. Order a custom data export module — we'll evaluate your project in one business day. Get a consultation on architecture and timelines. Everything turnkey, with documentation and support.

