Как сжать картинки в прайс-листе при выгрузке из 1С в Excel после обновления платформы?

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

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

Почему Excel-файлы с картинками из 1С становятся слишком большими?

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

  1. Изменения в платформе 1С:Предприятие: Пользователи заметили, что до определенного обновления платформы (например, до 8.3.20.1674) механизм экспорта мог автоматически сжимать изображения. После обновления это поведение изменилось, и картинки стали сохраняться в их исходном размере, что значительно увеличивает объем файла. Прямых упоминаний об изменении механизма автоматического сжатия в документации к конкретным версиям платформы может и не быть, однако это могло стать побочным эффектом других оптимизаций или изменений во взаимодействии с операционной системой или компонентами MS Office.
  2. Формат сохранения 1С в Excel: По умолчанию 1С может экспортировать табличный документ в старый формат Excel (например, 05 MS EXCEL), который не всегда эффективно обрабатывает современные форматы изображений или метаданные, что также может способствовать увеличению размера файла, если изображения не сжимаются должным образом.
  3. Внутренняя конвертация изображений: При сохранении в Excel, 1С иногда может выполнять внутреннюю переконвертацию изображений. Например, файлы формата JPG могут быть конвертированы в PNG. Хотя PNG является форматом сжатия без потерь и часто используется для изображений с четкими границами или прозрачностью, для фотографий он зачастую дает больший размер файла по сравнению с JPG при сравнимом визуальном качестве. Это может привести к увеличению объема, даже если качество изображения не улучшается.
  4. Хранение исходного размера в Excel: Сам Excel, даже если мы визуально уменьшаем изображение на листе, может хранить данные об изображениях в их исходном, высоком разрешении и качестве. Это означает, что если в отчет вставлена фотография размером несколько мегапикселей, Excel сохранит все эти данные, даже если в ячейке она отображается в виде маленькой превьюшки. Это значительно увеличивает размер файла, поскольку несжатые данные занимают много места.

Понимание этих причин поможет нам выбрать наиболее эффективный подход к решению проблемы.

Решение 1: Сжатие картинок непосредственно в Microsoft Excel

Один из самых простых и эффективных способов уменьшить размер файла с прайс-листом после экспорта из 1С – это воспользоваться встроенной функцией сжатия изображений в самом Microsoft Excel. Этот метод работает независимо от версии платформы 1С и не требует программных изменений в конфигурации.

Пошаговая инструкция по сжатию картинок в Excel

Рассмотрим, как вы можете выполнить это вручную после сохранения прайс-листа в формате .xls или .xlsx:

  1. Откройте файл Excel: После экспорта прайс-листа из 1С, откройте получившийся файл в Microsoft Excel.
  2. Выберите изображение: Щелкните по любому изображению в вашем документе Excel, чтобы активировать вкладку "Формат рисунка" (или "Работа с рисунками" / "Формат" в более старых версиях Excel) на ленте.
  3. Найдите функцию "Сжать рисунки": На вкладке "Формат рисунка" найдите группу "Настройка" (или "Изменить") и нажмите кнопку "Сжать рисунки".
  4. Настройте параметры сжатия: Откроется диалоговое окно "Сжатие рисунков". Здесь вам будут доступны следующие опции:
    • Параметры сжатия:
      • "Применить ко всем рисункам в документе": Обязательно установите этот флажок, если вы хотите сжать все изображения в прайс-листе, а не только выбранное.
      • "Удалить обрезанные области рисунков": Эта опция полезна, если вы обрезали изображения в Excel. Удаление обрезанных частей поможет дополнительно уменьшить размер файла.
    • Разрешение: Здесь выберите целевое разрешение для изображений. От этого параметра будет зависеть степень сжатия и, соответственно, конечный размер файла. Мы рекомендуем следующие значения:
      • "Веб (150 ppi)": Отличное качество для отображения на экране и печати на большинстве офисных принтеров. Хороший баланс между качеством и размером.
      • "Электронная почта (96 ppi)": Максимально сжимает изображения для отправки по электронной почте, но качество для печати может быть низким. Используйте, если критичен минимальный размер файла и печать не предполагается.
      • "Печать (220 ppi)": Если прайс-лист предназначен для высококачественной печати, но все еще требует сжатия по сравнению с исходным разрешением.
  5. Примените сжатие: После выбора всех необходимых параметров нажмите кнопку "ОК". Excel обработает все изображения в документе, и вы заметите значительное уменьшение размера файла при его сохранении.

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

Решение 2: Программное сжатие картинок в 1С перед экспортом

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

Использование объекта "Картинка" и метода УстановитьРазмер()

