Как уменьшить размер файла Excel при выгрузке прайса с картинками из 1С:Управление торговлей?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Торговля и дистрибуция
← На главную

При работе с системой 1С:Предприятие, особенно при выгрузке больших объемов данных, таких как прайс-листы с изображениями, мы часто сталкиваемся с проблемой избыточного размера итоговых файлов Excel. Эта ситуация становится особенно острой после обновления платформы, когда, казалось бы, идентичные данные приводят к значительному увеличению размера файла. Рассмотрим эту проблему подробно и разберем пути её решения.

Представьте следующую ситуацию: у клиента имеется две базы 1С:Управление торговлей (УТ) – старая, на релизе 11.5.12, и новая, на 11.5.17. Обе базы работают на платформе 8.3.25.1286 (с последующим обновлением). Используется внешняя обработка для формирования прайс-листа, которая выводит товары с описаниями и картинками. В старой базе экспорт прайс-листа в Excel давал файл размером около 11 Мб. После обновления базы до новой версии, с абсолютно идентичными данными, тот же прайс-лист вдруг стал весить 270 Мб. Это огромное увеличение размера файла, которое делает его неудобным для работы и пересылки.

Давайте выясним причину такого поведения.

Разберем причину: изменения в обработке изображений платформой 1С

Основная причина увеличения размера файлов Excel связана с тем, как платформа 1С:Предприятие обрабатывает и встраивает изображения в табличные документы при их сохранении в формат Excel. Между различными версиями платформы существуют существенные отличия в этом процессе.

  1. В старых версиях платформы: При экспорте изображений в Excel система могла использовать более "легкие" подходы. Это могло быть сохранение картинок как "снимков их отображения в табличном документе" или пропорциональное масштабирование, которое автоматически уменьшало физический размер изображения в выходном файле, даже если исходное изображение было высокого разрешения. Такой подход часто приводил к меньшему размеру итогового файла Excel, поскольку фактически сохранялась оптимизированная, "экранная" версия изображения.
  2. В новых версиях платформы: Как мы можем заметить, в более свежих релизах платформа 1С начала выгружать изображения в Excel, сохраняя их "реальный размер" по умолчанию, а не пропорциональный или сжатый, если не указаны явные параметры сжатия. Это означает, что если в базе 1С хранится изображение с высоким разрешением и большим размером в байтах (даже если оно визуально отображается маленьким в ячейке), то именно этот "реальный размер" будет встроен в Excel. Например, изображение, занимающее 20 КБ в базе данных 1С, при экспорте в Excel без дополнительной оптимизации могло легко увеличиться до 80-150 КБ или даже больше в зависимости от формата и метаданных, добавляемых Excel. Это и является главной причиной значительного увеличения размера файла.

Это поведение, при котором сохраняется исходный размер изображения, если не задано иное, является более точным с точки зрения сохранения данных, но менее оптимальным для размера файла при массовой выгрузке.

Диагностика проблемы: сравниваем содержимое XLSX-файлов

