Заполнение шаблона word данными php

Обновлено: 04.07.2024

Мы живем в мире, где PHP разработчикам приходится время от времени взаимодействовать с операционной системой Windows. WMI (Windows Management Interface, Интерфейс управления Windows) - один из таких примеров - взаимодействие с Microsoft Office.

В данной статье мы рассмотрим простую интеграцию между Word и PHP: генерацию документа Microsoft Word на основе полей ввода в HTML-форме с помощью PHP (и его расширения Interop).

Подготовительные шаги

Первым делом убедимся, что у нас настроено базовое окружение WAMP. Так как Interop присутствует только в Windows, то нам необходимо, чтобы наш сервер Apache и инсталляция PHP были развернуты на Windows машине. В этом качестве я использую EasyPHP 14.1, который крайне прост в установке и настройке.

Следующим делом необходимо установить Microsoft Office. Версия не очень важна. Я использую Microsoft Office 2013 Pro, но любая версия Office старше 2007 должна подойти.

Также необходимо убедиться, что у нас установлены библиотеки для разработки приложения Interop (PIA, Primary Interop Assemblies, Основные Сборки Interop). Узнать это можно открыв Проводник Windows, и перейдя в директорию <Windows Directory>\assembly , и там мы должны увидеть набор установленных сборок:


Здесь можно увидеть элемент Microsoft.Office.Interop.Word (подчеркнут на скриншоте). Это будет та сборка, которую мы будем использовать в нашей демонстрации. Пожалуйста, обратите особое внимание на поля “Assembly name (Имя сборки)”, “Version (Версия)” и “Public key token (Токен публичного ключа)”. Их мы скоро будем использовать в нашем PHP скрипте.

Если список сборок не включает весь пакет Microsoft.Office.Interop , то нам нужно либо переустановить Office, добавив PIA, или вручную загрузить пакет с сайта Microsoft и установить его. Для более детальных инструкций обратитесь к этой странице на MSDN.

Замечание: к загрузке и установке доступен только дистрибутив PIA Microsoft Office 2010. Версия сборок в этом пакете 14.0.0, а 15 версия поставляется только с Office 2013.

И, наконец, необходимо включить расширение php_com_dotnet.dll в php.ini и перезапустить сервер.

Теперь можно перейти к программированию.

HTML форма

Так как основная часть данного примера ложится на серверную сторону, мы создадим простую страничку с формой, которая будет выглядеть следующим образом:


Серверная часть

Файл-обработчик на серверной стороне - это основная цель нашего разговора. Для начала я приведу полный код этого файла, а потом объясню его шаг за шагом.

После того, как мы записали в переменную $inputs значения, полученные из формы, а также создали пустой элемент с ключом printdate (зачем мы это сделали - обсудим позже), мы переходим к четырем очень важным строкам:

Манипулятор COM в PHP требует создания экземпляра класса в рамках “сборки”. В нашем случае мы работаем с Word. Если взглянуть на первый скриншот, то можно записать полную сигнатуру сборки для Word:

  • “Name”, “Version”, “Public Key Token” - все это берется из информации, которую можно просмотреть в “c:\Windows\assembly“ .
  • “Culture” всегда neutrual

Класс, на который мы хотим ссылаться, всегда называется “имя.сборки”+ “ .ApplicationClass “.

Установив два этих параметра мы сможем получить объект для работы с Word.

Этот объект может оставаться в фоне, или мы можем перевести его в рабочий режим установкой атрибута visible в true .

Следующим шагом открываем документ, требующий обработки, и записываем экземпляр “документа” в переменную $d .

Чтобы создать в документе содержимое, основанное на данных с формы, можно пойти несколькими путями.

Самым неправильным было бы жестко прописать содержимое документа в PHP, а потом вывести его в документ Word. Я настоятельно рекомендую этого не делать по следующим причинам:

  1. Вы теряете гибкость. Любые изменения в выходном файле потребуют изменения кода PHP.
  2. Это нарушает разделение управления и вида
  3. Применение стилей к содержимому документа (выравнивание, шрифты, стили, и т.д.) в скрипте сильно увеличит количество строк кода. Программное изменение стилей чересчур громоздко.

Другим вариантом будет использование поиска и замены. У PHP есть хорошие встроенные средства для этого. Мы можем создать документ Word, в котором разместим метки со специальными разделителями, которые в последствии будут заменены. Например, мы можем создать документ, который будет содержать следующий фрагмент:

а с помощью PHP мы легко можем заменить его на содержимое поля “Имя”, полученное с формы.

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

Я рекомендую третий способ, и он основывается на более глубоком знании Word. В качестве заполнителей мы будем использовать поля, а с помощью PHP кода будем непосредственно обновлять значения в полях соответствующими значениями.

Этот подход гибкий, быстрый, и согласуется с лучшими практиками работы с Word. С его помощью также можно избежать полнотекстового поиска в документе, что хорошо сказывается на производительности. Замечу, что у этого решения также есть недостатки.

