Наверх

Электронные формы в Microsoft Word 2007: извлечение и вставка данных

Время чтения: 8 минут
6
Электронные формы в Microsoft Word 2007: извлечение и вставка данных

Продолжение заметки о работе с формами в Word 2007

В предыдущей статье Электронные формы в Microsoft Word 2007: простые формы "парой кликов" я быстро пробежался по процессу создания шаблона электронной формы в MS Word 2007, что называется "без единой строчки кода". Однако в реальных рабочих сценариях, таких "форм в себе", для которых нужно еще приложить усилия по извлечению данных, толку не очень много. С другой стороны, все эти предварительные действия по настройке формы может выполнить обычный бизнес-пользователь, а обработка в любом случае - на совести программиста.

В наших изысканиях мы будем исходить из того, что:

  • документ с формой у нас уже есть
  • для обработки нам достаточно извлечь данные формы в каком-нибудь структурированном формате, так, чтобы каждое поле было введено отдельно (в нашем случае это будет XML).
  • Ну что ж, поехали...

    Для начала, несколько общих теоретических моментов, которые мы будем использовать в дальнейшем. Для тех, кто знаком с WordprocessingML, это все известно, а остальным, надеюсь, пригодится для понимания того, что мы будем делать дальше (все это, и многое другое можно найти в книге Воутер Ван Вугт "Open XML: кратко и доступно". Где найти книгу и другие ресурсы по OpenXML, смотрите здесь Ресурсы по Open XML). Итак: 

  • Файлы формата WordprocessingML (как, впрочем, и других форматов семейства OpenXML), представляют собой файл формата deflate (zip-файл), который содержит можество других файлов, представляющих как контент, так и метаданные документа. Большая часть из этих файлов - имеют формат xml. Т.е., не представляет никакой проблемы открыть файл OpenXML, и прочитать (если знать, конечно, что и как читать), нужный файл содержимого.
  • Тело документа как раз представляет собой файл формата XML, а для представления элементов ввода, которые мы использовали в нашем примере, используются специальные теги, названные "структурными тегами документа" (structured document tag, SDT)
  • Наиболее интересной, для нас, особенностью SDT для нас является то, что они позволяют использовать источники данных, которые располагаются в том же архиве, что и само тело документа, но абсолютно в другом файле. Причем, по своей структуре файл данных представляет собой обычный xml, произвольной структуры. Привязывание же SDT к узлам файла-источника осуществляется с помощью XPath-запросов, которые прописываются в атрибутах SDT. В этот самый источник и будут сохраняться все введенные в форму данные.
  • Итак, задача сводится к тому, чтобы:

  • Привязать элементы управления (точнее SDT) к узлам xml-файла, в который мы будем собирать данные формы.
  • После сохранения документа с формой, открыть файл docx, из которого и достать нужный нам файл данных.
  • Начнем со связывания. К сожалению, мне не известны удобные (да и не удобные) способы связать элементы управления с узлами источника данных непосредственно из самого Word, однако нам вполне хватить возможностей бесплатной утилиты Word 2007 Content Control Toolkit, которую можно найти на https://www.codeplex.com/dbe.

    Запустив эту программу, и выбрав в меню File\Open наш документ, мы увидим примерно следующую картину:

    Word 2007 Content Control Toolkit

    В левой части перечислены все элементы управления, найденные в документе, а в правой - источники данных в том же документе (у нас пока нет ни одного).

    Теперь, чтобы добавить новый источник, мы сначала щелкнем по ссылке "Create a new Custom XML Part", а затем переключимся на закладку "Edit View". На этой закладке можно отредактировать xml c данными вручную, или загрузить ее из внешнего файла. Мы воспользуемся вторым вариантом, после чего вернемся на закладку "Bind View". Теперь можно произвести связывание узлов данных и полей представления. Для этого достаточно схватить мышкой нужный узел в правой части и перетащить его на нужный же контроль в левой. То, что примерно должно получиться в результате, можно увидеть на следующем рисунке:

    Настроенный шаблон формы в Word 2007 Content Control Toolkit

    Теперь нужно только сохранить файл и наша форма со связанным источником готова к использованию.

    Остался последний, но, очень важный штрих - как извлечь данные из файла формы? Вот несколько возможных способов:

    1. Помня о том, что OpenXML-файл это, по сути своей, простой zip-архив, мы можем распаковать файл данных из этого архива. Принимая во внимание, что Content Control Toolkit складывает файлы Custom XML в одну и ту же папку, их совсем не сложно найти (в нашем случае это файл \customXml\item1.xml):

    Содержимое Open Xml файла

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

    2. Второй способ основывается на использовании Open XML Format SDK. Нам подойдет и первая, и вторая (пока еще CTP) версии. В качестве иллюстрации приведу простейший пример, извлекающий ФИО заявителя и дату подписания:

    Пример кода на Open XML SDK (извлечение XML-данных)

    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 работает в обе стороны, т.е. можно заранее подготовить форму, а затем менять в ней компонент с данными!!! Вот простейший пример, демонстрирующий это:

    Пример кода на Open XML SDK (запись в форму XML-данных)

    Наконец, вместо итога, хочется обсудить какие варианты применения и какие ограничения есть у этого механизма.

  • В первую очередь, этот механизм хорошо использовать для всевозможных сценариев работы с шаблонами документов. С одной стороны, это простой механизм для разработки строгих по форме шаблонов для часто используемых документов, который доступен любому пользователю, не знакомому с программированием, но имеющему хотябы базовые навыки работы с Word. С другой стороны, при подключении разработчика - это отличный способ создания как автоматически заполняемых документов, анкет, отчетов и т.д.
  • Все описанные возможности, кончно же, доступны только в Office 2007, однако, если Вы планируете использовать подобный механизм только для автоматического заполнения шаблонов документов, без их ручной правки, т.е. документы будут в основном открывться только на чтение, то можно остаться на более ранних версиях Office, но предварительно установить Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint 2007 File Formats (в этом случае даже не нужно устанавливать полный вариант Office на компьютеры - достотчно обойтись просмотрщиками, которые распространяются бесплатно, например Word Viewer)
  • Электронные формы Word, скорее всего, не удастся использовать в сценариях, связанных, с заполнением данных внешними респондентами. Причина, я думаю, понятно - нет гарантий, что у них установлен Office да еще и нужной версии.
  • У механизма SDT есть одно неприятное ограничение - он не поддерживает работу со списочными структурами и таблицами. Точнее, использовать эти элементы можно и в таблицах, и списках, но либо последние должны иметь фиксированное число элементов, либо придется писать довольно непростые расширения, позволяющие автоматически вставлять во вновь добавляемые строки таблиц или списков SDT-элементы. Ни о какой простоте, ясное дело, речи уже не идет.
  • Пожалуй, это все. Если остались вопросы и неясности, задавайте их в комментариях, постараюсь ответить.

    Чтобы прочитать эту статью до конца,
    или зарегистрируйтесь

    Комментарии 6


    Электронные формы Word, скорее всего, не удастся использовать в сценариях, связанных, с заполнением данных внешними респондентами.

    И все же возможно ли использовать данные из БД в 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


    Михаил, скажите пожалуйста, можно ли как-то сделать форму для изображения?

    Со времени публикации данной статьи прошло уже более четырех лет, и, конечно же, некоторые моменты стали не актуальными. Например, мое утверждение

    У механизма SDT есть одно неприятное ограничение - он не поддерживает работу со списочными структурами и таблицами.

    утратило силу с появлением Office 2013. Теперь SDT (или content controls) работают и для списочных/табличных структур.

    Кроме того, у самой статьи было несколько существенных изъянов:

    • отсутствовали доступные примеры кода (из-за ограничений движка сайта пришлось вставлять картинки, что по меньшей мере не удобно)
    • для генерации Custom XML использовалось прямое манипулирование XML (что выглядит не слишком технологичным решением).

    Посему, я собрался с силами и обновил данное руководство. Получился следующий набор статей:

    Кстати, используемый сквозной пример с генерацией отчета о совещании (meeting notes) - взят с реального проекта (правда шаблон я делал сам - на исходном были логотипы заказчика).

    Тем же, кто не хочет читать "много русских букв", могу привести еще несколько ссылок:

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

    Чтобы прокомментировать, или зарегистрируйтесь