Прежде чем переходить к решениям, нам нужно убедиться, что именно изображения являются причиной увеличения размера файла. Для этого мы можем провести простую диагностику:

  1. Сохраним прайс-лист в формат *.xlsx: Если вы еще не используете формат .xlsx, настоятельно рекомендуем это сделать. Формат .xlsx (Microsoft Excel 2007 и выше) является предпочтительным, поскольку он основан на открытом стандарте Open XML и по сути представляет собой ZIP-архив. Это обеспечивает лучшую степень сжатия данных, включая изображения, по сравнению со старым форматом .xls. Сохранение в .xlsx само по себе может немного уменьшить размер файла. Используем следующий метод сохранения:
    
    ЭтаФорма.Таб.Записать(ДиалогОткрытияФайла.ПолноеИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
    
    Даже если размер файла все еще будет большим, это шаг к более эффективной диагностике.
  2. Анализируем содержимое *.xlsx файла: Поскольку файл .xlsx по сути является ZIP-архивом, мы можем изменить его расширение на .zip и распаковать.
    1. Создадим два таких файла: один из "старой" конфигурации (если есть такая возможность и она демонстрирует меньший размер), и один из "новой" конфигурации.
    2. Распакуем оба ZIP-архива в разные папки.
    3. Внутри каждой папки найдем подкаталог, обычно xl/media. В этом каталоге хранятся все изображения, встроенные в документ Excel.
    4. Сравним свойства картинок в этих каталогах: их размеры в байтах, разрешения. Мы увидим, что одна и та же картинка в файлах из разных баз будет отличаться не только размерами, но и самим форматом или степенью сжатия. Как показывает опыт, из обновленной базы часто выгружается реальный размер изображения, а из старой — пропорциональный или оптимизированный.
    Этот анализ подтвердит, что проблема именно в обработке изображений при экспорте.

Первые попытки решения и почему они не помогли

Столкнувшись с проблемой, многие программисты, включая автора исходной темы, предприняли ряд логичных шагов для уменьшения размера изображений. Рассмотрим их и объясним, почему они не дали желаемого результата в данной ситуации:

  1. Программное сжатие картинок внутри 1С:
    • Использование ОбрабатываемаяКартинка: Были попытки сжать картинку с помощью объекта ОбрабатываемаяКартинка, например:
      
      СжимаемаяКартинка = Картинка;
      ОбрабатываемаяКартинка = Новый ОбрабатываемаяКартинка(СжимаемаяКартинка);
      ОбрабатываемаяКартинка.УстановитьРазмер(Неопределено, 110); // Устанавливаем высоту 110 пикселей
      СжатаяКартинка = ОбрабатываемаяКартинка.ПолучитьКартинку;
      
      Этот метод действительно позволяет уменьшить физические размеры изображения (ширину и высоту в пикселях). Однако, как правило, он приводит к значительному ухудшению качества картинки, что часто не устраивает клиента, особенно для прайс-листов, где важна визуальная привлекательность товара.
    • Сжатие через ХранилищеЗначения: Также предпринимались попытки использовать ХранилищеЗначения со сжатием данных:
      
      НовоеХранилище = Новый ХранилищеЗначения(Картинка, Новый СжатиеДанных(9));
      КартинкаСжатая = НовоеХранилище.Получить;
      
      Этот способ предназначен для сжатия данных при хранении внутри 1С, но он не влияет напрямую на то, как платформа встраивает изображения в итоговый файл Excel. Данные, извлеченные из хранилища, затем снова обрабатываются стандартными механизмами экспорта в табличный документ, и проблема большого размера файла оставалась.
  2. Настройки свойств картинки на макете табличного документа:

    В свойствах элемента "Рисунок" на макете табличного документа 1С есть свойство РазмерКартинки (или РазмерРисунка), которое определяет способ масштабирования картинки в ячейке. Возможные значения включают "Авторазмер", "Пропорционально", "РеальныйРазмер", "Растянуть" и "Черепица".

    • Были попытки установить значение "Черепица", как было предложено в одном из сообщений. Хотя это значение может влиять на способ отображения, оно, как правило, предназначено для создания фоновых узоров и приводит к нежелательному визуальному эффекту, "размножая" картинку по ячейке. Для прайс-листа это неприемлемо.
    • Другие варианты, такие как "Авторазмер" или "Пропорционально", влияют на визуальное отображение, но не всегда на фактический размер данных изображения, встраиваемых в Excel. Если платформа решает встроить "реальный размер" изображения, эти настройки лишь масштабируют его отображение, но не уменьшают объем данных.
    • Также проверяли отключение фона и узора для ячейки, но это также не помогло, поскольку проблема была глубже – в механизме встраивания самого изображения, а не его декоративных элементов.
  3. Сохранение через "дискету" на форме: Использование стандартного метода сохранения через кнопку "Сохранить" на форме табличного документа (ЭтаФорма.Таб.Записать(...)) также не решало проблему, поскольку это просто вызов того же встроенного механизма записи, который по умолчанию приводил к большому файлу.

Все эти попытки оказались либо неэффективными, либо приводили к неприемлемому качеству. Это подводило к мысли, что проблема носит более системный, платформенный характер.

Ключевое свойство: ПлотностьСохраняемыхКартинок

Для решения проблемы с большим размером файлов, содержащих изображения, в платформе 1С:Предприятие было введено специальное свойство – ПлотностьСохраняемыхКартинок для объекта ТабличныйДокумент. Это свойство предназначено для управления качеством и, соответственно, размером сохраняемых изображений при экспорте табличного документа в различные форматы, включая Excel.

Предполагалось, что мы могли бы установить это свойство, например, следующим образом:


ТабДок.ПлотностьСохраняемыхКартинок = ПлотностьСохраняемыхКартинокТабличногоДокумента.Низкая;

Значения, которые можно присвоить этому свойству, это элементы перечисления ПлотностьСохраняемыхКартинокТабличногоДокумента: Низкая, Средняя, Высокая. Выбор Низкая плотность должен был бы значительно уменьшить размер файлов за счет дополнительного сжатия изображений.

Однако, здесь возникла серьезная загвоздка. В некоторых промежуточных версиях платформы (например, в той, что использовал автор темы до обновления, а именно 8.3.25.1286), попытка установить это свойство приводила к ошибке "Несоответствие типов". Это означало, что несмотря на наличие свойства в документации, его корректное использование было невозможно из-за внутренней ошибки в самой платформе.

Эта ошибка в платформе была источником значительного разочарования для разработчиков, поскольку инструмент для решения проблемы уже был, но его нельзя было применить.

Решение проблемы: Обновление платформы и корректное использование ПлотностьСохраняемыхКартинок

Итак, после многочисленных попыток и диагностики, стало очевидно, что проблема кроется в самой платформе. Решение, которое в итоге оказалось эффективным, было следующим:

  1. Обновление платформы 1С:Предприятие:

    Ключевым шагом стало обновление платформы до более свежей версии. В данном случае, обновление до версии 8.3.27.1688 (и, вероятно, любой другой актуальной версии выше 8.3.25.x) устранило ошибку "Несоответствие типов" при работе со свойством ПлотностьСохраняемыхКартинок.

    После обновления платформы, система 1С начинает корректно распознавать и применять это свойство.

  2. Корректное использование свойства ПлотностьСохраняемыхКартинок:

    После обновления платформы, мы можем теперь успешно использовать свойство ПлотностьСохраняемыхКартинок в коде нашей обработки для формирования прайс-листа.

    Давайте рассмотрим пример кода, который демонстрирует, как это делается:

    
    &НаКлиенте
    Процедура СохранитьПрайсВExcel(Команда)
    
        // Получаем табличный документ, который уже заполнен данными и картинками
        // (Предполагаем, что ЭтаФорма.Таб содержит сформированный ТабличныйДокумент)
        ТабличныйДокументДляЭкспорта = ЭтаФорма.Таб; 
    
        // Устанавливаем плотность сохранения картинок.
        // Это критически важный шаг для уменьшения размера файла.
        // Возможные значения: ПлотностьСохраняемыхКартинокТабличногоДокумента.Низкая,
        //                   ПлотностьСохраняемыхКартинокТабличногоДокумента.Средняя,
        //                   ПлотностьСохраняемыхКартинокТабличногоДокумента.Высокая.
        // Для достижения максимального сжатия и минимального размера файла
        // выбираем значение "Низкая". Будьте готовы к возможному, но обычно приемлемому
        // снижению качества изображений в итоговом файле.
        ТабличныйДокументДляЭкспорта.ПлотностьСохраняемыхКартинок = ПлотностьСохраняемыхКартинокТабличногоДокумента.Низкая; 
    
        // Создаем диалог для выбора файла сохранения
        ДиалогСохраненияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
        ДиалогСохраненияФайла.Заголовок = "Сохранить прайс-лист в Excel";
        ДиалогСохраненияФайла.Фильтр = "Файлы Excel (*.xlsx)|*.xlsx";
        ДиалогСохраненияФайла.ПолноеИмяФайла = "ПрайсЛист.xlsx"; // Предлагаемое имя файла
    
        // Открываем диалог и ждем выбора пользователя
        Если ДиалогСохраненияФайла.Выбрать() Тогда
            Попытка
                // Сохраняем табличный документ в выбранный файл в формате XLSX.
                // Формат XLSX обеспечивает лучшее сжатие по сравнению с XLS.
                ТабличныйДокументДляЭкспорта.Записать(ДиалогСохраненияФайла.ПолноеИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
                Сообщить("Прайс-лист успешно сохранен в файл: " + ДиалогСохраненияФайла.ПолноеИмяФайла);
            Исключение Е
                Сообщить("Ошибка при сохранении прайс-листа: " + Е.Описание, СтатусСообщения.Важное);
            КонецПопытки;
        Иначе
            Сообщить("Сохранение отменено пользователем.");
        КонецЕсли;
    
    КонецПроцедуры
    

    Важные моменты:

    • Мы рекомендуем всегда сохранять файлы в формате .xlsx (ТипФайлаТабличногоДокумента.XLSX), так как этот формат по умолчанию использует сжатие и лучше подходит для больших файлов с изображениями.
    • Значение ПлотностьСохраняемыхКартинокТабличногоДокумента.Низкая обеспечит максимальное сжатие, что существенно уменьшит размер файла. Проверьте результат, чтобы убедиться, что качество изображений остается приемлемым для ваших требований. Если качество окажется недостаточным, можно попробовать Средняя плотность.

После применения этого решения, размер файла Excel с прайс-листом должен значительно уменьшиться, возвращаясь к значениям, близким к тем, что были в старой версии платформы, или даже становясь меньше.

Альтернативные подходы (если обновление платформы невозможно)

В некоторых случаях не всегда есть возможность оперативно обновить платформу. В таких ситуациях мы можем рассмотреть альтернативные методы, хотя они могут быть менее удобными или требовать дополнительных усилий:

  1. Использование ПакетОтображаемыхДокументов:

    Вместо прямого сохранения табличного документа через его метод Записать(), мы можем попробовать использовать объект ПакетОтображаемыхДокументов. Этот объект предоставляет более гибкий подход к работе с составными документами, и иногда его методы могут по-другому обрабатывать внутренние данные, включая изображения.

    Рассмотрим пример кода:

    
    &НаКлиенте
    Процедура СохранитьПрайсЧерезПакет(Команда)
    
        // Предполагаем, что ТабличныйДокумент1 уже сформирован
        // и содержит все необходимые данные, включая картинки.
        ТабличныйДокумент1 = ЭтаФорма.Таб; // Пример получения табличного документа
    
        Книга = Новый ПакетОтображаемыхДокументов;
        Лист1 = Книга.Состав.Добавить();
        // Помещаем табличный документ во временное хранилище, а затем связываем с листом
        Лист1.Данные = ПоместитьВоВременноеХранилище(ТабличныйДокумент1);
        Лист1.Имя = "ПрайсЛист"; // Имя листа в Excel
    
        // При необходимости можно добавить другие листы:
        // Лист2 = Книга.Состав.Добавить();
        // Лист2.Данные = ПоместитьВоВременноеХранилище(ДругойТабличныйДокумент);
        // Лист2.Имя = "ДополнительнаяИнформация";
    
        ДиалогСохраненияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
        ДиалогСохраненияФайла.Заголовок = "Сохранить прайс-лист через Пакет";
        ДиалогСохраненияФайла.Фильтр = "Файлы Excel (*.xlsx)|*.xlsx";
        ДиалогСохраненияФайла.ПолноеИмяФайла = "ПрайсЛист_Пакет.xlsx";
    
        Если ДиалогСохраненияФайла.Выбрать() Тогда
            Попытка
                // Сохраняем пакет документов в файл Excel.
                // Используем ТипФайлаПакетаОтображаемыхДокументов.XLSX для лучшего сжатия.
                Книга.Записать(ДиалогСохраненияФайла.ПолноеИмяФайла, ТипФайлаПакетаОтображаемыхДокументов.XLSX);
                Сообщить("Прайс-лист через пакет документов успешно сохранен: " + ДиалогСохраненияФайла.ПолноеИмяФайла);
            Исключение Е
                Сообщить("Ошибка при сохранении прайс-листа через пакет: " + Е.Описание, СтатусСообщения.Важное);
            КонецПопытки;
        Иначе
            Сообщить("Сохранение отменено пользователем.");
        КонецЕсли;
    
    КонецПроцедуры
    

    Хотя этот метод может дать другой результат сжатия, он не гарантирует такого же эффекта, как непосредственное управление плотностью изображений через ПлотностьСохраняемыхКартинок.

  2. Предварительная оптимизация изображений:

    Самый эффективный способ контроля размера файлов — это предварительная обработка изображений до их загрузки в базу 1С. Если вы можете уменьшить разрешение и размер файлов изображений до их первоначального помещения в информационную базу, это значительно снизит их "реальный размер", который затем будет выгружаться в Excel.

    • Используйте графические редакторы для уменьшения разрешения (например, до 800x600 пикселей для миниатюр прайса).
    • Оптимизируйте формат файлов (например, используйте JPEG с приемлемой степенью сжатия вместо несжатых форматов).

    Этот подход требует изменений в процессе загрузки изображений, но дает наибольший контроль над конечным размером.

  3. Использование COM-объекта Excel или генерация XML:

    В случае, если ни один из вышеперечисленных методов не дает удовлетворительного результата, мы можем рассмотреть более сложные, но мощные подходы:

    • Через COM-объект Excel: Можно программно создавать и заполнять файл Excel, управляя каждым элементом, включая вставку и сжатие изображений, используя возможности самого Excel через COM-соединение. Это дает максимальный контроль, но значительно усложняет код и требует установки Excel на сервере или клиентской машине.
    • Генерация XML для XLSX: Формат .xlsx — это набор XML-файлов внутри ZIP-архива. Теоретически, мы можем самостоятельно сформировать эти XML-файлы, включая оптимизированные изображения, и затем упаковать их в .xlsx. Это очень сложный подход, который требует глубокого понимания структуры формата XLSX, но предоставляет полный контроль над каждым байтом выходного файла.

    Эти методы являются крайними мерами, когда стандартные средства 1С не справляются с задачей, и обычно используются в проектах с очень специфическими требованиями к размеру и структуре выходных файлов.

Заключение

Проблема большого размера файлов Excel при выгрузке прайсов с картинками из 1С:Управление торговлей, возникающая после обновления платформы, является достаточно типичной и связана с изменениями в логике обработки изображений. Наиболее прямым и эффективным решением, как мы выяснили, является обновление платформы 1С:Предприятие до актуальной версии (например, 8.3.27.1688 или новее) и последующее использование свойства ПлотностьСохраняемыхКартинок для табличного документа с установкой значения ПлотностьСохраняемыхКартинокТабличногоДокумента.Низкая.

Мы настоятельно рекомендуем в первую очередь рассмотреть возможность обновления платформы, поскольку это позволяет использовать штатные и наиболее поддерживаемые механизмы 1С для оптимизации изображений. Если же обновление невозможно, мы можем прибегнуть к альтернативным методам, таким как использование ПакетОтображаемыхДокументов или предварительная оптимизация изображений, загружаемых в базу.

Выбирайте подход, который наилучшим образом соответствует вашим возможностям и требованиям к качеству и размеру выходного файла.

← На главную