Word с самого начала не поддерживал именные индексы для полей. Даже если мы и указали имена для создаваемых полей - нам все равно необходимо пользоваться числовыми идентификаторами этих полей. Это также объясняет, зачем нам нужно использовать отдельную функцию ( setupfields ) для того, чтобы задать соответствие индекса поля и имени поля из формы.

В этом демонстрационном уроке мы будем использовать документ с 5 полями MERGEFIELD . Шаблонный документ разместим там же, где и наш скрипт-обработчик.

Прошу заметить, что поле printdate не имеет соответствующего поля на форме. Вот зачем мы добавили пустой элемент printdate в массив $inputs . Без этого скрипт все же будет запускаться и работать, но PHP будет выдавать предупреждение, что индекс printdate отсутствует в массиве $inputs .

После замены полей новыми значениями мы отпечатаем документ с помощью

Метод PrintOut принимает несколько необязательных параметров, и мы используем самую простую его форму. Так будет отпечатана одна копия документа на принтере по умолчанию, который присоединен к Windows-машине.

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

Необходимо подождать некоторое время, прежде чем завершить работу с приложением Word, так нужно время на то чтобы поставить в очередь задание на печать. Без delay(3) метод $w->Quit выполняется незамедлительно, и задание не ставится в очередь.

Наконец, мы вызываем $w->Quit(false) , что закрывает приложение Word, которое было вызвано нашим скриптом. Единственным параметром, передаваемым в метод, является указание сохранить файл перед выходом. Мы сделали правки в документе, но мы не хотим их сохранять, так как нам нужен чистый шаблон для последующей работы.



Улучшение скорости обработки и немного подробнее о PIA

PHP - слабо типизированный язык. Объект COM типа Object . Во время написания скрипта у нас нет возможности получить описание объекта, будь оно приложением Word, документом или полем. Мы не знаем, какие свойства есть у этого объекта, или какие он поддерживает методы.

С указанием типа переменной, можно наслаждаться более понятным кодом и автодополнением, и скорость разработки существенно повышается.

Другой способ повысить скорость разработки на PHP - вызывать макрос в Word. Мы проводим ту же последовательность действий, а после сохраняем ее как макрос. Макрос написан на Visual Basic, который также просто перевести в PHP.

И, что самое важное - документация по Office PIA от Microsoft, особенно документация по пространствам имен каждого приложения Office является самым детальным справочным материалом. Наиболее используемые три приложения:

Заключение

В этой статье мы показали, как заполнить данными документ Word с помощью библиотек PHP COM и возможностями взаимодействия Microsoft Office.

Windows и Office широко используются в повседневной жизни. Знать силу Office/Window и PHP будет полезно каждому PHP и Windows разработчику.

С помощью расширения PHP COM вам открывается дверь к использованию этой комбинации.

5 последних уроков рубрики "PHP"

Фильтрация данных с помощью zend-filter

Когда речь идёт о безопасности веб-сайта, то фраза "фильтруйте всё, экранируйте всё" всегда будет актуальна. Сегодня поговорим о фильтрации данных.

Контекстное экранирование с помощью zend-escaper

Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

Подключение Zend модулей к Expressive

Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.

Совет: отправка информации в Google Analytics через API

Подборка PHP песочниц

Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

image

Что делать, если нужно создавать много Word файлов одинакового вида, но разного содержания? Например заполнять бланки, квитанции.

Есть 3 варианта:
1) использовать одну из библиотек для работы с Word документами
2) сохранить документ в формате docx, открыть архиватором и внутри мы увидим "\word\document.xml" — чистый xml, с которым можно работать через str_replace (спасибо Enuriru за подсказку)
3) использовать сторонний сервис, который сделает за меня большую часть работы

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

Второй варинт хорош и прост, когда мы работаем с word документами в формате .docx, но к сожалению он не поддерживает формат .doc

В процессе проработки третьего варианта, наткнулся на интересное решение LiveDocx

Преимущества:
— файл шаблона можно создать привычным способом через Word
— представление документа в форматах doc, docx, rtf, pdf
— не нужно заморачиваться с представлением Word документа через html или XML
— простота подключения
— надежность — сервис существует давно и под него даже есть готовая библиотека от Zend
Недостатки:
— в бесплатной версии ограничение на 250 генерируемых документов в сутки
— шаблон нельзя менять (например нельзя сгенерировать таблицу с кол-вом строк, равным количеству элементов в базе)

Вот так выглядел присланный заказчиком файл.


1) Для начала нужно разметить шаблон. Открываем файл и размечаем нужные поля специальными вордовскими переменными mergeField, вот как это делается в Word 2007:
— Вставка => Экспресс блоки => Поле
Появляется окно.


Выбираем тип поля: MergeField => В имени поле пишем имя переменной => Жмем ОК

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


