При автоматизации документооборота в среде 1С:Предприятие разработчики часто сталкиваются с необходимостью предварительной обработки скан-копий документов. Одна из типичных задач — автоматический поворот страниц PDF-файла (например, если документ был отсканирован в альбомной ориентации, а его обработка или распознавание требуют портретной).
Поскольку стандартные встроенные механизмы 1С для работы с бинарными файлами PDF долгое время имели существенные ограничения, разработчики используют внешние инструменты. В этой статье мы подробно разберем, как решить задачу поворота страниц PDF-документа на 90 градусов по часовой стрелке на стороне сервера без участия пользователя.
Иногда на форумах можно встретить рекомендации использовать скрипты автоматизации интерфейса через COM-объект Wscript.Shell и метод SendKeys, имитируя нажатие горячих клавиш (например, Ctrl+Shift++ для поворота страницы в программе просмотра). Рассмотрим, почему этот метод не подходит для реальных задач:
Для надежной работы на сервере необходимо манипулировать непосредственно файлом или его бинарными данными. Рассмотрим наиболее эффективные способы решения этой задачи.
Наиболее простым и надежным решением, проверенным практикой, является использование консольной утилиты PDFtk (PDF Toolkit). На форумах часто упоминается, что программа платная, однако это заблуждение. Платным является графический интерфейс (PDFtk Pro), в то время как консольная версия PDFtk Server полностью бесплатна, распространяется под лицензией GPL и может свободно использоваться на серверах предприятий.
Для поворота страниц используется встроенная операция cat (объединение/выборка страниц) со специальными суффиксами направления: north (0°), east (90° по часовой стрелке), south (180°), west (270° по часовой стрелке).
Рассмотрим пример кода на языке 1С, который выполняет поворот всех страниц исходного документа на 90 градусов по часовой стрелке:
&НаСервере
Процедура ПовернутьPDFЧерезPDFtk(ПутьКФайлуИсточнику, ПутьКФайлуРезультату)
// Путь к исполняемому файлу утилиты на сервере
ПутьКПакету = """C:\Program Files (x86)\PDFtk\bin\pdftk.exe""";
// Экранируем пути к файлам двойными кавычками на случай наличия пробелов в путях
ФайлИсточник = """" + ПутьКФайлуИсточнику + """";
ФайлРезультат = """" + ПутьКФайлуРезультату + """";
// Параметр "1-zeast" означает: страницы с первой (1) по последнюю (z) повернуть на восток (east - 90 градусов)
ПараметрыЗапуска = ФайлИсточник + " cat 1-zeast output " + ФайлРезультат;
ПолнаяКоманда = ПутьКПакету + " " + ПараметрыЗапуска;
Попытка
// Запуск утилиты в синхронном режиме (третий параметр равен Истина)
ЗапуститьПриложение(ПолнаяКоманда, , Истина);
Исключение
ЗаписьЖурналаРегистрации("ОбработкаФайловPDF", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка при вызове PDFtk: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение "Не удалось повернуть PDF-файл с помощью внешней утилиты.";
КонецПопытки;
КонецПроцедуры
Если вам требуется повернуть только конкретную страницу (например, первую страницу многостраничного документа), синтаксис команды изменится. Вы можете собрать новый файл, указав правила для каждой страницы отдельно.
Утилита QPDF — это мощный кроссплатформенный инструмент командной строки с открытым исходным кодом для структурного преобразования PDF-файлов. Он отлично подходит для серверов под управлением как Windows, так и Linux.
Важное преимущество QPDF перед другими инструментами заключается в наличии параметра --flatten-rotation. Дело в том, что обычный поворот во многих программах просто прописывает метаданные (тег /Rotate), при этом физические координаты содержимого страницы не меняются. Некоторые старые просмотрщики или системы распознавания текста (OCR) игнорируют этот тег и продолжают видеть страницу неразвернутой. QPDF умеет полностью перестраивать (запекать) структуру содержимого под новый угол.
Рассмотрим код для вызова QPDF из 1С:
&НаСервере
Процедура ПовернутьPDFЧерезQPDF(ПутьКФайлуИсточнику, ПутьКФайлуРезультату)
ПутьКQPDF = """C:\Program Files\qpdf\bin\qpdf.exe""";
ФайлИсточник = """" + ПутьКФайлуИсточнику + """";
ФайлРезультат = """" + ПутьКФайлуРезультату + """";
// Команда поворачивает все страницы на 90 градусов (+90:1-z) и физически перестраивает их геометрию
ПараметрыЗапуска = "--rotate=+90:1-z --flatten-rotation " + ФайлИсточник + " " + ФайлРезультат;
ПолнаяКоманда = ПутьКQPDF + " " + ПараметрыЗапуска;
Попытка
ЗапуститьПриложение(ПолнаяКоманда, , Истина);
Исключение
ЗаписьЖурналаРегистрации("ОбработкаФайловPDF", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка при вызове QPDF: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение "Ошибка выполнения операции QPDF.";
КонецПопытки;
КонецПроцедуры
Начиная с современных версий платформы 1С:Предприятие 8.3.21 и выше, разработчикам стал доступен новый специализированный объект ДокументPDF. В версиях 8.3.26 и новее возможности этого объекта были расширены, в частности, появилась встроенная коллекция Страницы.
Теперь на сервере мы можем программно открыть файл PDF и прочитать его метаданные, включая текущий угол наклона страницы:
&НаСервере
Процедура ПроверитьУголПоворотаСтраниц(ПутьКФайлу)
Документ = Новый ДокументPDF;
Документ.Прочитать(ПутьКФайлу);
Индекс = 1;
Для Каждого Страница Из Документ.Страницы Цикл
// Свойство Угол возвращает текущее значение угла поворота в градусах (0, 90, 180, 270)
ТекущийУгол = Страница.Угол;
Ширина = Страница.Ширина;
Высота = Страница.Высота;
Сообщить(СтрШаблон("Страница %1: Угол = %2, Ширина = %3, Высота = %4", Индекс, ТекущийУгол, Ширина, Высота));
Индекс = Индекс + 1;
КонецЦикла;
КонецПроцедуры
Важное ограничение платформы: Несмотря на то, что объект СтраницаPDF предоставляет свойства для чтения геометрических параметров и углов, полноценное изменение свойства Угол с последующим сохранением структуры документа средствами 1С на сервере на текущий момент не поддерживается. Запись изменений встроенными методами ориентирована преимущественно на добавление вложений или работу с электронными подписями. Поэтому для изменения геометрии страниц использование внешних консольных утилит (QPDF, PDFtk) по-прежнему остается основным техническим решением.
Если сервер 1С функционирует под управлением операционной системы Linux, использование Windows-ориентированных утилит становится невозможным. В этом случае отличной альтернативой будет написание небольшого серверного скрипта на языке Python, который использует популярную библиотеку pypdf.
Сначала проанализируем код самого скрипта Python (назовем файл rotate_pdf.py):
import sys
from pypdf import PdfReader, PdfWriter
def rotate_pdf(input_path, output_path, angle):
reader = PdfReader(input_path)
writer = PdfWriter()
# Обходим все страницы и поворачиваем их на заданный угол
for page in reader.pages:
page.rotate(int(angle))
writer.add_page(page)
with open(output_path, "wb") as fp:
writer.write(fp)
if __name__ == "__main__":
# Получаем аргументы из командной строки
rotate_pdf(sys.argv[1], sys.argv[2], sys.argv[3])
Для вызова этого скрипта из 1С мы передаем пути к файлам и требуемый угол поворота в качестве аргументов командной строки:
&НаСервере
Процедура ПовернутьPDFЧерезPython(ПутьКФайлуИсточнику, ПутьКФайлуРезультату, УголПоворота)
// Задаем пути запуска скрипта
ПутьКСкрипту = "/usr/share/1c_scripts/rotate_pdf.py";
ФайлИсточник = """" + ПутьКФайлуИсточнику + """";
ФайлРезультат = """" + ПутьКФайлуРезультату + """";
СтрокаУгла = Формат(УголПоворота, "ЧГ=0");
// Формируем команду для интерпретатора python3
ПолнаяКоманда = "python3 " + ПутьКСкрипту + " " + ФайлИсточник + " " + ФайлРезультат + " " + СтрокаУгла;
Попытка
ЗапуститьПриложение(ПолнаяКоманда, , Истина);
Исключение
ЗаписьЖурналаРегистрации("ОбработкаФайловPDF", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка при вызове Python: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение "Не удалось повернуть PDF средствами Python на сервере.";
КонецПопытки;
КонецПроцедуры
В некоторых типовых конфигурациях 1С (в составе подсистемы работы с файлами) присутствует интеграция с пакетом ImageMagick. Этот инструмент используется преимущественно для разбивки многостраничных сканов и работы с растровыми форматами.
Мы также можем применить ImageMagick для решения нашей задачи. Однако стоит учитывать специфику метода: утилита конвертирует страницы PDF-файла в промежуточное растровое изображение (JPEG), поворачивает картинку и упаковывает ее обратно в PDF. Этот способ имеет как плюсы, так и минусы.
Преимущества метода:
Недостатки метода:
Подводя итоги анализа способов решения задачи, выделим ключевые рекомендации для разработчиков 1С:
--flatten-rotation. Это гарантирует корректное отображение результата во всех типах клиентского ПО.pypdf.ДокументPDF (в актуальных релизах платформы 1С:Предприятие 8.3) на данный момент рекомендуется использовать для анализа метаданных файлов и программного определения текущих углов поворота страниц перед вызовом внешних утилит.