В 1С есть возможность программно управлять размерами изображений. Для этого используется объект Картинка и его метод УстановитьРазмер(). Этот метод позволяет изменить размеры картинки по вертикали и горизонтали, при этом можно сохранить пропорции.

  1. Загрузка двоичных данных: Сначала нам нужно получить двоичные данные файла изображения, которые хранятся в базе данных, например, из регистра сведений ДвоичныеДанныеФайлов, как это указано в исходном запросе автора темы.
  2. Создание объекта Картинка: Из полученных двоичных данных мы создаем объект Картинка.
  3. Изменение размера: Используем метод УстановитьРазмер() для уменьшения размеров. Мы можем задать новую ширину или высоту, и 1С пропорционально изменит вторую величину.
  4. Получение сжатых двоичных данных: После изменения размера, мы можем получить новые двоичные данные из объекта Картинка, которые будут содержать уже уменьшенное изображение. Эти данные затем могут быть использованы для вставки в табличный документ отчета.

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


// Предположим, у нас есть ДвоичныеДанныеФайла из запроса
// ДвоичныеДанныеФайлов.ДвоичныеДанныеФайла КАК КартинкаДвоичныеДанные
// и мы хотим получить объект Картинка
// Из запроса СКД мы получаем ДвоичныеДанныеФайла

// Пример извлечения двоичных данных и их обработки
Функция ПолучитьСжатуюКартинкуДляОтчета(ДвоичныеДанныеФайла, МаксимальнаяШирина = 200, МаксимальнаяВысота = 200)

    Если ТипЗнч(ДвоичныеДанныеФайла) <> Тип("ДвоичныеДанные") Тогда
        Возврат Неопределено; // или выдать ошибку, или вернуть исходные данные
    КонецЕсли;

    Попытка
        КартинкаОбъект = Новый Картинка(ДвоичныеДанныеФайла);
    Исключение
        Возврат Неопределено; // Не удалось создать картинку из двоичных данных
    КонецПопытки;

    Если КартинкаОбъект.Ширина > МаксимальнаяШирина ИЛИ КартинкаОбъект.Высота > МаксимальнаяВысота Тогда
        // Определяем новые размеры с сохранением пропорций
        КоэффициентШирины = МаксимальнаяШирина / КартинкаОбъект.Ширина;
        КоэффициентВысоты = МаксимальнаяВысота / КартинкаОбъект.Высота;

        Если КоэффициентШирины < КоэффициентВысоты Тогда
            // Ограничиваем по ширине
            НоваяШирина  = МаксимальнаяШирина;
            НоваяВысота = Цел(КартинкаОбъект.Высота * КоэффициентШирины);
        Иначе
            // Ограничиваем по высоте
            НоваяВысота = МаксимальнаяВысота;
            НоваяШирина  = Цел(КартинкаОбъект.Ширина * КоэффициентВысоты);
        КонецЕсли;

        // Применяем новые размеры
        КартинкаОбъект.УстановитьРазмер(НоваяШирина, НоваяВысота);
    КонецЕсли;

    Возврат КартинкаОбъект; // Возвращаем объект Картинка уменьшенного размера
КонецФункции

// Пример использования в процедуре формирования отчета
// ...
// ТабличныйДокумент = Новый ТабличныйДокумент;
// ...
// Если РезультатЗапроса.Следующий() Тогда
//     ОбластьМакета.Параметры.Номенклатура = РезультатЗапроса.Номенклатура;
//     
//     КартинкаДляОтчета = ПолучитьСжатуюКартинкуДляОтчета(РезультатЗапроса.КартинкаДвоичныеДанные, 150, 150);
//     Если КартинкаДляОтчета <> Неопределено Тогда
//         ТабличныйДокумент.Картинки.Добавить(КартинкаДляОтчета, ОбластьМакета.Область("B2:C5"), ОбластьМакета); // Пример вставки
//     КонецЕсли;
//
//     ТабличныйДокумент.Вывести(ОбластьМакета);
// КонецЕсли;
// ...

Важно отметить, что УстановитьРазмер() изменяет только разрешение картинки. Она не выполняет JPEG-сжатие, которое позволяет значительно уменьшить размер файла за счет потери качества. Для JPEG-сжатия могут потребоваться внешние компоненты или библиотеки.

Использование внешних обработок/сервисов для сжатия

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

  1. Уменьшать физический размер изображений.
  2. Перекодировать изображения в более эффективные форматы (например, из PNG в JPG).
  3. Настраивать степень сжатия JPG для оптимального баланса между качеством и размером.

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

Решение 3: Управление сжатием картинок в Excel через COM-объект из 1С

Более сложным, но потенциально мощным подходом является программное управление Microsoft Excel через COM-объект из 1С. Этот метод позволяет автоматизировать действия, которые мы выполняем вручную в Excel.

Идея программного сжатия через COM-объект

Основная идея заключается в следующем:

  1. Сформировать отчет в 1С и сохранить его во временный файл Excel.
  2. Открыть этот файл с помощью COM-объекта Excel.Application.
  3. Программно вызвать функцию сжатия изображений в Excel.
  4. Сохранить измененный файл Excel.