Сохраняем документ, кладём в директорию нашего приложения.

2) Поработаем с кодом

Регистрируемся на сайте LiveDocx, получаем логин и пароль.

Если вы счастливый/несчастливый обладатель Zend Framework, то всё довольно просто, поддержка LiveDocx идёт прямо из коробки:

Если же вы предпочитаете plain php, то голодными тоже не останетесь.

Для работы понадобится включенный модуль soap, в большинстве случаев он включен по умолчанию, но проверьте как обстоит дело у вас:
phpinfo();
Раздел SOAP
Вы должны увидеть Soap client enabled и Soap server enabled.

image

Что делать, если нужно создавать много Word файлов одинакового вида, но разного содержания? Например заполнять бланки, квитанции.

Есть 3 варианта:
1) использовать одну из библиотек для работы с Word документами
2) сохранить документ в формате docx, открыть архиватором и внутри мы увидим "\word\document.xml" — чистый xml, с которым можно работать через str_replace (спасибо Enuriru за подсказку)
3) использовать сторонний сервис, который сделает за меня большую часть работы

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

Второй варинт хорош и прост, когда мы работаем с word документами в формате .docx, но к сожалению он не поддерживает формат .doc

В процессе проработки третьего варианта, наткнулся на интересное решение LiveDocx

Преимущества:
— файл шаблона можно создать привычным способом через Word
— представление документа в форматах doc, docx, rtf, pdf
— не нужно заморачиваться с представлением Word документа через html или XML
— простота подключения
— надежность — сервис существует давно и под него даже есть готовая библиотека от Zend
Недостатки:
— в бесплатной версии ограничение на 250 генерируемых документов в сутки
— шаблон нельзя менять (например нельзя сгенерировать таблицу с кол-вом строк, равным количеству элементов в базе)

Вот так выглядел присланный заказчиком файл.


1) Для начала нужно разметить шаблон. Открываем файл и размечаем нужные поля специальными вордовскими переменными mergeField, вот как это делается в Word 2007:
— Вставка => Экспресс блоки => Поле
Появляется окно.


Выбираем тип поля: MergeField => В имени поле пишем имя переменной => Жмем ОК

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


Сохраняем документ, кладём в директорию нашего приложения.

2) Поработаем с кодом

Регистрируемся на сайте LiveDocx, получаем логин и пароль.

Если вы счастливый/несчастливый обладатель Zend Framework, то всё довольно просто, поддержка LiveDocx идёт прямо из коробки:

Если же вы предпочитаете plain php, то голодными тоже не останетесь.

Для работы понадобится включенный модуль soap, в большинстве случаев он включен по умолчанию, но проверьте как обстоит дело у вас:
phpinfo();
Раздел SOAP
Вы должны увидеть Soap client enabled и Soap server enabled.

Работа с phpWord. Заполнение шаблона договора docx (генерация word из php)
Начну с постановки задачи. А она довольно простая — работая над сайтом клиента по прокату автомобилей возникла необходимость несколько автоматизировать рутинные операции. В частности требовалось при оформлении аренды на сайте автоматически заполнять в договоре некоторые поля. Вот этим и займемся.

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

Итак, мы скачали phpWord, распаковали архив и залили на веб-сервер. В моем случае речь идет о версии 0.6.2 Beta.

Теперь нам необходимо подготовить сам шаблон. Для этого запускаем MS Word или даже Wordpad и набираем текст договора. Для примера я набросал тестовый договор, который выглядит вот так (кликабельно):

Давайте определимся, что в этом шаблоне мы поручим заполнять php скрипту. К примеру, пусть это будет номер договора с датой, а также ФИО продавца и номер паспорта. Теперь давайте превратим наш договор в шаблон, с которым будем работать дальше.

Итак, для заполнения мы определили данные, давайте подберем для них имена. Это может быть транслитерация или английское написание, вы можете выбрать по вкусу.

Данные Переменная
Номер договора d_num
Дата договора d_date
Фамилия last_name
Имя name
Отчество surname
Замечательно. Теперь делаем следующее — на тех местах, где у нас данные, мы их удаляем и вставляем имена переменных в виде

Т. е. там, где у нас номер договора 123 мы пишем $ и т. д. для всех переменных. В итоге получится вот такой шаблон договора:

Отнеситесь к этому внимательно — ошибок допускать нельзя. Сохраняем полученный шаблон под именем Template.docx (можно назвать по своему).

Внимание! При сохранении документа в Word 2010 поставьте чекбокс «Поддерживать совместимость с предыдущими версиями Word» иначе работать не будет.

Вот теперь наш шаблон готов, теперь давайте научим php заполнять его.

Создаем php файл (к примеру, index.php) со следующим содержимым:

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

На этом все. Надеюсь, что хоть немного помог читателю разобраться с заполнением docx файлов на php. Для изучения все материалы можно скачать в виде архива.

Читайте также: