Word Template Engine:
PHP based template processor and converter

Word Template Engine is a PHP based template processor and converter that allows to create documents from DOCX templates (download an example.docx) and convert them trough LibreOffice into the following formats: PDF, HTML, XHTML, mail-adapted HTML. This light-weight library will help you in creating invoices, contracts, waylists and other documents. Use variables inside your document and substitute them with values on the server side, replace and delete images, manage document sections (pages), make a document copy or a section copy inside the document, add rows to your tables. Output the documents to a user browser, attach the WORD or PDF files to emails, or create a HTML mail content from your template.

Changelog

  • 1.0.1 : 2021-07-19 : Improved performance of processing large documents. More than 1000 variable replacements take a few seconds. Reduced memory and CPU usage. Speed increased by 6-8 times.
  • 1.0.2 : 2021-07-21 : 1) Fixed directory separators caused issues on Windows platform. 2) Generation of unique temporary subdirectory to resolve potential multiuser conflicts.
  • 1.0.3 : 2023-04-28 : Fixed broken titles/headers in Safari browser when outputting a file.

Installation and usage

#!/bin/bash

# Download an unpack the latest version
wget 'https://github.com/philip-sorokin/word-template-engine/archive/refs/tags/v1.0.3.tar.gz'
tar xzf 'v1.0.3.tar.gz'

# Install LibreOffice for conversion DOCX to PDF, HTML and other formats
apt update && apt install libreoffice
<?php

// Require the library
require_once 'word-template-engine-1.0.3/WordTemplateEngine.php';

// Require the WordTemplateEngineExamples class with examples if you need
require_once 'word-template-engine-1.0.3/examples/examples.php';

Public methods

__construct ( string $template [, string|null $tmp_path, callable $errorHandler ] )
  • @param $template The full path to the .docx template.
  • @param $tmp_path Optional. The full path to the temporary directory where the working files are created. By default, the site root or a current directory is used.
  • @param $errorHandler Optional. A function to replace the default error handler. The callback takes two string parameters: the error description and a unique error status.

The constructor.

$doc = '/var/www/site.com/template.docx';

/* Example 1. */
$template = new WordTemplateEngine($doc);

/* Example 2. Define temporary directory */
$template = new WordTemplateEngine($doc, '/var/www/site.com/tmp');

/* Example 3. Attach custom error handler */
$template = new WordTemplateEngine($doc, null, 'myErrorHandler');
setValue ( string $varName, string|null $replacement ): void
  • @param $varName The variable name.
  • @param $replacement The replacement.

Method to replace a template variable with the $replacement value. A template variable must have the following format: ${name}, where 'name' is passed as the $varName argument.

/* Example. */

$varName = 'company_name';
$replacement = 'AddonDev';

$template->setValue($varName, $replacement);
cloneRow ( string $varName, int $cnt ): void
  • @param $varName The anchor variable.
  • @param $cnt How many rows you need.

Method to clone a table row with an anchor. An integer counter followed by '#' is appended to the names of all variables inside the row including the anchor.