Однако прямой программный доступ к функции "Сжать рисунки" (Compress Pictures) в Excel через VBA (а значит, и через COM-объект из 1С) может быть неочевиден или ненадежен. Макросы, созданные записью действий пользователя в Excel, не всегда включают необходимые команды для сжатия, поскольку это часто является частью более высокоуровневых операций. В некоторых случаях могут использоваться методы, имитирующие нажатия клавиш (SendKeys), но этот подход крайне ненадежен и не рекомендуется для использования в продуктивных системах из-за зависимости от фокуса окна и скорости выполнения.

Альтернативные методы через COM-объект

Вместо прямого вызова функции сжатия, мы можем попробовать управлять свойствами каждого изображения в Excel. Например, можно перебирать все объекты Shape (которые включают изображения) на листах Excel и пытаться программно изменять их свойства. Однако, API Excel через COM не предоставляет прямого метода для "сжатия" изображения в том смысле, как это делает пользовательская функция. Чаще всего, через COM можно управлять размером, позицией, иногда качеством сохранения, но не запускать процесс перекодирования и сжатия, который происходит при использовании кнопки "Сжать рисунки".

В контексте 1С и табличных документов, для сохранения исходных размеров и разрешения картинки при экспорте в Excel, можно установить для свойства РазмерКартинки в табличном документе значение РазмерКартинки.Растянуть или РазмерКартинки.Авто. Это влияет на то, как картинка масштабируется в ячейке, но не на ее фактические двоичные данные, которые передаются в Excel.

Пример работы с COM-объектом Excel для открытия файла (без конкретного кода сжатия, так как он сложен и ненадежен):


// ... код формирования ТабличногоДокумента и сохранения его во временный файл
ИмяФайлаExcel = КаталогВременныхФайлов() + "ПрайсЛист.xlsx";
ТабличныйДокумент.Записать(ИмяФайлаExcel, ТипФайлаТабличногоДокумента.XLSX);

// Создаем объект Excel
Попытка
    ExcelПриложение = Новый COMОбъект("Excel.Application");
    ExcelПриложение.Visible = Истина; // Или Ложь, если не хотим показывать пользователю
    КнигаExcel = ExcelПриложение.Workbooks.Open(ИмяФайлаExcel);

    // Здесь может быть код для перебора листов и объектов Shape (рисунков)
    // и попытки изменить их свойства, но прямое сжатие через COM не всегда доступно.
    // Например, можно попробовать изменить размер или свойства объекта.

    // КнигаExcel.Save(); // Сохранить изменения
    // КнигаExcel.Close();
    // ExcelПриложение.Quit();

Исключение
    Сообщить("Ошибка при работе с COM-объектом Excel: " + ОписаниеОшибки());
КонецПопытки;

Рекомендации по работе с COM-объектами Excel

Для стабильной работы с COM-объектами Excel, особенно на сервере 1С, необходимо учитывать несколько моментов:

  1. Установленная версия Excel: На компьютере или сервере, где выполняется код с COM-объектом, должна быть установлена соответствующая версия Microsoft Excel.
  2. Права доступа: Для пользователя, под которым запускается служба 1С (или пользователь, который работает с тонким/толстым клиентом), должны быть настроены достаточные права для запуска DCOM Microsoft Excel Application. Это часто является источником проблем при серверной работе.
  3. Освобождение объектов: Крайне важно корректно освобождать все COM-объекты после работы (КнигаExcel.Close(), ExcelПриложение.Quit(), а также устанавливать переменные в Неопределено), чтобы избежать зависания процессов Excel в памяти.

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

Вывод картинок в отчетах на СКД

В контексте Системы Компоновки Данных (СКД), вывод картинок часто требует программной доработки, поскольку стандартными средствами конструктора СКД задача не всегда решается в полном объеме. Как правило, двоичные данные картинки можно получить запросом, как это сделал автор (ДвоичныеДанныеФайлов.ДвоичныеДанныеФайла КАК Картинка). Однако, вставить эти данные в табличный документ как полноценное изображение с нужным размером и расположением обычно приходится в процедуре ПриКомпоновкеРезультата() или аналогичной, где программно формируется табличный документ и в него вставляются картинки с помощью методов объекта ТабличныйДокумент.Картинки.Добавить(), используя объект Картинка.

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

Заключение

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

Для более глубокой и автоматизированной оптимизации мы рассмотрели варианты программного сжатия картинок в 1С с использованием объекта Картинка и метода УстановитьРазмер(), а также возможность использования специализированных внешних обработок. Эти методы требуют доработки конфигурации, но позволяют контролировать размер изображений еще до формирования отчета.

Наконец, мы обсудили возможности и ограничения управления Excel через COM-объект. Хотя этот метод потенциально позволяет автоматизировать многие действия, прямое вызов функции сжатия изображений через COM является сложным и ненадежным, поэтому рекомендуется использовать его с осторожностью или для других задач управления Excel.

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

← На главную