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

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

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

В чем кроется причина потери качества изображений?

Мы выясним, почему так происходит, обратившись к основам графики, известным нам еще со школьного курса. Существуют два основных типа изображений: растровые и векторные. Формат JPG, с которым вы работаете, является растровым изображением. Растровые изображения состоят из пикселей — маленьких цветных точек, расположенных в сетке. Когда мы увеличиваем растровое изображение, мы фактически растягиваем эти пиксели, из-за чего они становятся видимыми, и картинка выглядит зернистой. В отличие от них, векторные изображения (например, SVG) описываются математическими формулами, которые определяют линии, кривые и формы. Благодаря этому они могут масштабироваться до любого размера без потери качества.

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

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


// ... код получения двоичных данных картинки и создания объекта Картинка ...
ДД = РаботаСФайлами.ДвоичныеДанныеФайла(ХранимыйФайл,Ложь);
Картинка = Новый Картинка(ДД);

Попытка
    Размер = ДД.Размер;
Исключение
    Размер = 0;
    Картинка = Новый Картинка;
КонецПопытки;

МаксимальныйРазмер = 40000;
Если Размер > МаксимальныйРазмер Тогда
    ОбрабатываемаяКартинка = Новый ОбрабатываемаяКартинка(Картинка);
    Попытка
        Если Картинка.ПлотностьПоВертикали >= 150 Тогда
            ОбрабатываемаяКартинка.УстановитьПлотность(72, 72);
        КонецЕсли;
    Исключение
    КонецПопытки;
    //ОбрабатываемаяКартинка.Масштабировать(Макс(10,Окр(100*МаксимальныйРазмер/Размер)));
    //Ширина = Картинка.Ширина;
    //МаксимальнаяШирина = 120;
    Высота = Картинка.Высота;
    МаксимальнаяВысота = 100;
    Попытка
        Если Высота > МаксимальнаяВысота Тогда
            ОбрабатываемаяКартинка.УстановитьРазмер(Окр(Картинка.Ширина/Высота*МаксимальнаяВысота),МаксимальнаяВысота);
        КонецЕсли;
        //Если Ширина > МаксимальнаяШирина Тогда
        // ОбрабатываемаяКартинка.УстановитьРазмер(МаксимальнаяШирина,Окр(Картинка.Высота/Ширина*МаксимальнаяШирина));
        //КонецЕсли;
        Картинка = ОбрабатываемаяКартинка.ПолучитьКартинку;
    Исключение
    КонецПопытки;
КонецЕсли;
// ... код добавления картинки в ТабличныйДокумент ...

В этом фрагменте кода ключевой метод, который вызывает потерю качества, — это ОбрабатываемаяКартинка.УстановитьРазмер(Окр(Картинка.Ширина/Высота*МаксимальнаяВысота),МаксимальнаяВысота);. Когда мы вызываем УстановитьРазмер, мы фактически изменяем количество пикселей в изображении. То есть, если исходная картинка была 1000x800 пикселей, а мы устанавливаем ей размер 120x100 пикселей, то 1С создает новую, уменьшенную картинку с меньшим количеством пикселей. После этого, когда мы вставляем эту *уже сжатую* картинку в ТабличныйДокумент и сохраняем его в Excel, Excel получает именно эту уменьшенную версию. При попытке увеличить ее в Excel, система просто растягивает эти 120x100 пикселей, что и приводит к пикселизации.

Свойство КартинкаВДокументе.РазмерКартинки = РазмерКартинки.Пропорционально;, которое вы устанавливаете, лишь определяет, как изображение будет отображаться *внутри ячейки* ТабличногоДокумента, сохраняя пропорции. Оно не может вернуть утраченные пиксели, если исходное изображение уже было уменьшено.

Решение 1: Предотвращаем программное сжатие изображений в 1С

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

Давайте модифицируем ваш код из сообщения 6, исключив блок, отвечающий за сжатие:

  1. Удаляем блок сжатия: Полностью убираем конструкцию Если Размер > МаксимальныйРазмер Тогда ... КонецЕсли; вместе со всем содержимым, которое использует ОбрабатываемаяКартинка.УстановитьРазмер или ОбрабатываемаяКартинка.УстановитьПлотность.

  2. Корректно вставляем изображение: После загрузки исходной картинки мы добавляем ее в ТабличныйДокумент, управляя ее отображением через свойства.

Вот как будет выглядеть модифицированный фрагмент процедуры ВывестиКартинкиВТабДок:


Процедура ВывестиКартинкиВТабДок(ДокументРезультат, ДанныеРасшифровки)
    КоличествоСтрок = ДокументРезультат.ВысотаТаблицы;
    КоличествоКолонок = ДокументРезультат.ШиринаТаблицы;
    Для СтрокаДокумента = 1 По КоличествоСтрок Цикл
        Для КолонкаДокумента = 1 По КоличествоКолонок Цикл
            Область = ДокументРезультат.Область(СтрокаДокумента,КолонкаДокумента);
            Расшифровка = Область.Расшифровка;
            Если ТипЗнч(Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
                ПоляРасшифровки = ДанныеРасшифровки.Элементы.Получить(Расшифровка).ПолучитьПоля;
                НайденноеПоле = ПоляРасшифровки.Найти("Картинка");
                Если НЕ НайденноеПоле = Неопределено Тогда
                    ХранимыйФайл = НайденноеПоле.Значение;
                    Если ТипЗнч(ХранимыйФайл) = Тип("СправочникСсылка.НоменклатураПрисоединенныеФайлы") И ЗначениеЗаполнено(ХранимыйФайл) Тогда
                        ДД = РаботаСФайлами.ДвоичныеДанныеФайла(ХранимыйФайл,Ложь);
                        Картинка = Новый Картинка(ДД); // Здесь загружается оригинальное изображение

                        // *** ИСКЛЮЧАЕМ БЛОК СЖАТИЯ ИЗОБРАЖЕНИЯ! ***
                        // МаксимальныйРазмер = 40000;
                        // Если Размер > МаксимальныйРазмер Тогда
                        //    ОбрабатываемаяКартинка = Новый ОбрабатываемаяКартинка(Картинка);
                        //    ...
                        //    Картинка = ОбрабатываемаяКартинка.ПолучитьКартинку;
                        // КонецЕсли;

                        КартинкаВДокументе = ДокументРезультат.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
                        КартинкаВДокументе.Картинка = Картинка; // Присваиваем ОРИГИНАЛЬНУЮ картинку
                        КартинкаВДокументе.РазмерКартинки = РазмерКартинки.Пропорционально; // Отображение с сохранением пропорций
                        КартинкаВДокументе.Высота = 100; // Задаем желаемую высоту в пунктах
                        // КартинкаВДокументе.Ширина = Окр(Картинка.Ширина / Картинка.Высота * КартинкаВДокументе.Высота); // Можно задать ширину пропорционально, если нужно
                        Область.ВысотаСтроки = 70; // Высота строки, в которой будет картинка
                        КартинкаВДокументе.Расположить(Область); // Размещаем картинку в области
                    КонецЕсли;
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
КонецПроцедуры

В этом коде мы:

  1. Загружаем изображение в объект Картинка без каких-либо изменений его пиксельного состава.
  2. Создаем объект РисунокТабличногоДокумента с типом ТипРисункаТабличногоДокумента.Картинка.
  3. Присваиваем свойству КартинкаВДокументе.Картинка наш оригинальный объект Картинка.
  4. Устанавливаем свойство КартинкаВДокументе.РазмерКартинки в РазмерКартинки.Пропорционально. Это гарантирует, что изображение будет масштабировано для отображения, сохраняя свои пропорции, а главное — Excel получит изображение с его полным разрешением.
  5. Дополнительно можем указать желаемую высоту картинки в ячейке через КартинкаВДокументе.Высота. Платформа 1С самостоятельно рассчитает соответствующую ширину, исходя из пропорций.
  6. Обязательно устанавливаем высоту строки Область.ВысотаСтроки, чтобы картинка корректно отображалась.
  7. Используем метод КартинкаВДокументе.Расположить(Область) для позиционирования изображения.

Решение 2: Использование прямого формирования табличного документа и обход СКД

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

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

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

Рассмотрим, как это можно реализовать, опираясь на код из сообщения 2:


// ... код выполнения компоновки данных ...
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиОтчета,ДанныеРасшифровки,,Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

ДокументРезультат = ВыгрузитьРезультатСКДПоМакету(МакетКомпоновкиДанных,ВнешниеНаборы,Истина);

// ... далее ДокументРезультат можно сохранять в Excel ...

Функция ВыгрузитьРезультатСКДПоМакету(МакетКомпоновки, ВнешниеНаборыДанных = Неопределено, ВыводВДерево = Ложь) Экспорт
    ДокументРезультат = Новый ТабличныйДокумент; // Создаем новый ТабличныйДокумент

    Результат = Новый ТаблицаЗначений;
    Если ВыводВДерево Тогда
        Результат = Новый ДеревоЗначений;
    КонецЕсли;

    // Создаем процессор компоновки для получения данных
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    Если ВнешниеНаборыДанных = Неопределено Тогда
        ПроцессорКомпоновки.Инициализировать(МакетКомпоновки,,,Истина);
    Иначе
        ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных,,Истина);
    КонецЕсли;

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

    // Теперь, когда данные из СКД получены, заполняем ТабличныйДокумент
    // используя наш собственный макет и код для вставки картинок
    ТабличныйДокумент = Новый ТабличныйДокумент;
    Макет = ЭтотОбъект.ПолучитьМакет("МакетДляЭкселя"); // Получаем макет для ручного заполнения

    Область = Макет.ПолучитьОбласть("Шапка");
    ТабличныйДокумент.Вывести(Область);

    ТабличныйДокумент.НачатьАвтоГруппировкуСтрок;
    // Обходим дерево данных СКД и заполняем ТабличныйДокумент
    ОбходДереваДетально(Результат, ТабличныйДокумент, Макет);
    ТабличныйДокумент.ЗакончитьАвтоГруппировкуСтрок;

    Возврат ТабличныйДокумент;
КонецФункции

Процедура ОбходДереваДетально(ПереданноеДер, ТабДок, Макет)
    Для Каждого Строка Из ПереданноеДер.Строки Цикл
        Если НЕ ЗначениеЗаполнено(Строка.КоллекцияНоменклатуры) Тогда
            Продолжить;
        КонецЕсли;

        Если НЕ ЗначениеЗаполнено(Строка.Номенклатура) Тогда
            // Если номенклатура не заполнена, считаем что это группировка
            Область = Макет.ПолучитьОбласть("Группировка");
            ЗаполнитьЗначенияСвойств(Область.Параметры, Строка, "КоллекцияНоменклатуры");
            РодительЕсть = ЗначениеЗаполнено(Строка.Родитель);
            УровеньГруппировки = ?(РодительЕсть, 2, 1);
            ТабДок.Вывести(Область, УровеньГруппировки, ?(РодительЕсть,Строка.Родитель.КоллекцияНоменклатуры, Строка.КоллекцияНоменклатуры), Истина);
        КонецЕсли;

        Если ЗначениеЗаполнено(Строка.Номенклатура) Тогда
            Область = Макет.ПолучитьОбласть("Строка");
            ЗаполнитьЗначенияСвойств(Область.Параметры, Строка);
            
            // Здесь мы загружаем оригинальные двоичные данные файла
            ДД = РаботаСФайлами.ДвоичныеДанныеФайла(Строка.Картинка,Ложь);
            Картинка = Новый Картинка(ДД); // Создаем объект Картинка из оригинальных данных

            // Теперь вставляем картинку в рисунок макета.
            // Предполагается, что в макете "МакетДляЭкселя" есть элемент "Рисунки" с именем "D1".
            // Важно: в этом месте мы присваиваем оригинальный объект Картинка,
            // без предварительного сжатия методом УстановитьРазмер.
            Область.Рисунки.D1.Картинка = Картинка;
            // Управление размером картинки в ячейке осуществляется через свойства рисунка в макете
            // или программно, как было показано в Решении 1, если это не задано в макете.
            // Например, можно задать: Область.Рисунки.D1.РазмерКартинки = РазмерКартинки.Пропорционально;
            // и Область.Рисунки.D1.Высота = 100;

            ТабДок.Вывести(Область, 3, Строка.Родитель.КоллекцияНоменклатуры, Истина);
        КонецЕсли;

        Если Строка.Строки.Количество>0 Тогда
            ОбходДереваДетально(Строка, ТабДок, Макет);
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

В этой схеме мы делаем следующее:

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

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

Детальный разбор работы с картинками в ТабличномДокументе

Давайте еще раз подробно рассмотрим основные объекты и методы 1С, которые позволяют нам работать с изображениями в ТабличномДокументе, сохраняя их качество:

  1. ДвоичныеДанныеФайла и Картинка:

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

    
    ДД = РаботаСФайлами.ДвоичныеДанныеФайла(ПутьКФайлуИзображения, Ложь);
    Картинка = Новый Картинка(ДД); // Здесь объект Картинка хранит данные с полным разрешением
    

    Именно этот объект Картинка мы должны передавать в ТабличныйДокумент без каких-либо промежуточных преобразований, изменяющих его размер пикселей.

  2. Рисунки и РисунокТабличногоДокумента:

    Каждый ТабличныйДокумент имеет коллекцию Рисунки, в которую можно добавлять графические элементы. Если мы используем макет, то рисунки могут быть предварительно размещены в областях макета. Доступ к ним осуществляется через Область.Рисунки.<ИмяРисунка>.

    
    КартинкаВДокументе = ДокументРезультат.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
    КартинкаВДокументе.Картинка = Картинка; // Присваиваем оригинал!
    

    Имя рисунка в макете может быть задано в его свойствах. Например, D1.

  3. Свойство РазмерКартинки:

    Это одно из важнейших свойств РисунокТабличногоДокумента, определяющее, как изображение будет отображаться в отведенной ему области.

    • РазмерКартинки.Пропорционально: Изображение масштабируется с сохранением пропорций, чтобы максимально вписаться в отведенную область. Если область больше изображения, оно не будет растягиваться. Если область меньше, изображение будет уменьшено. Это наиболее предпочтительный вариант для сохранения качества, так как он не искажает пропорции и позволяет Excel получить исходное разрешение.
    • РазмерКартинки.АвтоРазмер: Аналогично Пропорционально, но может иметь незначительные отличия в поведении в зависимости от версии платформы.
    • РазмерКартинки.Растянуть: Изображение растягивается или сжимается так, чтобы полностью заполнить отведенную область, игнорируя пропорции. Использовать с осторожностью, так как может исказить изображение.
    • РазмерКартинки.РеальныйРазмер: Изображение отображается в своем реальном размере (1 пиксель изображения = 1 пиксель на экране/в Excel), независимо от размера ячейки. Если область меньше, изображение обрезается.
    КартинкаВДокументе.РазмерКартинки = РазмерКартинки.Пропорционально;

    Выбор РазмерКартинки.Пропорционально или РазмерКартинки.АвтоРазмер позволяет нам управлять визуальным размером без изменения фактического разрешения картинки, передаваемой в Excel.

  4. Свойства Высота и Ширина РисунокТабличногоДокумента:

    Мы можем явно указать желаемые размеры для отображения картинки в ячейке. Если задана одна из сторон (например, Высота) и установлено РазмерКартинки.Пропорционально, другая сторона будет автоматически пересчитана для сохранения пропорций.

    
    КартинкаВДокументе.Высота = 100; // Высота в пунктах
    // Если нужно, можно явно задать ширину:
    // КартинкаВДокументе.Ширина = 120;
    

    Не забудьте, что высоту строки или колонки, где находится рисунок, также следует корректировать: Область.ВысотаСтроки = 70;.

  5. Метод Расположить():

    Позволяет привязать рисунок к определенной области ТабличногоДокумента. Это важно для корректного позиционирования.

    КартинкаВДокументе.Расположить(Область);

Пример интегрированного кода для решения

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


// ... код выше, включая Функцию ВыгрузитьРезультатСКДПоМакету ...

Процедура ОбходДереваДетально(ПереданноеДер, ТабДок, Макет)
    Для Каждого Строка Из ПереданноеДер.Строки Цикл
        Если НЕ ЗначениеЗаполнено(Строка.КоллекцияНоменклатуры) Тогда
            Продолжить;
        КонецЕсли;

        Если НЕ ЗначениеЗаполнено(Строка.Номенклатура) Тогда
            // Если номенклатура не заполнена, считаем что это группировка
            Область = Макет.ПолучитьОбласть("Группировка");
            ЗаполнитьЗначенияСвойств(Область.Параметры, Строка, "КоллекцияНоменклатуры");
            РодительЕсть = ЗначениеЗаполнено(Строка.Родитель);
            УровеньГруппировки = ?(РодительЕсть, 2, 1);
            ТабДок.Вывести(Область, УровеньГруппировки, ?(РодительЕсть,Строка.Родитель.КоллекцияНоменклатуры, Строка.КоллекцияНоменклатуры), Истина);
        КонецЕсли;

        Если ЗначениеЗаполнено(Строка.Номенклатура) Тогда
            Область = Макет.ПолучитьОбласть("Строка");
            ЗаполнитьЗначенияСвойств(Область.Параметры, Строка);
            
            // Загружаем оригинальные двоичные данные файла
            ДД = РаботаСФайлами.ДвоичныеДанныеФайла(Строка.Картинка,Ложь);
            Картинка = Новый Картинка(ДД); // Создаем объект Картинка из оригинальных данных, без сжатия

            // Получаем рисунок из области макета по имени.
            // Предполагаем, что в макете "Строка" есть рисунок с именем "D1".
            Если Область.Рисунки.Найти("D1") <> Неопределено Тогда
                РисунокВОбласти = Область.Рисунки.D1;
                РисунокВОбласти.Картинка = Картинка; // Присваиваем ОРИГИНАЛЬНУЮ картинку
                РисунокВОбласти.РазмерКартинки = РазмерКартинки.Пропорционально; // Управляем отображением
                РисунокВОбласти.Высота = 70; // Устанавливаем желаемую высоту
                // Ширина будет рассчитана пропорционально автоматически
            КонецЕсли;

            ТабДок.Вывести(Область, 3, Строка.Родитель.КоллекцияНоменклатуры, Истина);
        КонецЕсли;

        Если Строка.Строки.Количество>0 Тогда
            ОбходДереваДетально(Строка, ТабДок, Макет);
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Важно убедиться, что в вашем макете (например, "МакетДляЭкселя") в области "Строка" действительно присутствует элемент типа "Рисунок" с именем "D1". Если его нет, вам потребуется добавить его вручную в конфигураторе или программно создавать РисунокТабличногоДокумента, как было показано в Решении 1.

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


// ... ДокументРезультат - это ваш сформированный ТабличныйДокумент ...
ДиалогСохраненияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
ДиалогСохраненияФайла.Заголовок = "Сохранить прайс-лист в Excel";
ДиалогСохраненияФайла.Фильтр = "Файлы Excel (*.xlsx)|*.xlsx|Все файлы (*.*)|*.*";
ДиалогСохраненияФайла.Расширение = "xlsx";

Если ДиалогСохраненияФайла.Выбрать() Тогда
    ПутьКФайлу = ДиалогСохраненияФайла.ПолноеИмяФайла;
    // Используем формат XLSX для лучшей совместимости с изображениями
    ДокументРезультат.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX); 
КонецЕсли;

Используйте формат XLSX для сохранения, так как он является более современным и обычно лучше работает с изображениями по сравнению со старым форматом XLS (Excel 97-2003).

Дополнительные рекомендации

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

  1. Формат файла Excel: Всегда отдавайте предпочтение формату XLSX (ТипФайлаТабличногоДокумента.XLSX) при сохранении из 1С. Старый формат XLS (ТипФайлаТабличногоДокумента.Excel97) имеет ряд ограничений, которые могут негативно сказываться на качестве встроенных изображений.

  2. Настройки сжатия в Excel: Даже если вы правильно экспортируете изображения из 1С, сам Excel может применять сжатие при сохранении файла, если пользователь не отключил эту опцию. Убедитесь, что в настройках Excel (обычно "Файл" -> "Параметры" -> "Дополнительно" или "Сжать рисунки") не стоит автоматическое сжатие изображений при сохранении файла.

  3. Предварительная оптимизация изображений: Если у вас очень большие исходные изображения (например, 5000x4000 пикселей), которые никогда не будут отображаться в таком разрешении, рассмотрите возможность их предварительной оптимизации. Это означает, что вы можете уменьшить их разрешение до разумного предела (например, 1500x1200 пикселей) *до загрузки в базу 1С*. Это сократит размер базы, ускорит формирование отчетов и при этом оставит достаточное качество для комфортного масштабирования в Excel. Однако, это должна быть *контролируемая* оптимизация, выполненная внешними средствами или обработками, а не автоматическое сжатие при выводе в отчет.

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

Заключение

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

  1. Гарантировать, что оригинальное, высококачественное изображение (объект Картинка) передается в ТабличныйДокумент без каких-либо программных методов, изменяющих его пиксельный размер (таких как ОбрабатываемаяКартинка.УстановитьРазмер).
  2. Управлять *визуальным* размером изображения в ТабличномДокументе с помощью свойств РисунокТабличногоДокумента.РазмерКартинки = РазмерКартинки.Пропорционально; и РисунокТабличногоДокумента.Высота/Ширина.
  3. Если стандартный вывод СКД вызывает проблемы, использовать собственный механизм формирования ТабличногоДокумента, который получает данные из СКД, а затем вручную заполняет макет, вставляя изображения с полным контролем над их качеством.

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

← На главную