Pull to refresh

PHPStamp — честная генерация DOCX документов из шаблона

Website development *PHP *XSLT *
Sandbox
Это еще одна попытка реализовать стабильный, полноценный шаблонизатор офисных документов, основанных на XML, пользуясь стандартными для PHP средствами DOMDocument и XSL.

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

Найти библиотеку можно здесь: github.com/shadz3rg/PHPStamp

Принцип работы


Несмотря на все прелести визуальных редакторов, на выходе всегда получается далеко не самый оптимальный код документа, и MS Word — не исключение. Вот так просто добавленные в документ Тэги заменить на XSL логику не получится, даже не смотря на относительно простую структуру DOCX документа.

Основную проблему представляют разбитые на отрывки (они же «run», представлены нодами <w:r/>) параграфы, содержимое Тэгов разбивается на несколько нод и в таком виде их обработать не получится.

Для начала попробуем упростить разметку.

1. Удалим свойства языка у отрывков. Что логично, при замене Тэга может быть вставлено значение на любом языке, к тому же знаки пунктуации не имеют принадлежности к языку, что доставляет дополнительные проблемы при поиске Тэгов.
2. Удалим пустые ноды свойств отрывков, чисто технический момент.
3. Объединим рядом стоящие отрывки, используя deepEqual сравнение (которое в DOMDocument до сих пор «Not implemented») нод свойств.

Если все прошло по плану, библиотеке остается лишь добавить подходящую XSL логику. Предусмотрена возможность — некоторая расширяемость с опциями. Так, например, на данный момент реализованы табличные строки и списки.
Полученный шаблон кэшируется в файловой системе, поэтому последующие его вызовы будут максимально быстрыми (настолько, насколько способен XSL).

Предусмотрена поддержка разных форматов. В планах было добавить поддержку формата ODT, но ввиду отличной поддержки DOCX в LibreOffice особой необходимости нет. Возможно, хорошей идеей будет генерация XLSX, должно получится довольно быстро в сравнении с PHPExcel.

Зависимости и установка


Установить библиотеку вы можете через Composer, на сервере понадобится PHP 5.3 с модулями Zip, DOM и XSL.

{
    "minimum-stability": "dev",
    "require": {
        "shadz3rg/php-stamp": "dev-master"
    }
}


Пример использования


Для примера используем шаблон:



<?php
	require 'vendor/autoload.php';

	use PHPStamp\Templator;
	use PHPStamp\Document\WordDocument;

	$cachePath = 'path/to/writable/directory/';
	$templator = new Templator($cachePath); // опционально можно задать свой формат скобочек
	// Для того чтобы каждый раз шаблон генерировался заново: 
	// $templator->debug = true;

	$documentPath = 'path/to/document.docx';
	$document = new WordDocument($documentPath);

	$values = array(
		'library' => 'PHPStamp 0.1',
		'simpleValue' => 'I am simple value',
		'nested' => array(
			'firstValue' => 'First child value',
			'secondValue' => 'Second child value'
		),
		'header' => 'test of a table row',
		'students' => array(
			array('id' => 1, 'name' => 'Student 1', 'mark' => '10'),
			array('id' => 2, 'name' => 'Student 2', 'mark' => '4'),
			array('id' => 3, 'name' => 'Student 3', 'mark' => '7')
		),
		'maxMark' => 10,
		'todo' => array(
			'TODO 1',
			'TODO 2',
			'TODO 3'
		)
	);
	$result = $templator->render($document, $values);
	$result->download();


На выходе получаем документ с нужными нам данными:

Tags:
Hubs:
Total votes 20: ↑17 and ↓3 +14
Views 24K
Comments Comments 15