Как в 1С программно преобразовать присоединенный PDF-файл в картинку (PNG/JPG)?

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

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

Выясним причину, почему это происходит. Платформа 1С умеет распознавать форматы изображений (такие как PNG, JPG, GIF, BMP) по их сигнатурам в начале файла и может работать с ними напрямую. PDF — это сложный документный формат, а не изображение. Поэтому, чтобы отобразить его как картинку, его нужно предварительно конвертировать.

Общий алгоритм действий для преобразования PDF в изображение выглядит следующим образом:

  1. Получить двоичные данные присоединенного PDF-файла из хранилища 1С (удобно через модуль управления хранением и структурой присоединенных файлов).
  2. Сохранить эти данные во временный файл на диске с расширением «.pdf». Это ключевой шаг, так как внешние утилиты работают с файлами, а не с данными в памяти.
  3. Вызвать внешнюю программу-конвертер (например, ImageMagick или Ghostscript) через командную строку, передав ей путь к временному PDF-файлу.
  4. Обработать результат. Конвертер создаст один или несколько файлов-изображений (по одному на каждую страницу PDF).
  5. Использовать полученные изображения в 1С: вставить в табличный документ, сохранить как присоединенный файл и т.д.
  6. Удалить временные файлы (и исходный PDF, и полученные картинки), чтобы не засорять диск.

Рассмотрим два популярных способа реализации этого алгоритма с примерами кода.

Решение 1: Использование утилиты ImageMagick

ImageMagick — это мощный набор бесплатных программ для создания, редактирования и конвертации изображений. Он работает через командную строку и поддерживает огромное количество форматов. Подобный инструментарий также позволяет реализовать более сложные сценарии, такие как автоматизация добавления водяных знаков на фотографии — для этого подойдёт обработка автоматической вставки сканов печатей и подписей в печатные формы.

Посмотрим на пример функции, которая выполняет всю работу:


Функция КонвертироватьПрисоединенныйФайл_2_JPG(СсылкаПрисоединенныйФайл) Экспорт
	// 1. Получаем двоичные данные файла
	ДанныеФайла = РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаПрисоединенныйФайл);
	Если ДанныеФайла = Неопределено Тогда    
		Возврат Новый Массив;
	КонецЕсли;
	
	// 2. Создаем временный PDF-файл
	ПолноеИмяФайлаPDF = ПолучитьИмяВременногоФайла("pdf");
	Попытка
		ДанныеФайла.Записать(ПолноеИмяФайлаPDF);
	Исключение  
		// Обработка ошибки записи файла
		Возврат Новый Массив;
	КонецПопытки;
	
	// 3. Вызываем конвертацию через ImageMagick
	масФайлы = КонвертироватьФайл_PDF_TO_JPG(ПолноеИмяФайлаPDF);

	// 4. Удаляем временный PDF
	УдалитьФайлы(ПолноеИмяФайлаPDF);

	Возврат масФайлы; // Возвращаем массив путей к созданным картинкам
КонецФункции

Функция КонвертироватьФайл_PDF_TO_JPG(ПолноеИмяФайлаPDF) Экспорт
	пФайл = Новый Файл(ПолноеИмяФайлаPDF);
	ПутьКФайлам = пФайл.Путь;
	ИмяФайла = пФайл.ИмяБезРасширения; 
	
	// Формируем строку для командной строки
	// Здесь ПутьImageMagic() - ваша функция, возвращающая путь к convert.exe
	СтрокаВыполнить = ПутьImageMagic() + "convert -density 250 " + """" + ПолноеИмяФайлаPDF + """" + " -quality 120 " + """" + ПутьКФайлам + ИмяФайла + "-%02d.jpg" + """";  
	
	КодВозврата = 0;
	// Запускаем процесс конвертации
	ЗапуститьПриложение(СтрокаВыполнить, ПутьКФайлам, Истина, КодВозврата);
	
	// Ищем созданные файлы по маске
	МаскаДляПоиска = ИмяФайла + "-??.jpg";
	массивИменJPG = НайтиФайлы(ПутьКФайлам, МаскаДляПоиска);	
	
	мас = Новый Массив;
	Для каждого ФайлJPG из массивИменJPG Цикл
		мас.Добавить(ФайлJPG.ПолноеИмя);
	КонецЦикла;	
	
	Возврат мас;
КонецФункции

Разберем по шагам:

Решение 2: Использование утилиты Ghostscript

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


Функция КонверторPDFtoJPG_двоичные(ДвоичныеДанныеФайла, УникальныйИдентификаторФормы=Неопределено) Экспорт
	
	Путь_ВТ_Каталога = КаталогВременныхФайлов();
	// ПутьККонвертеруPDFtoJPG() - ваша функция, возвращающая путь к gswin64c.exe
	ПутьПриложенияКонвертор = ПутьККонвертеруPDFtoJPG(); 
	
	ФайлКонвертированияPDF = Путь_ВТ_Каталога + СтрЗаменить(Новый УникальныйИдентификатор, "-", "") + ".pdf";
	ФайлКонвертированияJPG = СтрЗаменить(ФайлКонвертированияPDF, ".pdf", "_p%02d.jpg");
	
	ДвоичныеДанныеФайла.Записать(ФайлКонвертированияPDF);
	
	// Формируем командную строку для Ghostscript
	СтрокаЗапуска = """" + ПутьПриложенияКонвертор + """" 
		+ " -q -dSAFER -dBATCH -dNOPAUSE -sDEVICE=jpeg -r150 -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile="
		+ """" + ФайлКонвертированияJPG + """" + " "	 	
		+ """" + ФайлКонвертированияPDF + """";
	
	// Выполняем через WScript.Shell для большего контроля
	WshShell = Новый COMОбъект("Wscript.Shell");
	WshShell.Run(СтрокаЗапуска, 0, Истина); // 0 - скрыть окно, Истина - ждать завершения
	
	// Ищем первый созданный файл
	МассивФайлов = НайтиФайлы(Путь_ВТ_Каталога, СтрЗаменить(ФайлКонвертированияJPG, "%02d.jpg", "*.jpg"));
	
	Если МассивФайлов.Количество() > 0 Тогда
		// Читаем данные первой страницы и помещаем во временное хранилище
		НовыеДвоичныеДанные = Новый ДвоичныеДанные(МассивФайлов[0].ПолноеИмя);
		СсылкаНаХранилище = ПоместитьВоВременноеХранилище(НовыеДвоичныеДанные, УникальныйИдентификаторФормы);
		
		// Очистка
		УдалитьФайлы(ФайлКонвертированияPDF);
		Для Каждого Файл Из МассивФайлов Цикл
			УдалитьФайлы(Файл.ПолноеИмя);
		КонецЦикла;
		
		Возврат СсылкаНаХранилище;
	Иначе
		УдалитьФайлы(ФайлКонвертированияPDF);
		Возврат Неопределено;
	КонецЕсли;
	
КонецФункции

В этом примере для запуска используется COMОбъект("Wscript.Shell"). Его метод Run позволяет скрыть окно консоли (параметр 0) и дождаться завершения процесса (параметр Истина). Параметр -r150 аналогичен -density в ImageMagick и задает разрешение. После конвертации код находит результат, считывает его в двоичные данные, помещает во временное хранилище и удаляет за собой все временные файлы.

Другие подходы и современные альтернативы

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

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

← На главную