При формировании каталогов товаров или прайс-листов с графическими миниатюрами разработчики часто сталкиваются с ситуацией: отчет формируется на экране без замечаний, успешно выгружается в PDF или XLSX, но при попытке сохранить его в стандартный формат Excel 97–2003 (XLS) платформа 1С аварийно завершает операцию с системным сообщением: «Ошибка при выполнении файловой операции. Файл имеет слишком большой объём».
Проанализируем техническую причину такого поведения платформы и разберем проверенные способы обхода этого ограничения.
Формат XLS базируется на устаревшей бинарной архитектуре OLE Structured Storage (BIFF8). Встроенный в платформу 1С экспортер при формировании XLS-файла обрабатывает графические объекты по следующему алгоритму:
MSODRAWING).Формат XLSX устроен принципиально иначе: это ZIP-контейнер OpenXML. Платформа складывает изображения в каталог медиаданных без декомпрессии в BMP — картинки остаются сжатыми JPEG или PNG, поэтому файл получается компактным (около 1–2 МБ) и сохраняется без ошибок.
Рассмотрим подробнее варианты решения проблемы в зависимости от бизнес-процесса и используемого программного обеспечения пользователей.
Если конечные пользователи или менеджеры работают в бесплатных офисных пакетах OpenOffice Calc или LibreOffice Calc, сохранять данные в устаревший формат XLS не имеет практического смысла. Пакет OpenOffice значительно точнее и быстрее обрабатывает свой родной формат ODS (OpenDocument Spreadsheet).
Архитектурно ODS, как и XLSX, представляет собой ZIP-архив с XML-описанием и упакованными медиафайлами. При экспорте в ODS картинки не конвертируются в тяжеловесный BMP, переполнения потока не происходит, а разметка документа в OpenOffice отображается без искажений.
Посмотрим на пример программного сохранения табличного документа в формат ODS:
// ТабличныйДокумент - сформированный отчет или прайс-лист
ПутьКФайлу = "C:\Temp\ПрайсЛист.ods";
ТабличныйДокумент.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.ODS);
Если контрагенту или внутреннему клиенту критически необходим именно файл с расширением .xls (например, для загрузки в устаревшие учетные системы), можно реализовать двухэтапную выгрузку: штатно сформировать XLSX из 1С, а затем программно пересохранить его в XLS с помощью внешнего офисного пакета.
Разберем по шагам реализацию через запуск LibreOffice / OpenOffice в фоновом консольном режиме (headless mode). Для этого используется команда ЗапуститьПриложение():
ПутьXLSX = "C:\Temp\Прайс.xlsx";
КаталогВыгрузки = "C:\Temp";
// Шаг 1. Штатное сохранение в XLSX без переполнения памяти
ТабличныйДокумент.Записать(ПутьXLSX, ТипФайлаТабличногоДокумента.XLSX);
// Шаг 2. Конвертация в XLS силами офисного пакета
КомандаКонвертации = "soffice --headless --convert-to xls """ + ПутьXLSX + """ --outdir """ + КаталогВыгрузки + """";
ЗапуститьПриложение(КомандаКонвертации, , Истина);
// Исходный временный XLSX можно удалить после успешной конвертации
УдалитьФайлы(ПутьXLSX);
Специализированные офисные пакеты используют собственные оптимизированные алгоритмы размещения картинок внутри BIFF8, поэтому конвертация файла объемом 1–2 МБ проходит без системных сбоев.
Частая ошибка разработчиков заключается в том, что миниатюру сжимают по качеству в формате JPEG (получая малый размер файла на диске, например 15 КБ), но сохраняют ее высокое физическое разрешение (например, 800×800 пикселей). При экспорте в XLS размер несжатого BMP зависит исключительно от ширины, высоты и глубины цвета, а не от исходной степени сжатия JPEG.
Проанализируем параметры графики, которые необходимо скорректировать при подготовке миниатюр:
В релизах платформы ветки 8.3.9 и 8.3.10 присутствовали зарегистрированные ошибки внутреннего генератора отчетов, связанные с некорректным расчетом длины бинарных блоков OLE-контейнера при работе с графикой. Начиная с версий платформы 8.3.14 и выше механизмы экспорта табличных документов были переработаны, что снизило вероятность падения при формировании объемных документов Excel.