
Что делать, если нужно создавать много 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 идёт прямо из коробки:
// Создаём объект для работы с сервисом и передаём свой логин и пароль
$livDoc = new Zend_Service_LiveDocx_MailMerge(array(
'username' => 'yourusername',
'password' => 'yourpassword'
));
// Передаём значения для наших mergeFields в Word шаблоне
$livDoc->assign('orderNum','Номер заказа');
$livDoc->assign('orderDay',date('d', 'Дата заказа'));
// Задаём путь к файлу шаблона и передаём его объекту
$documentPath = 'contract_bid_for_customer.doc';
$livDoc->setLocalTemplate($documentPath);
// заполняем документ с помощью сервиса
$livDoc->createDocument();
$doc = $livDoc->retrieveDocument('doc');
// отдаём готовый документ для скачки
header("Cache-Control: public");
header("Content-Description: File Transfer");
$fileName = "Документ.doc";
header("Content-Disposition: attachment; filename=$fileName");
header("Content-Type: application/msword");
header("Content-Transfer-Encoding: binary");
echo $doc;
die;
Если же вы предпочитаете plain php, то голодными тоже не останетесь.
Для работы понадобится включенный модуль soap, в большинстве случаев он включен по умолчанию, но проверьте как обстоит дело у вас:
phpinfo();
Раздел SOAP
Вы должны увидеть Soap client enabled и Soap server enabled.
// Выключаем WSDL кэширование
ini_set ('soap.wsdl_cache_enabled', 0);
// Выставляем временную зону
date_default_timezone_set('Europe/Moscow');
// Создаём экземпляр объекта Soap и передаём ему свои учетные данные
$soap = new SoapClient('https://api.livedocx.com/1.2/mailmerge.asmx?WSDL');
$soap->LogIn(
array(
'username' => 'yourusername',
'password' => 'yourpassword'
)
);
// Путь к файлу шаблона
$data = file_get_contents('contract_bid_for_customer.doc');
// Установка расширения файла .doc и параметров кодирования
$soap->SetLocalTemplate(
array(
'template' => base64_encode($data),
'format' => 'doc'
)
);
// Задаём значения переменным
$fieldValues = array (
'orderNum' => 'Номер заказа',
'orderDay' => 'Дата заказа'
);
// Эта хитрая функция преобразует массив c переменными в то что понимает SOAP
function assocArrayToArrayOfArrayOfString ($assoc)
{
$arrayKeys = array_keys($assoc);
$arrayValues = array_values($assoc);
return array ($arrayKeys, $arrayValues);
}
// Передаём переменные в наш LiveDocx объект
$soap->SetFieldValues(
array (
'fieldValues' => assocArrayToArrayOfArrayOfString($fieldValues)
)
);
// Формируем документ
$soap->CreateDocument();
$result = $soap->RetrieveDocument(
array(
'format' => 'doc'
)
);
$doc = base64_decode($result->RetrieveDocumentResult);
// Разрываем сессию с SOAP
$soap->LogOut();
// Отдаём вордовский файл
header("Cache-Control: public");
header("Content-Description: File Transfer");
$fileName = "Документ.doc";
header("Content-Disposition: attachment; filename=$fileName");
header("Content-Type: application/msword");
header("Content-Transfer-Encoding: binary");
echo $doc;
die;
3) На выходе мы имеем вот такой файл

LiveDocx поддерживает и другие форматы: DOCX, RTF and PDF.
Подробнее вы можете почитать здесь:
livedocx.com
phplivedocx.org/articles/getting-started-with-phplivedocx
blog.zendguru.com/2010/02/13/creating-word-processing-document-using-zend_service_livedocx