При работе с системой 1С:Предприятие, особенно при выгрузке больших объемов данных, таких как прайс-листы с изображениями, мы часто сталкиваемся с проблемой избыточного размера итоговых файлов Excel. Эта ситуация становится особенно острой после обновления платформы, когда, казалось бы, идентичные данные приводят к значительному увеличению размера файла. Рассмотрим эту проблему подробно и разберем пути её решения.
Представьте следующую ситуацию: у клиента имеется две базы 1С:Управление торговлей (УТ) – старая, на релизе 11.5.12, и новая, на 11.5.17. Обе базы работают на платформе 8.3.25.1286 (с последующим обновлением). Используется внешняя обработка для формирования прайс-листа, которая выводит товары с описаниями и картинками. В старой базе экспорт прайс-листа в Excel давал файл размером около 11 Мб. После обновления базы до новой версии, с абсолютно идентичными данными, тот же прайс-лист вдруг стал весить 270 Мб. Это огромное увеличение размера файла, которое делает его неудобным для работы и пересылки.
Давайте выясним причину такого поведения.
Основная причина увеличения размера файлов Excel связана с тем, как платформа 1С:Предприятие обрабатывает и встраивает изображения в табличные документы при их сохранении в формат Excel. Между различными версиями платформы существуют существенные отличия в этом процессе.
Это поведение, при котором сохраняется исходный размер изображения, если не задано иное, является более точным с точки зрения сохранения данных, но менее оптимальным для размера файла при массовой выгрузке.
Прежде чем переходить к решениям, нам нужно убедиться, что именно изображения являются причиной увеличения размера файла. Для этого мы можем провести простую диагностику:
*.xlsx: Если вы еще не используете формат .xlsx, настоятельно рекомендуем это сделать. Формат .xlsx (Microsoft Excel 2007 и выше) является предпочтительным, поскольку он основан на открытом стандарте Open XML и по сути представляет собой ZIP-архив. Это обеспечивает лучшую степень сжатия данных, включая изображения, по сравнению со старым форматом .xls. Сохранение в .xlsx само по себе может немного уменьшить размер файла. Используем следующий метод сохранения:
ЭтаФорма.Таб.Записать(ДиалогОткрытияФайла.ПолноеИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
*.xlsx файла: Поскольку файл .xlsx по сути является ZIP-архивом, мы можем изменить его расширение на .zip и распаковать.
xl/media. В этом каталоге хранятся все изображения, встроенные в документ Excel.Столкнувшись с проблемой, многие программисты, включая автора исходной темы, предприняли ряд логичных шагов для уменьшения размера изображений. Рассмотрим их и объясним, почему они не дали желаемого результата в данной ситуации:
ОбрабатываемаяКартинка: Были попытки сжать картинку с помощью объекта ОбрабатываемаяКартинка, например:
СжимаемаяКартинка = Картинка;
ОбрабатываемаяКартинка = Новый ОбрабатываемаяКартинка(СжимаемаяКартинка);
ОбрабатываемаяКартинка.УстановитьРазмер(Неопределено, 110); // Устанавливаем высоту 110 пикселей
СжатаяКартинка = ОбрабатываемаяКартинка.ПолучитьКартинку;
ХранилищеЗначения: Также предпринимались попытки использовать ХранилищеЗначения со сжатием данных:
НовоеХранилище = Новый ХранилищеЗначения(Картинка, Новый СжатиеДанных(9));
КартинкаСжатая = НовоеХранилище.Получить;
В свойствах элемента "Рисунок" на макете табличного документа 1С есть свойство РазмерКартинки (или РазмерРисунка), которое определяет способ масштабирования картинки в ячейке. Возможные значения включают "Авторазмер", "Пропорционально", "РеальныйРазмер", "Растянуть" и "Черепица".
ЭтаФорма.Таб.Записать(...)) также не решало проблему, поскольку это просто вызов того же встроенного механизма записи, который по умолчанию приводил к большому файлу.Все эти попытки оказались либо неэффективными, либо приводили к неприемлемому качеству. Это подводило к мысли, что проблема носит более системный, платформенный характер.
ПлотностьСохраняемыхКартинокДля решения проблемы с большим размером файлов, содержащих изображения, в платформе 1С:Предприятие было введено специальное свойство – ПлотностьСохраняемыхКартинок для объекта ТабличныйДокумент. Это свойство предназначено для управления качеством и, соответственно, размером сохраняемых изображений при экспорте табличного документа в различные форматы, включая Excel.
Предполагалось, что мы могли бы установить это свойство, например, следующим образом:
ТабДок.ПлотностьСохраняемыхКартинок = ПлотностьСохраняемыхКартинокТабличногоДокумента.Низкая;
Значения, которые можно присвоить этому свойству, это элементы перечисления ПлотностьСохраняемыхКартинокТабличногоДокумента: Низкая, Средняя, Высокая. Выбор Низкая плотность должен был бы значительно уменьшить размер файлов за счет дополнительного сжатия изображений.
Однако, здесь возникла серьезная загвоздка. В некоторых промежуточных версиях платформы (например, в той, что использовал автор темы до обновления, а именно 8.3.25.1286), попытка установить это свойство приводила к ошибке "Несоответствие типов". Это означало, что несмотря на наличие свойства в документации, его корректное использование было невозможно из-за внутренней ошибки в самой платформе.
Эта ошибка в платформе была источником значительного разочарования для разработчиков, поскольку инструмент для решения проблемы уже был, но его нельзя было применить.
ПлотностьСохраняемыхКартинокИтак, после многочисленных попыток и диагностики, стало очевидно, что проблема кроется в самой платформе. Решение, которое в итоге оказалось эффективным, было следующим:
Ключевым шагом стало обновление платформы до более свежей версии. В данном случае, обновление до версии 8.3.27.1688 (и, вероятно, любой другой актуальной версии выше 8.3.25.x) устранило ошибку "Несоответствие типов" при работе со свойством ПлотностьСохраняемыхКартинок.
После обновления платформы, система 1С начинает корректно распознавать и применять это свойство.
ПлотностьСохраняемыхКартинок:
После обновления платформы, мы можем теперь успешно использовать свойство ПлотностьСохраняемыхКартинок в коде нашей обработки для формирования прайс-листа.
Давайте рассмотрим пример кода, который демонстрирует, как это делается:
&НаКлиенте
Процедура СохранитьПрайсВExcel(Команда)
// Получаем табличный документ, который уже заполнен данными и картинками
// (Предполагаем, что ЭтаФорма.Таб содержит сформированный ТабличныйДокумент)
ТабличныйДокументДляЭкспорта = ЭтаФорма.Таб;
// Устанавливаем плотность сохранения картинок.
// Это критически важный шаг для уменьшения размера файла.
// Возможные значения: ПлотностьСохраняемыхКартинокТабличногоДокумента.Низкая,
// ПлотностьСохраняемыхКартинокТабличногоДокумента.Средняя,
// ПлотностьСохраняемыхКартинокТабличногоДокумента.Высокая.
// Для достижения максимального сжатия и минимального размера файла
// выбираем значение "Низкая". Будьте готовы к возможному, но обычно приемлемому
// снижению качества изображений в итоговом файле.
ТабличныйДокументДляЭкспорта.ПлотностьСохраняемыхКартинок = ПлотностьСохраняемыхКартинокТабличногоДокумента.Низкая;
// Создаем диалог для выбора файла сохранения
ДиалогСохраненияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
ДиалогСохраненияФайла.Заголовок = "Сохранить прайс-лист в Excel";
ДиалогСохраненияФайла.Фильтр = "Файлы Excel (*.xlsx)|*.xlsx";
ДиалогСохраненияФайла.ПолноеИмяФайла = "ПрайсЛист.xlsx"; // Предлагаемое имя файла
// Открываем диалог и ждем выбора пользователя
Если ДиалогСохраненияФайла.Выбрать() Тогда
Попытка
// Сохраняем табличный документ в выбранный файл в формате XLSX.
// Формат XLSX обеспечивает лучшее сжатие по сравнению с XLS.
ТабличныйДокументДляЭкспорта.Записать(ДиалогСохраненияФайла.ПолноеИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
Сообщить("Прайс-лист успешно сохранен в файл: " + ДиалогСохраненияФайла.ПолноеИмяФайла);
Исключение Е
Сообщить("Ошибка при сохранении прайс-листа: " + Е.Описание, СтатусСообщения.Важное);
КонецПопытки;
Иначе
Сообщить("Сохранение отменено пользователем.");
КонецЕсли;
КонецПроцедуры
Важные моменты:
.xlsx (ТипФайлаТабличногоДокумента.XLSX), так как этот формат по умолчанию использует сжатие и лучше подходит для больших файлов с изображениями.ПлотностьСохраняемыхКартинокТабличногоДокумента.Низкая обеспечит максимальное сжатие, что существенно уменьшит размер файла. Проверьте результат, чтобы убедиться, что качество изображений остается приемлемым для ваших требований. Если качество окажется недостаточным, можно попробовать Средняя плотность.После применения этого решения, размер файла Excel с прайс-листом должен значительно уменьшиться, возвращаясь к значениям, близким к тем, что были в старой версии платформы, или даже становясь меньше.
В некоторых случаях не всегда есть возможность оперативно обновить платформу. В таких ситуациях мы можем рассмотреть альтернативные методы, хотя они могут быть менее удобными или требовать дополнительных усилий:
ПакетОтображаемыхДокументов:
Вместо прямого сохранения табличного документа через его метод Записать(), мы можем попробовать использовать объект ПакетОтображаемыхДокументов. Этот объект предоставляет более гибкий подход к работе с составными документами, и иногда его методы могут по-другому обрабатывать внутренние данные, включая изображения.
Рассмотрим пример кода:
&НаКлиенте
Процедура СохранитьПрайсЧерезПакет(Команда)
// Предполагаем, что ТабличныйДокумент1 уже сформирован
// и содержит все необходимые данные, включая картинки.
ТабличныйДокумент1 = ЭтаФорма.Таб; // Пример получения табличного документа
Книга = Новый ПакетОтображаемыхДокументов;
Лист1 = Книга.Состав.Добавить();
// Помещаем табличный документ во временное хранилище, а затем связываем с листом
Лист1.Данные = ПоместитьВоВременноеХранилище(ТабличныйДокумент1);
Лист1.Имя = "ПрайсЛист"; // Имя листа в Excel
// При необходимости можно добавить другие листы:
// Лист2 = Книга.Состав.Добавить();
// Лист2.Данные = ПоместитьВоВременноеХранилище(ДругойТабличныйДокумент);
// Лист2.Имя = "ДополнительнаяИнформация";
ДиалогСохраненияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
ДиалогСохраненияФайла.Заголовок = "Сохранить прайс-лист через Пакет";
ДиалогСохраненияФайла.Фильтр = "Файлы Excel (*.xlsx)|*.xlsx";
ДиалогСохраненияФайла.ПолноеИмяФайла = "ПрайсЛист_Пакет.xlsx";
Если ДиалогСохраненияФайла.Выбрать() Тогда
Попытка
// Сохраняем пакет документов в файл Excel.
// Используем ТипФайлаПакетаОтображаемыхДокументов.XLSX для лучшего сжатия.
Книга.Записать(ДиалогСохраненияФайла.ПолноеИмяФайла, ТипФайлаПакетаОтображаемыхДокументов.XLSX);
Сообщить("Прайс-лист через пакет документов успешно сохранен: " + ДиалогСохраненияФайла.ПолноеИмяФайла);
Исключение Е
Сообщить("Ошибка при сохранении прайс-листа через пакет: " + Е.Описание, СтатусСообщения.Важное);
КонецПопытки;
Иначе
Сообщить("Сохранение отменено пользователем.");
КонецЕсли;
КонецПроцедуры
Хотя этот метод может дать другой результат сжатия, он не гарантирует такого же эффекта, как непосредственное управление плотностью изображений через ПлотностьСохраняемыхКартинок.
Самый эффективный способ контроля размера файлов — это предварительная обработка изображений до их загрузки в базу 1С. Если вы можете уменьшить разрешение и размер файлов изображений до их первоначального помещения в информационную базу, это значительно снизит их "реальный размер", который затем будет выгружаться в Excel.
Этот подход требует изменений в процессе загрузки изображений, но дает наибольший контроль над конечным размером.
В случае, если ни один из вышеперечисленных методов не дает удовлетворительного результата, мы можем рассмотреть более сложные, но мощные подходы:
.xlsx — это набор XML-файлов внутри ZIP-архива. Теоретически, мы можем самостоятельно сформировать эти XML-файлы, включая оптимизированные изображения, и затем упаковать их в .xlsx. Это очень сложный подход, который требует глубокого понимания структуры формата XLSX, но предоставляет полный контроль над каждым байтом выходного файла.Эти методы являются крайними мерами, когда стандартные средства 1С не справляются с задачей, и обычно используются в проектах с очень специфическими требованиями к размеру и структуре выходных файлов.
Проблема большого размера файлов Excel при выгрузке прайсов с картинками из 1С:Управление торговлей, возникающая после обновления платформы, является достаточно типичной и связана с изменениями в логике обработки изображений. Наиболее прямым и эффективным решением, как мы выяснили, является обновление платформы 1С:Предприятие до актуальной версии (например, 8.3.27.1688 или новее) и последующее использование свойства ПлотностьСохраняемыхКартинок для табличного документа с установкой значения ПлотностьСохраняемыхКартинокТабличногоДокумента.Низкая.
Мы настоятельно рекомендуем в первую очередь рассмотреть возможность обновления платформы, поскольку это позволяет использовать штатные и наиболее поддерживаемые механизмы 1С для оптимизации изображений. Если же обновление невозможно, мы можем прибегнуть к альтернативным методам, таким как использование ПакетОтображаемыхДокументов или предварительная оптимизация изображений, загружаемых в базу.
Выбирайте подход, который наилучшим образом соответствует вашим возможностям и требованиям к качеству и размеру выходного файла.