Заполнение шаблона Word на сервере, без использования MS Office (docx -> zip -> xml). Предусмотрен вывод табличных частей





Шаблон в Word, управляемые формы. Создание заполнение документа Word (docx -> zip -> xml) по шаблону на сервере без использования MS Office. Предусмотрен вывод табличных частей.

Обработать шаблон документа Word на сервере это проблема, с которой уверен сталкивались многие. Библиотека стандартных подсистем делает обработку шаблона на клиенте, а это исключает веб интерфейс и рабочие места, где нет MS Office. При попытке в Word открыть шаблон файла под серверным пользователем, возникают проблемы с доступом. Не отрицаю существования таких настроек на сервере, при которых это возможно, но в моем случае речь шла о массовом продукте. 

Чтобы избавиться от всех прелестей этой прекрасной пары 1с+Word, решил отказаться от Word, хотя над первым может тоже стоило подумать?

Формат MS Word (docx)  — это по сути zip архив с набором xml файлов (Office Open XML). Меняя определенные файлы xml, можно добиться заполнения своего шаблона.

Всю красоту парсинга XML,  из 1с уверен, вы сможете или уже смогли оценить в своей работе.

О решении:

Результатом решения стал общий модуль осуществляющий всю работу по заполнению шаблона.

Общий модуль, для простоты скачивания поместил в модуль обработки.

Процедура ответственная за заполнение шаблона:

ОбработатьФайлDocx(ФайлШаблона,ПараметрыЗаполнения, ШаблоныКЗамене)

  • ФайлШаблона  — (тип: "Строка") Путь к файлу шаблону.
  • ПараметрыЗаполнения  — (тип: "Структура") содежащую символ начала, окончания шаблона.
  • ШаблоныКЗамене — (тип: "Таблица значений") с параметрами, содержащую колонки:  ИмяПараметраВWord — строка с именем шаблона который будет заменен. Результат — Содержит значение на которое будет заменен шаблон.

 

Колонка «Результат»  из «ШаблоныКЗамене»  может иметь тип: "Строка" или "Массив" (содержащий строки).

  • Колонка «Результат» тип "Строка" — заменяет шаблон. 
  • Колонка «Результат» тип "Массив" (содержащий строки). — заменяет шаблон. перечисляет строки через ";", Но если он использован в word таблице, то добавляет строки (если значений в массиве больше чем одно) и расставляет значения. 

Пример 1:

ШаблоныКЗамене имеет строки:

ИмяПараметраВWord = «массив 1» , Результат(массив) содержит два значения: ("Значение 1 массив 1"; "Значение 2 массив 1" ,

ИмяПараметраВWord =  «массив 2», Результат(массив) содержит три значения:("Значение 1 массив 2";"Значение 2 массив 2";"Значение 3 массив 2") :

Пример шаблона в таблице word:

<массив 1>

<массив 2>

 

Результат:

Значение 1 массив 1

Значение 1 массив 2

Значение 2 массив 1

Значение 2 массив 2

 

Значение 3 массив 2

 

Пример 2:

ШаблоныКЗамене имеет строку:

ИмяПараметраВWord = «МассивЧленыКомиссии» ; Результат(массив) содержит значения: ("Прохоров Сергей Петрович"; "Петров Адрей Федорович"; "Смирнов Антон Викторович")

 

Шаблон:

Члены комиссии

   

<МассивЧленыКомиссии>

 

Результат:

Члены комиссии

   

Прохоров Сергей Петрович

     

Петров Адрей Федорович

     

Смирнов Антон Викторович

 

Жду ваших комментариев и предложений.

Модуль можете использовать для коммерческого использования, однако прошу не удалять ссылку на мои реквизиты.

 

27 Comments

  1. Поручик

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

    Reply
  2. IsiKosta

    Спасибо! Наверняка пригодится для моей публикации https://infostart.ru/public/595984/

    Reply
  3. sytkosa

    С макетами сформированными в формате docx отличным от 2010 office будет работать? Например в макете созданным и сохраненным в 2016 word?

    Reply
  4. Dimasik2007

    (0) Автору спасибо, формируется все быстро. Интгерировал с подсистемой «Печать» БСП. Также добавил возможность вставки картинки в документ (реализовал заменой картинки-эталона в папке media). Тестировал на 2010 офисе.

    Reply
  5. websamson

    Спасибо, работает! Только добавьте в описание, что в макете после параметров нужно добавлять пробел, иначе параметр не отображается на печати.

    Reply
  6. XelOla

    (5)

    макете после параметров нужно добавлять пробел, иначе параметр не отображается на печати.

    как это

    Reply
  7. artms

    (3) ДА конечно

    Reply
  8. artms

    (6) В Word пробел может записываться в XML специальным тегом (не всегда) . В некоторых ситуациях такое возникало, ошибку исправил, но пока не опубликовал решение в виду низкой популярности статьи. Проблема решается в шаблоне удалением строки и добавлением новой или копированием такой, где проблема не возникала.

    Reply
  9. KRIHA

    Спасибо вам большое, гражданин, за проделанную работу. Считаю ваше решение красивым, до сих пор в восторге от волшебства:

    Функция СоединитьШаблоны(Теги,ПараметрыЗаполнения)

    Всех благ!

    P.S.

    Использовал в https://infostart.ru/public/937082/

    Reply
  10. allexx

    Все хорошо работает. Одна только проблема — это ориентация Ландшафт. На последующих страницах можно вставлять разрывы, а вот как первую страницу заставить быть ландшафтной? Для себя выкрутился с помощью MSWord.Application.Selection.PageSetup.Orientation = 1, но это не совсем правильно. Остальные в портрете все делают что ли?

    Reply
  11. artms

    (10) Тестировал в ландшафте, проблем не возникло. Однако возможно рассматривается случай совмещения различных ориентации в одном документе, такой случай не тестировал.

    Reply
  12. allexx

    Может быть от версий офиса зависит, но я вроде на разных пробовал и результат один и тот же. Вот такая же проблема описывается https://answers.microsoft.com/en-us/msoffice/forum/all/selectioninsertfile-does-not-preserve-pagesetup/a393e023-6b92-4a91-a58d-3bd55c29c441

    Когда дальше стал тестировать, то выяснилось, что и размеры полей берутся по умолчанию, а не из подготовленного документа.

    Reply
  13. artms

    (12) Нужны примеры, для исправления, но рейтинг разработки низкий нет смысла поддерживать.

    Reply
  14. user864530

    Вопрос? Как обработка работает с нижним и верхним колонтитулом и вставка разрывы страниц для изменения ориентации страницы в документе.

    Reply
  15. andrewbc

    Дорогой мой человек, спасибо огромное!

    Сам начал было этим заниматься, но времени катастрофически в обрез.

    Спас.

    11 шаблонов за 1 сутки (с учетом адаптации кода под свою задачу — порядка 80-ти рассчитываемых параметров, включая несколько таблиц).

    Все отрабатывает шикарно.

    Замечания / предложения:

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

    2. Нужно было вывести картинку — я не стал заморачиваться, в папке «wordmedia» просто перезаписывал файл «image1.jpeg». Понимаю, что нужно через таблицу связей обрабатывать, но времени нет. Может, есть решение?

    А в остальном — все ок.

    Могу прислать разумную рублевую благодарность после сдачи своего проекта (стукни в личку).

    Reply
  16. artms

    (15) Спасибо за отзыв.

    Извини за недоработки. Пока обновлений нет из-за низкой популярности модуля, возможно будут позднее.

    Reply
  17. as7bs

    Добрый день. Подскажите, а можно ли реализовать в цикле вывод повторяющегося текста на отдельных листах? Нужно после основного текста вывести несколько приложений, в каждом текст(Заголовок) и таблица. Количество приложений заранее неизвестно.

    Reply
  18. as7bs

    (17) Реализовал, програмно обрабатывая шаблон файла после его загрузки в обработку, точнее ТегиСШаблонами полученные из шаблона файла. В цикле вставляю данные находящиеся между определенными метками в шаблоне(НачалоПовтораПриложений и ОкончаниеПовтораПриложений). Если есть более правильный или красивый вариант буду рад если расскажете.

    Reply
  19. artms

    (18) Добрый день. Такая задача не стояла. Делал бы аналогично. Разница могла быть только в реализации.

    Reply
  20. artms

    (5) Ошибка исправлена

    Reply
  21. Euroset1

    Автору однозначно плюс за, по сути, мануал а ля «быстрый старт» по работе с Open XML. За этим способом, будущее, кстати. Не знаю, почему он так редок в использовании. Например, задача по рассылке сервером по расписанию кадровых документов сотрудникам решается только этим способом.

    Reply
  22. artms

    (21) На самом деле речь шла не о мануале, а о модуле, который решает проблемы: разбиение строки шаблона в xml, и заполнение таблиц Word.

    Reply
  23. Euroset1

    (22) если отказаться от спецсимволов и вводить в шаблон теги монотонно без копипоста и за один раз типа ДатаПолученияДоговора или НомерСтроки, то этот текст будет лежать в одном теге гарантированно. Мне норм. Не вижу основания использовать скобки для тегов теперь, обладая этими экспериментальными данными =)

    Reply
  24. artms

    (23) 1. Увы это не так, зависит от настроек авто форматирования, выделения ошибок и ещё чего то, что ещё не выяснил.

    2. И опять же упустили момент вывода таблиц (могу добавлять строки из массива).

    3. По Т.З. на создание модуля нужно было дать возможность через БСП изменять макет клиенту, увы ваш вариант на это не способен. Клиент легко разделит вам шаблон. Пробовал указанный способ, но увы Word и другие редакторы, обожают разбивать целые слова на части, что делает сложным настройку даже разработчику (потратил на эту схему прямой замены много часов, поскольку сложно найти обрубок шаблона в xml, а затем убрать лишние теги, которых часто не оправдано много).

    Reply
  25. o.nikolaev

    Подскажите, а если надо выполнять подстановку в колонтитулах, то аналогичным образом надо вначале разбирать xml в таблицу значений, а потом собирать?

    Reply
  26. artms

    (25) Такая задача не стояла, но посмотрел что необходимо сделать. Сейчас собирается разбирается только файл document.xml, а колонтитулы находятся в header1.xml,header2.xml,header3.xml. Предлагаю проверять наличие и менять аналогично document.xml файлы header1.xml,header2.xml,header3.xml.

    По договоренности, могу сделать указанную доработку.

    Reply
  27. o.nikolaev

    (26) Спасибо. В конечном счете, все-таки стал использовать функции БСП. Если кому интересно, то в БСП 3.0 куча ошибок, которая нормально с форматом Open Office работать не позволяла. Но. С помощью расширения часть функций была взята из 3.01. После этого работа с шаблонами подстановки вида {v8 НомерДокумента} и пр. заработала нормально. Даже с заголовками, даже с фигурами и текстом в фигурах.

    Но, при выводе многострочного блока — например табличной части — подглючивает, выдает сообщение типа «Документ неожиданно поврежден. Восстановить его средствами Microsoft Word?» при выборе «Да», вроде все открывается нормально. Причем в БСП 3.1 эта ошибка происходит прямо на демо-базе БСП. Но тем не менее, документ, в конечном счете, формируется без видимых повреждений.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *