Мы рассмотрим сложную проблему, с которой сталкиваются разработчики 1С:Предприятия при попытке сохранить диаграмму в графический файл непосредственно на сервере. Метод ПолучитьКартинку объекта Диаграмма, который прекрасно работает на клиенте, при вызове на сервере зачастую возвращает пустой графический файл. Разберем, почему это происходит, и какие подходы можно использовать для решения этой задачи.
Ситуация, описанная в первом сообщении форума, является достаточно распространенной для разработчиков 1С:Предприятия. При попытке получить изображение диаграммы и сохранить его в файл на сервере с помощью следующего кода:
ГрафикКартинка = График.ПолучитьКартинку(,,ФорматКартинки.PNG);
ГрафикКартинка.Записать("C:\temp\график.PNG");
где График — это объект типа Диаграмма, в результате получается пустой графический файл указанного формата. При этом, если точно такой же код выполнить на клиенте, файл сохраняется корректно, содержа изображение диаграммы. Данная проблема проявляется как в регламентных заданиях, так и в обычных серверных процедурах, что подтверждается сообщениями 5 и 7 из обсуждения.
Проведенный анализ показал, что проблема заключается именно в методе ПолучитьКартинку. При его выполнении на сервере, получаемые двоичные данные картинки отличаются от тех, что получаются на клиенте, и соответствуют пустому изображению. Попытки указать конкретные размеры картинки (например, 200x200) также не привели к изменению ситуации: на сервере по-прежнему генерируется пустая картинка заданных размеров, как отмечено в сообщении 9.
Для понимания причин такого поведения необходимо глубже рассмотреть архитектуру платформы 1С:Предприятие и особенности работы серверного компонента.
ПолучитьКартинку для серверного вызова содержит логику, которая по каким-то причинам не может быть успешно завершена в "безголовом" режиме, или опирается на компоненты, отсутствующие в серверном окружении по умолчанию.
В ходе обсуждения были сделаны важные наблюдения, которые помогают сузить круг поиска решения и предложить обходные пути:
ТабличныйДокумент, вероятно, использует другие, более надежные механизмы для работы с графикой на сервере, которые не зависят от наличия GUI или других специфических графических библиотек. Это может быть связано с тем, что табличный документ не "рисует" картинку сам, а скорее, инкапсулирует данные и использует специализированный компонент для экспорта в PDF, который способен самостоятельно рендерить графические объекты.
Учитывая выявленные особенности, мы можем рассмотреть несколько стратегий для решения задачи сохранения диаграммы в файл на сервере.
Поскольку на клиенте метод ПолучитьКартинку работает корректно, одним из наиболее надежных обходных путей является генерация изображения на стороне клиента, а затем его передача на сервер для сохранения в файл.
Шаги реализации:
// В клиентской процедуре
ГрафикКартинка = Элементы.ПолеДиаграммы.Значение.ПолучитьКартинку(,,ФорматКартинки.PNG); // Элементы.ПолеДиаграммы.Значение - это сама Диаграмма
ДвоичныеДанныеКартинки = ГрафикКартинка.ПолучитьДвоичныеДанные();
// Продолжение клиентской процедуры
АдресВременногоХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеКартинки, УникальныйИдентификатор);
Затем вызываем серверную процедуру:
// Вызов серверной процедуры
СохранитьКартинкуНаСервере(АдресВременногоХранилища, "C:\temp\график.PNG");
// Серверная процедура
Процедура СохранитьКартинкуНаСервере(АдресВременногоХранилища, ПутьКФайлу) Экспорт
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВременногоХранилища);
Если ДвоичныеДанные <> Неопределено Тогда
ДвоичныеДанные.Записать(ПутьКФайлу);
Иначе
ЗаписьЖурналаРегистрации(НСтр("ru='Не удалось получить данные картинки из временного хранилища.'"), УровеньЖурналаРегистрации.Ошибка);
КонецЕсли;
КонецПроцедуры
Важно: Этот метод подходит, если инициация сохранения может происходить с клиента (например, по кнопке пользователя). Для регламентных заданий или полностью серверного кода этот вариант не подходит, поскольку клиент отсутствует.
Как было выяснено, сохранение диаграммы в PDF через табличный документ на сервере работает корректно. Этот подход является весьма ценным, если конечной целью может быть PDF-файл. К сожалению, напрямую получить растровый графический файл (PNG, JPG) из табличного документа на сервере без GUI может быть также затруднительно из-за тех же ограничений. Однако, сам факт успешной работы с PDF указывает на потенциал.
Принцип:
Объект ТабличныйДокумент, по всей видимости, имеет свои собственные механизмы рендеринга графических объектов или использует системные компоненты, которые доступны на сервере и не требуют активного GUI. Он способен корректно обрабатывать и встраивать диаграмму для последующего экспорта в PDF.
Пример кода для сохранения в PDF (подтвержденный обходной путь):
// Серверная процедура (например, в регламентном задании)
Процедура СохранитьДиаграммуВPDFНаСервере() Экспорт
// Предположим, у нас есть Диаграмма с данными
Диаграмма = Новый Диаграмма;
// ... Заполняем Диаграмму данными (пример) ...
Диаграмма.Заголовок = "Пример Диаграммы";
Диаграмма.ТипДиаграммы = ТипДиаграммы.ГистограммаОбъемная;
Серия1 = Диаграмма.Серии.Добавить();
Серия1.Имя = "Серия 1";
Серия1.Значение = 100;
Серия2 = Диаграмма.Серии.Добавить();
Серия2.Имя = "Серия 2";
Серия2.Значение = 150;
Точка1 = Диаграмма.Точки.Добавить();
Точка1.Имя = "Точка 1";
Точка1.Значение = 1;
Значение11 = Диаграмма.Значения.Добавить();
Значение11.Серия = Серия1;
Значение11.Точка = Точка1;
Значение11.Значение = 20;
Значение12 = Диаграмма.Значения.Добавить();
Значение12.Серия = Серия2;
Значение12.Точка = Точка1;
Значение12.Значение = 30;
// Создаем новый ТабличныйДокумент
ТабДок = Новый ТабличныйДокумент;
// Определяем область, в которую будет вставлена диаграмма
// Можем задать размер области, чтобы диаграмма отображалась корректно
ОбластьДляДиаграммы = ТабДок.Область(1, 1, 20, 10); // Например, 20 строк, 10 колонок
ТабДок.Вывести(ОбластьДляДиаграммы); // Важно вывести область, даже если она пустая
// Добавляем рисунок типа Диаграмма в ТабличныйДокумент
РисунокДиаграмма = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Диаграмма);
РисунокДиаграмма.Область = ОбластьДляДиаграммы; // Привязываем к нашей области
РисунокДиаграмма.Объект = Диаграмма;
РисунокДиаграмма.РазмерКартинки = РазмерКартинки.Авто;
РисунокДиаграмма.ВыводитьЗаголовок = Истина;
РисунокДиаграмма.Текст = Диаграмма.Заголовок; // Можно указать текст, если заголовок не выводится по другим причинам
// Сохраняем табличный документ в формате PDF
ПутьКФайлуPDF = "C:\temp\диаграмма.pdf";
Попытка
ТабДок.Записать(ПутьКФайлуPDF, ТипФайлаТабличногоДокумента.PDF);
ЗаписьЖурналаРегистрации(НСтр("ru='Диаграмма успешно сохранена в файл: '") + ПутьКФайлуPDF, УровеньЖурналаРегистрации.Информация);
Исключение
ЗаписьЖурналаРегистрации(НСтр("ru='Ошибка при сохранении диаграммы в PDF: '") + ОписаниеОшибки(), УровеньЖурналаРегистрации.Ошибка);
КонецПопытки;
КонецПроцедуры
Этот метод подтвержден как рабочий и является хорошим решением, если конечной целью может быть PDF-файл. Если нужен именно растровый формат (PNG/JPG), придется либо использовать внешние инструменты для конвертации PDF в PNG на сервере (что усложняет решение), либо принять факт, что прямой способ получить растровую картинку из Диаграммы на сервере без GUI крайне затруднителен.
Хотя этот вариант менее вероятен для "чистого" 1С-кода, особенно если проблема носит системный характер, стоит убедиться, что окружение сервера соответствует минимальным требованиям для работы с графикой.
ПолучитьКартинку. Подробные логи могут указать на отсутствие DLL-файлов или сбои в вызовах системных функций.
Проблема с методом График.ПолучитьКартинку() на сервере 1С:Предприятия, вероятно, связана с особенностями работы в среде без графического интерфейса и отсутствием необходимых системных компонентов для рендеринга. Прямого и простого решения, которое позволило бы использовать ПолучитьКартинку на сервере так же эффективно, как на клиенте, не обнаружено. Однако, существуют эффективные обходные пути.
Если вам нужен PDF-файл, мы настоятельно рекомендуем использовать ТабличныйДокумент в качестве посредника — этот метод подтвержден как рабочий и надежный. Если же требуется именно растровое изображение (PNG, JPG) для серверного задания, рассмотрите возможность генерации на клиенте с последующей передачей двоичных данных на сервер. В крайнем случае, для получения растрового изображения из PDF на сервере, возможно, потребуется интеграция со сторонними инструментами для конвертации форматов, что, однако, значительно усложняет архитектуру решения.
Мы продолжим следить за развитием платформы 1С и надеемся, что в будущих версиях появятся более удобные и прямые способы работы с графикой на сервере без привязки к GUI.