При работе с Библиотекой стандартных подсистем (БСП) разработчики часто сталкиваются с проблемой: внешние печатные формы в формате docx начинают «тормозить», если объем документа превышает 5–10 страниц. Стандартная функция УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента может обрабатывать документ на 20 листов в течение нескольких минут, что неприемлемо для конечного пользователя. В этой статье мы разберем причины такого поведения платформы и рассмотрим эффективные методы оптимизации.
Основная проблема кроется не в объеме текста как таковом, а в том, как 1С и БСП взаимодействуют с внутренней структурой XML внутри файла docx. Рассмотрим основные факторы замедления:
w:rsidR. Они буквально «разрывают» слова и параметры. Например, вместо чистого параметра [ДатаДоговора] в коде может оказаться [Дата<тег>Договора].ИнициализироватьМакетОфисногоДокумента вынужден выполнять тяжелую операцию нормализации (склеивания) текстовых узлов w:t, чтобы найти параметры, разбитые тегами форматирования. Чем больше документ, тем сложнее дерево DOM и тем дольше длится поиск.ПрисоединитьОбласть система каждый раз обращается к структуре документа. На больших файлах количество узлов исчисляется десятками тысяч, что приводит к геометрическому росту нагрузки на процессор.Прежде чем переписывать код, проанализируем состояние самого макета. Часто простое «очищение» документа дает прирост скорости в несколько раз. Выполним следующие шаги:
Как показывает практика, чистый шаблон на 20 листов может инициализироваться за 10–15 секунд, в то время как «грязный» — более 2 минут.
Если стандартный механизм БСП всё равно не обеспечивает нужной скорости, проанализируем более радикальный, но эффективный метод. Файл docx — это обычный ZIP-архив, внутри которого лежит основной текст в файле word/document.xml. Мы можем работать с ним напрямую как со строкой.
Рассмотрим алгоритм реализации этого метода:
word/document.xml в строку.СтрЗаменить.Пример кода для реализации этого подхода:
// Пример упрощенной замены параметров в XML
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("zip");
ДвоичныеДанныеМакета.Записать(ИмяВременногоФайла);
ЧтениеZip = Новый ЧтениеZipФайла(ИмяВременногоФайла);
ПутьРаспаковки = КаталогВременныхФайлов() + "WorkWithDocx";
ЧтениеZip.ИзвлечьВсе(ПутьРаспаковки, РежимВосстановленияПутейФайловZip.Восстанавливать);
ЧтениеZip.Закрыть();
ПутьКXml = ПутьРаспаковки + "/word/document.xml";
ТекстДокумента = ЧтениеТекстаИзФайла(ПутьКXml); // Используйте ЧтениеТекста
// Прямая замена параметров (в шаблоне они должны быть без мусорных тегов)
ТекстДокумента = СтрЗаменить(ТекстДокумента, "[НомерДоговора]", НомерДоговора);
ТекстДокумента = СтрЗаменить(ТекстДокумента, "[Дата]", Формат(ДатаДоговора, "ДЛФ=Д"));
// Записываем измененный текст обратно
ЗаписьТекста = Новый ЗаписьТекста(ПутьКXml, КодировкаТекста.UTF8);
ЗаписьТекста.Записать(ТекстДокумента);
ЗаписьТекста.Закрыть();
// Запаковываем обратно
ЗаписьZip = Новый ЗаписьZipФайла(ИмяВременногоФайла + "_new.docx");
ЗаписьZip.Добавить(ПутьРаспаковки + "/*", РежимСохраненияПутейZip.СохранятьОтносительныеПути);
ЗаписьZip.Записать();
Важное примечание: Этот метод работает мгновенно даже на документах в 100 листов, но он требует, чтобы в шаблоне не было разбиения параметров тегами форматирования. Также этот способ не подходит, если вам нужно динамически добавлять области (строки таблиц), так как в этом случае потребуется более сложный парсинг XML (поиск узлов w:tr и их дублирование).
Если в документе есть повторяющиеся области (например, таблицы с товарами), рассмотрим комбинированный подход. Мы можем пометить начало и конец области в XML специальными комментариями или уникальными строками текста.
Проанализируем шаги:
#НачалоСтроки# и #КонецСтроки#.#НачалоСтроки# ... #КонецСтроки# на полученный результат.Такой подход позволяет обойти ограничения метода ПрисоединитьОбласть и сохранить высокую скорость формирования документа.
Подведем итог: если вы столкнулись с медленным открытием ВПФ в MS Word, в первую очередь проверьте шаблон на наличие лишнего форматирования и RSID-тегов. В 90% случаев тщательная очистка документа (через копирование в блокнот) решает проблему задержки.
Для критически важных участков, где требуется формирование огромных договоров или отчетов, откажитесь от использования УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента в пользу работы с ZIP/XML. Это обеспечит максимальную производительность и лояльность пользователей, которым не придется ждать открытия файла по несколько минут.