Электронные формы в Microsoft Word 2007: извлечение и вставка данных
Продолжение заметки о работе с формами в Word 2007
В предыдущей статье Электронные формы в Microsoft Word 2007: простые формы "парой кликов" я быстро пробежался по процессу создания шаблона электронной формы в MS Word 2007, что называется "без единой строчки кода". Однако в реальных рабочих сценариях, таких "форм в себе", для которых нужно еще приложить усилия по извлечению данных, толку не очень много. С другой стороны, все эти предварительные действия по настройке формы может выполнить обычный бизнес-пользователь, а обработка в любом случае - на совести программиста.
В наших изысканиях мы будем исходить из того, что:
Ну что ж, поехали...
Для начала, несколько общих теоретических моментов, которые мы будем использовать в дальнейшем. Для тех, кто знаком с WordprocessingML, это все известно, а остальным, надеюсь, пригодится для понимания того, что мы будем делать дальше (все это, и многое другое можно найти в книге Воутер Ван Вугт "Open XML: кратко и доступно". Где найти книгу и другие ресурсы по OpenXML, смотрите здесь Ресурсы по Open XML). Итак:
Итак, задача сводится к тому, чтобы:
Начнем со связывания. К сожалению, мне не известны удобные (да и не удобные) способы связать элементы управления с узлами источника данных непосредственно из самого Word, однако нам вполне хватить возможностей бесплатной утилиты Word 2007 Content Control Toolkit, которую можно найти на https://www.codeplex.com/dbe.
Запустив эту программу, и выбрав в меню File\Open наш документ, мы увидим примерно следующую картину:
В левой части перечислены все элементы управления, найденные в документе, а в правой - источники данных в том же документе (у нас пока нет ни одного).
Теперь, чтобы добавить новый источник, мы сначала щелкнем по ссылке "Create a new Custom XML Part", а затем переключимся на закладку "Edit View". На этой закладке можно отредактировать xml c данными вручную, или загрузить ее из внешнего файла. Мы воспользуемся вторым вариантом, после чего вернемся на закладку "Bind View". Теперь можно произвести связывание узлов данных и полей представления. Для этого достаточно схватить мышкой нужный узел в правой части и перетащить его на нужный же контроль в левой. То, что примерно должно получиться в результате, можно увидеть на следующем рисунке:
Теперь нужно только сохранить файл и наша форма со связанным источником готова к использованию.
Остался последний, но, очень важный штрих - как извлечь данные из файла формы? Вот несколько возможных способов:
1. Помня о том, что OpenXML-файл это, по сути своей, простой zip-архив, мы можем распаковать файл данных из этого архива. Принимая во внимание, что Content Control Toolkit складывает файлы Custom XML в одну и ту же папку, их совсем не сложно найти (в нашем случае это файл \customXml\item1.xml):
Несмотря на всю привлекательную простоту данного метода, назвать его удачным нельзя из-за привязки к конкретным именам и путям файлов, которые могут меняться от одной формы к другой (да и просто разные разработчики могут внести несогласованные изменения).
2. Второй способ основывается на использовании Open XML Format SDK. Нам подойдет и первая, и вторая (пока еще CTP) версии. В качестве иллюстрации приведу простейший пример, извлекающий ФИО заявителя и дату подписания:
3. Наконец, могу предложить некоторый промежуточный вариант - использовать PowerTools for Open XML - набор командлетов для оболочки PowerShell 1.0. Если вы имеете опыт использования этой, пока еще довольно новой командной среды, то указанный инструмент Вам очень может пригодится, причем не только для извлечения XML-данных, но и для манипулирования, коментариями, стилями, подписями и даже для преобразования в HTML. Пример использования командлета для извлечения XML-данных и результат его работы:
PS> (Get-OpenXmlCustomXmlData -Path 'Шаблон заявления на отпуск.docx' -Part item1.xml).ToString()
<Zajav>
<FIO>Романов М.Л</FIO>
<Period>
<God_nach>2009</God_nach>
<God_kon>2010</God_kon>
</Period>
<Otpusk>
<Data_nach>2009-03-02</Data_nach>
<Data_kon>2009-03-13</Data_kon>
<Data_vih>2009-03-16T00:00:00</Data_vih>
</Otpusk>
<Data_podp>2009-02-25</Data_podp>
</Zajav>
Как видите, ничего особо сложного работа с формами в Word 2007 не имеет.
Кроме того, хочу заметить, что механизм SDT работает в обе стороны, т.е. можно заранее подготовить форму, а затем менять в ней компонент с данными!!! Вот простейший пример, демонстрирующий это:
Наконец, вместо итога, хочется обсудить какие варианты применения и какие ограничения есть у этого механизма.
Пожалуй, это все. Если остались вопросы и неясности, задавайте их в комментариях, постараюсь ответить.
Комментарии 6
И все же возможно ли использовать данные из БД в Word через Directum? И как Вы смотрите на такую возможность как "слияние" в Word, тогда будет возможна выгрузка данных из динамически изменяющейся таблицы в Word, а также возможность за раз сделать ,больше одно заявления, например сразу на группу сотрудников, если это конечно необходимо.
И все же возможно ли использовать данные из БД в Word через Directum?
Хм. Я не уверен, что правильно понял вопрос... Вы хотите заполнять шаблоны документов на основе данных из базы Directum, или наоборот - выгружать содержимое документа (точнее отдельных полей) в базу? Вообще-то в обоих случаях, ответ будет - конечно можно , но выбор механизмов будет несколько разным.
Если Вас интересует заполнение документов из данных базы, то можно использовать на выбор один из двух механизмов. Тот что я описал в статье абсолютно не зависит от используемой системы, т.е. вы можете использовать эти наработки и для Directum и вне его. Второй механизм уже специфичен для Directum - это вставка полей через модуль интеграции с MS Office.
Использовать можно оба механизма. Тот, что описан в статье более универсален, т.к. позволяет собирать данные из множества источников (хоть из разных баз), однако он требует дополнительного программирования, а кроме того, без специальных доработок он не будет поддерживать автоматическое обновление данных - т.е. вы один раз подготовили документ и он остается таким навсегда (ну или до следующей явной смены данных в нем). Второй позволяет в качестве источника использовать только карточку самого документа и все связанные с ней справочник, зато он не требует дополнительных доработок и автоматически "подхватывает" все изменения из базы.
Если же Вы хотите выгружать данные из полей документа в базу, то в текущей версии Directum это можно сделать только методом, описанным в статье (есть еще вариант на основе Custom XML - он как раз позволяет выгружать данные в том числе и из таблиц переменного размера, но к сожалению, я так и не смог добиться от него стабильной работы - почему-то все время теряется привязка XML-элементов и содержимого документа. Если смогу это победить, то напишу и об этом методе. Правда мне он нравится гораздо меньше, т.к. требует на много более сложной подготовки.).
В принципе, продуктах MS Office есть также возможность напрямую работать с внешними источниками данных (т.е. забирать данные напрямую из базы или с web-сервиса), но пока я не могу сказать ничего определенного по поводу этого механизма - надо поизучать его подробнее. Надеюсь, в ближайшее время я этим займусь, а результатами обязательно поделюсь здесь в блоге.
И как Вы смотрите на такую возможность как "слияние" в Word
Если мы говорим об одном "слиянии" (то, которе, делается методом Document.Merge() и в качестве одного из источников используется текстовый файл), то по опыту работы с прошлыми версиями Word, не очень хорошо - на сколько мне помнится, у этого механизма переодически всплывала проблема, что он не мог верно определить кодировку текстового файла с данными, а указать явно - не было возможности.
Или Вы о каком-то другом механизме?
также возможность за раз сделать ,больше одно заявления, например сразу на группу сотрудников, если это конечно необходимо.
Ну, подготовить сразу группу документов, а не отдельный документ Вы можете и приведенным в статье способом. Все что нужно, это: подготовить данные для каждого документа, разможить шаблон, "залить" свою реплику данных в шаблон.
Спасибо за ответ, мне были интересны оба варианта. Тема, на мой взгляд, очень интересная и актуальная!
Пожалуйста, Алена. Очень рад, если смог в чем-то помочь.
На случай, если у Вас еще остались вопросы, то задавайте их или здесь, в этом блоге, или пишите непосредственно мне на Romanov_ML (коммерческое эт.) directum.ru
Со времени публикации данной статьи прошло уже более четырех лет, и, конечно же, некоторые моменты стали не актуальными. Например, мое утверждение
утратило силу с появлением Office 2013. Теперь SDT (или content controls) работают и для списочных/табличных структур.
Кроме того, у самой статьи было несколько существенных изъянов:
Посему, я собрался с силами и обновил данное руководство. Получился следующий набор статей:
Кстати, используемый сквозной пример с генерацией отчета о совещании (meeting notes) - взят с реального проекта (правда шаблон я делал сам - на исходном были логотипы заказчика).
Тем же, кто не хочет читать "много русских букв", могу привести еще несколько ссылок:
Если будут вопросы, их лучше задавать в комментариях к приведенным статьям.