Как программно повернуть PDF-документ на 90 градусов в 1С:Предприятие

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

При автоматизации документооборота в среде 1С:Предприятие разработчики часто сталкиваются с необходимостью предварительной обработки скан-копий документов. Одна из типичных задач — автоматический поворот страниц PDF-файла (например, если документ был отсканирован в альбомной ориентации, а его обработка или распознавание требуют портретной).

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

Почему не подходят клиентские методы эмуляции?

Иногда на форумах можно встретить рекомендации использовать скрипты автоматизации интерфейса через COM-объект Wscript.Shell и метод SendKeys, имитируя нажатие горячих клавиш (например, Ctrl+Shift++ для поворота страницы в программе просмотра). Рассмотрим, почему этот метод не подходит для реальных задач:

  1. Привязка к клиенту: Этот способ работает только на клиентском компьютере, где открыто интерактивное окно программы просмотра PDF.
  2. Неприменимость на сервере: На сервере 1С, работающем в фоновом режиме или в качестве службы Windows/Linux, нет активной сессии пользователя и графического интерфейса. Любая попытка вызвать эмуляцию клавиш приведет к ошибке или зависанию процесса.
  3. Низкая надежность: Интерактивные методы сильно зависят от скорости отклика интерфейса и фоновых процессов операционной системы.

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

Способ 1. Использование консольной утилиты PDFtk (Решение с форума)

Наиболее простым и надежным решением, проверенным практикой, является использование консольной утилиты 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-файл с помощью внешней утилиты.";
    КонецПопытки;
    
КонецПроцедуры

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

Способ 2. Использование утилиты QPDF (Рекомендуемый современный выбор)

Утилита 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.";
    КонецПопытки;
    
КонецПроцедуры

Способ 3. Работа со встроенными объектами «1С:Предприятие»

Начиная с современных версий платформы 1С:Предприятие 8.3.21 и выше, разработчикам стал доступен новый специализированный объект ДокументPDF. В версиях 8.3.26 и новее возможности этого объекта были расширены, в частности, появилась встроенная коллекция Страницы.

Теперь на сервере мы можем программно открыть файл PDF и прочитать его метаданные, включая текущий угол наклона страницы:


&НаСервере
Процедура ПроверитьУголПоворотаСтраниц(ПутьКФайлу)
    
    Документ = Новый ДокументPDF;
    Документ.Прочитать(ПутьКФайлу);
    
    Индекс = 1;
    Для Каждого Страница Из Документ.Страницы Цикл
        // Свойство Угол возвращает текущее значение угла поворота в градусах (0, 90, 180, 270)
        ТекущийУгол = Страница.Угол;
        Ширина = Страница.Ширина;
        Высота = Страница.Высота;
        
        Сообщить(СтрШаблон("Страница %1: Угол = %2, Ширина = %3, Высота = %4", Индекс, ТекущийУгол, Ширина, Высота));
        Индекс = Индекс + 1;
    КонецЦикла;
    
КонецПроцедуры

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

Способ 4. Кроссплатформенный вариант на Python (для Linux-серверов)

Если сервер 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 на сервере.";
    КонецПопытки;
    
КонецПроцедуры

Способ 5. Графическая конвертация через ImageMagick

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

Мы также можем применить ImageMagick для решения нашей задачи. Однако стоит учитывать специфику метода: утилита конвертирует страницы PDF-файла в промежуточное растровое изображение (JPEG), поворачивает картинку и упаковывает ее обратно в PDF. Этот способ имеет как плюсы, так и минусы.

Преимущества метода:

Недостатки метода:

Резюме и рекомендации

Подводя итоги анализа способов решения задачи, выделим ключевые рекомендации для разработчиков 1С:

  1. Для серверов на базе ОС Windows оптимальным, надежным и быстрым решением является использование бесплатной утилиты QPDF с параметром --flatten-rotation. Это гарантирует корректное отображение результата во всех типах клиентского ПО.
  2. Для Linux-серверов наиболее гибким подходом будет написание простого скрипта на Python с использованием библиотеки pypdf.
  3. Встроенный объект платформы ДокументPDF (в актуальных релизах платформы 1С:Предприятие 8.3) на данный момент рекомендуется использовать для анализа метаданных файлов и программного определения текущих углов поворота страниц перед вызовом внешних утилит.
← На главную