E.g. you have an anchor variable: ${key} and other variables inside the row: ${customer}, ${order_id}, they are replaced with: ${key#1}, ${customer#1}, ${order_id#1}; ${key#2}, ${customer#2}, ${order_id#2} etc.

/* Example. Make 3 table rows from one that contains a variable ${product_number}. */

$varName = 'product_number';
$template->cloneRow($varName, 3);

/* Then replace the variables */

$template->setValue('product_number#1', 1);
$template->setValue('product_number#2', 2);
$template->setValue('product_number#3', 3);
alternativeSyntax ( bool $bool ): void
  • @param $bool Whether to use alternative variable syntax.

Call this method before replacements to use alternative variable syntax ~(name) instead of default ${name}. You can also switch back to default syntax. Use the alternative syntax to replace the variables inside hyperlinks and other targets.

/* Example. */
$template->alternativeSyntax(true);

// Do some replacements of variables like ~(var_name)
$template->setValue('company_website', 'https://addondev.com');

// Switch back to the basic syntax if you need
$template->alternativeSyntax(false);

// Replace variables like ${var_name}
$template->setValue('company_website', 'https://addondev.com');
replaceImage ( int $imageID, string $replacement ): void
  • @param $imageID An image id according to the Word enumerator.
  • @param $replacement The path of a new image.

Replace an image in the document with another image.

/* Example. Replace a placeholder image with a signature. */
$template->replaceImage(2, '/var/www/site.com/uploads/signature.png');
deleteImage ( int $imageID ): void
  • @param $imageID An image id according to the Word enumerator.

Completely removes images with a certain id, it deletes both the elements and the file.

/* Example. Delete signature. */
$template->deleteImage(2);
save ( string $destination [, string $format = 'docx' ] ): string
  • @param $destination The destination path. Can be full or relative, e.g. '/var/www/newdoc.docx', 'newdoc.pdf'. The root of a relative path is the temporary directory.
  • @param $format Optional. The document format: 'docx' (default), 'pdf', 'html', 'xhtml', 'mail' (HTML adapted to email).
  • @return string The full path to the created document.

Creates a document from the processed template.

/* Example 1. Create a DOCX file. */
$template->save('/var/www/site.com/newdoc.docx');

/* Example 2. Create a PDF file. */
$template->save('/var/www/site.com/newdoc.pdf', 'pdf');

/* Example 3. Create a HTML file. */
$template->save('/var/www/site.com/newdoc.html', 'html');

/* Example 4. Create an xHTML file. */
$template->save('/var/www/site.com/newdoc.html', 'xhtml');

/* Example 5. Use a relative path and create HTML adapted to email. */
$fileName = $template->save('newdoc.html', 'mail');
output ( [ string $format = 'docx', string|null $fileName, bool $isAttachment ] ): void
  • @param $format Optional. The document format: 'docx' (default), 'pdf', 'html', 'xhtml', 'mail' (HTML adapted to email).
  • @param $fileName Optional. Defines the filename of downloaded file.
  • @param $isAttachment Optional. Forces docx and pdf documents to the certain disposition type: inline or attachment. By default, docx documents are attachments, PDFs are inlines.

Creates a document from the processed template and outputs it to the client browser.

/* Example 1. Output a DOCX file as an attachment to download. */
$template->output('docx', 'Invoice 777');

/* Example 2. Output a PDF to display in a user browser. */
$template->output('pdf', 'Invoice 777');

/* Example 3. Output a PDF file as an attachment to download. */
$template->output('pdf', 'Invoice 777', true);
useSection ( int $idx ): void
  • @param $idx The section index.

Remove all the sections in the template except the section with an index passed as the argument. This method truncates the document to the certain section.

Note! It must be called before any replacements, because the document paragraphs and rows are cached for better performance.
Note! If you use page breaks inside a section, the next page must begin with a paragraph. Otherwise, the document can be broken.

/* Example. */

// First we need to remove all unused images to reduce the file size.
$template->deleteImage(3);
$template->deleteImage(4);

// Shorten a document to the first section.
$template->useSection(1);

$template->setValue('company_name', 'AddonDev');
$template->save('/var/www/site.com/newdoc.docx');
repeat ( [ int $cnt = 1, int $idx ] ): void
  • @param $cnt Optional. How many copies are created. Default 1.
  • @param $idx Optional. Repeat only one section.

Copy the document one or several times. If the second argument is passed, it creates only a section copy and appends it to the end of the document.
Note! It must be called before or after any replacements, because the document paragraphs and rows are cached for better performance. The call order depends on your document.

/* Example 1. Copy the whole document one time. */
$template->repeat();

/* Example 2. Copy the whole document two times. */
$template->repeat(2);

/* Example 3. Use the first section only and make a copy. */
$template->useSection(1);
$template->setValue('company_name', 'AddonDev');
$template->repeat(1);
dropMetaData ( ): void

Drop all core document properties and two extended properties: Company, Manager. After calling this method you have to redefine the document creation time, the title and the document creator; otherwise, the document will be broken.

/* Example. */
$template->dropMetaData();
setTitle ( string $title ): void
  • @param $title

Set core document metadata - title. It also displays as the page title in documents opened in a browser: PDF, HTML, XHTML.

/* Example. */
$template->setTitle('Invoice 777');
setAuthor ( string $author ): void
  • @param $author

Set core document metadata - creator. Defines the document creator, clears lastModifiedBy properties.

/* Example. */
$template->setAuthor('Jane Doe');
setTime ( [ string|null $time ] ): void
  • @param $time Optional. DateTime in ISO 8601 format. If undefined or null, current DateTime is used.

Set core document metadata - created. Defines the document creation DateTime, clears modified and lastPrinted DateTime properties.

/* Example 1. Set current time. */
$template->setTime();

/* Example 2. Set another time. */
$template->setTime('2021-05-12T13:47:01+03:00');
setCompany ( string $companyName ): void
  • @param $companyName

Set extended document metadata - Company.

/* Example. */
$template->setCompany('AddonDev');
setManager ( string $manager ): void
  • @param $manager

Set extended document metadata - Manager.

/* Example. */
$template->setManager('John Doe');
setSubject ( string $subject ): void
  • @param $subject

Set core document metadata - subject.

/* Example. */
$template->setSubject('Invoice for Elisha Barton');
setKeywords ( string $keywords ): void
  • @param $keywords

Set core document metadata - keywords.

/* Example. */
$template->setKeywords('Documents, payment, order');
setDescription ( string $description ): void
  • @param $description

Set core document metadata - description.

/* Example. */
$template->setDescription('Document description');
setCategory ( string $category ): void
  • @param $category

Set core document metadata - category.

/* Example. */
$template->setCategory('Category');
setStatus ( string $contentStatus ): void
  • @param $contentStatus

Set core document metadata - content status.

/* Example. */
$template->setStatus('New');
embedStyleSheet ( string $stylesheet ): void
  • @param $stylesheet

Method to embed a custom stylesheet into the HEAD section of a document that is to be converted into HTML or XHTML format.

/* Example. */
$template->embedStyleSheet('.Table4_E10 {font-weight: bold}');
$template->output('mail');
embedScript ( string $script ): void
  • @param $script

Method to embed a custom script into the HEAD section of a document that is to be converted into HTML or XHTML format.

/* Example. */
$template->embedScript("console.log('Hello world!')");
$template->output('html');
addStyleSheet ( string $url ): void
  • @param $url

Method to append an external stylesheet into the HEAD section of a document that is to be converted into HTML or XHTML format.

/* Example. */
$template->addStyleSheet('https://site.com/style.css');
$template->output('html');
addScript ( string $url ): void
  • @param $url

Method to append an external script into the HEAD section of a document that is to be converted into HTML or XHTML format.

/* Example. */
$template->addScript('https://site.com/script.js');
$template->output('html');
sendOutputHeaders ( bool $bool ): void
  • @param $bool

Call this method with the FALSE parameter before outputting the document if you want to send your own HTTP headers.

/* Example. Set your headers before outputting a document. */
$template->sendOutputHeaders(false);
header('Content-type: application/pdf');
$template->output('pdf');
setOutputFilter ( string $filter ): void
  • @param $filter LibreOffice filter parameter, e.g. 'HTML:EmbedImages'.

If you need to overwrite a default conversion filter, define it before saving / outputting the document.

/* Example. */
$template->setOutputFilter('HTML:EmbedImages');
$template->output('html');
setLocale ( string $locale ): void
  • @param $locale UNIX locale.

The locale that is set before conversion the .docx template into other formats. Default is 'C.UTF-8'.

/* Example. */
$template->setLocale('en_US.utf8');
$template->output('html');

Additional information