Как ускорить медленное сохранение большого табличного документа в PDF в 1С?

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

При работе с объёмными печатными формами — например, массовой рассылкой квитанций ЖКУ, реестров или платежных документов — разработчики 1С нередко сталкиваются с проблемой: метод ТабличныйДокумент.Записать() в формат PDF выполняет сохранение крайне долго. Экспорт одного файла на 2000 страниц без иллюстраций может занимать от 8 до 15 минут, а если таких файлов десятки, процесс формирования затягивается на многие часы. Проанализируем, почему возникает эта задержка и как можно существенно ускорить генерацию PDF-файлов.

Выясним причины медленной работы метода Записать()

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

  1. Накладные расходы на верстку и шрифты: При экспорте платформе приходится рассчитывать точные метрики текста, пересчитывать автовысоту строк, обрабатывать объединённые ячейки и внедрять подмножества шрифтов (Font Subsetting) для каждой страницы.
  2. Однопоточная обработка платформой: Даже если сервер 1С имеет 32 ядра процессора, сохранение одного объекта ТабличныйДокумент утилизирует вычислительные ресурсы только одного вычислительного ядра.
  3. Задержки дискового ввода-вывода (I/O): Запись файла напрямую по сетевому пути или на медленный накопитель создает дополнительную нагрузку при множественных файловых операциях.
  4. Опрос подсистемы печати ОС: При формировании макета платформа может выполнять обращения к свойствам локального или сетевого принтера по умолчанию для расчёта границ и ориентации страниц.

Способ 1. Нарезка документа и многопоточная запись через фоновые задания

Наиболее эффективный подход к ускорению — распараллеливание процесса. Если сформировать единый документ на 2000 страниц и записывать его в один поток, сохранение займет около 8 минут. Но если разбить данные на 8 независимых частей по 250 страниц и запустить их обработку параллельно через ФоновыеЗадания, общее время сократится в разы.

Рассмотрим по шагам алгоритм организации многопоточной выгрузки:

  1. Делим исходный массив данных (например, список лицевых счетов или адресов) на равные порции.
  2. Для каждой порции запускаем фоновое задание через ФоновыеЗадания.Выполнить().
  3. Внутри фонового задания формируем отдельный ТабличныйДокумент и сохраняем его локально во временный PDF-файл.
  4. После выполнения всех потоков объединяем полученные части в один файл с помощью консольных утилит или передаем файлы в типографию отдельными пакетами.

Разберем пример кода для запуска фоновых процессов:


// Процедура-управляющий алгоритм многопоточной выгрузки
Процедура ВыгрузитьКвитанцииВНесколькоПотоков(МассивДанных) Изпользовать
    
    КоличествоПотоков = 8;
    РазмерПорции = Цел(МассивДанных.Количество() / КоличествоПотоков);
    
    МассивЗаданий = Новый Массив;
    
    Для НомерПотока = 1 По КоличествоПотоков Цикл
        
        // Формируем порцию данных для текущего потока
        НачальныйИндекс = (НомерПотока - 1) * РазмерПорции;
        
        ПараметрыПотока = Новый Структура;
        ПараметрыПотока.Вставить("ИмяФайла", "C:\Temp\Export_Part_" + Строка(НомерПотока) + ".pdf");
        ПараметрыПотока.Вставить("ИндексНачала", НачальныйИндекс);
        ПараметрыПотока.Вставить("Количество", РазмерПорции);
        
        МассивПараметров = Новый Массив;
        МассивПараметров.Добавить(ПараметрыПотока);
        
        // Запуск фонового задания в платформе 1С
        Задание = ФоновыеЗадания.Выполнить("МодульВыгрузки.СформироватьИСохранитьЧастьPDF", МассивПараметров);
        МассивЗаданий.Добавить(Задание);
        
КонецЦикла;
    
    // Ожидаем завершения всех фоновых заданий
    ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
    
КонецПроцедуры

Способ 2. Запись на локальный SSD и оптимизация работы с диском

Никогда не выполняйте метод ТабличныйДокумент.Записать() напрямую по сетевому пути (UNC-пути) или на медленные сетевые шарды. Сохраняйте файл во временный каталог на локальном SSD-диске сервера с помощью функции ПолучитьИмяВременногоФайла("pdf"), а затем копируйте готовый файл в целевую директорию файловой системой ОС.


ВременныйФайл = ПолучитьИмяВременногоФайла("pdf");

// Быстрая запись на локальный диск
ТабДок.Записать(ВременныйФайл, ТипФайлаТабличногоДокумента.PDF);

// Перемещение файла в целевой сетевой каталог
ПереместитьФайл(ВременныйФайл, ЦелевойСетевойПуть);

Способ 3. Использование сторонних компонент и внешних библиотек

Если штатный механизм платформы 1С не обеспечивает требуемой скорости, проанализируем варианты использования специализированных библиотек и внешних компонент:

  1. Библиотека iTextSharp / iText7: Генерация PDF с использованием внешней C#-компоненты или .NET-обертки работает значительно быстрее штатных средств 1С. Вы можете передавать из 1С структуру данных или готовый HTML/XML, а формирование структуры PDF доверить скомпилированному коду.
  2. Внешняя библиотека Йоксель (Yoksel): Позволяет быстро конвертировать табличные документы 1С в форматы Excel/PDF, минуя некоторые накладные расходы платформы при просчете макета.
  3. Двухэтапный экспорт через HTML5: Сохранение табличного документа из 1С в формат HTML5 (ТипФайлаТабличногоДокумента.HTML5) выполняется в десятки раз быстрее, чем в PDF. Полученный HTML-файл мгновенно конвертируется в PDF сторонними консольными утилитами (например, Headless Chrome, Puppeteer или wkhtmltopdf) в режиме командной строки.

Способ 4. Оптимизация параметров макета и свойств печатной формы

Для ускорения работы штатного алгоритма 1С при формировании табличного документа соблюдайте следующие правила:


ТабДок.АвтоМасштаб = Ложь;
ТабДок.ИмяПринтера = "";
ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
ТабДок.КоличествоЭкземпляров = 1;

Применение многопоточной нарезки данных в сочетании с сохранением на локальный SSD позволяет сократить общее время выгрузки печатных форм в PDF в 4–8 раз, успешно укладываясь в строгие временные рамки регламентных процедур.

← На главную