phpdocx v4.0 Tutorial

phpdocx v4.0 Tutorial

phpdocx installation

phpdocx is very easy to install. Usually it is just enough to unzip the package somewhere in your server and it is (almost) ready to go.

Obviously, as you could have guessed by its name, phpdocx requires PHP 5 to be installed in your server. Moreover the following PHP modules should be activated:

  • ZipArchive
  • XSLT
  • Tidy (not strictly necessary but highly recommended)

For your convenience we have included a PHP script in the package (directly located in the app root folder), check.php, that will check if any of the requirements are missing.

Of course, DO NOT FORGET to include the license key:

  • Download the license key from the "MYPHPDOCX section" of this website.
  • Copy it (plain, with no other word or character) in the code option of the config/phpdocxconfig.ini file.
  • Include the subdomain.domain (PRO version), the domain (CORPORATE version) or the IP (ENTERPRISE version) in the value option of the config/phpdocxconfig.ini file.

    WARNINGS:

  • The folders where your scripts are running and/or the folder where you want to store the resulting Word documents have to have writing permissions rights.
  • If possible, use always UTF-8 compatible editors to code your scripts or modify any script in the phpdocx library. The final Word documents have to be UTF-8 encoded and nonUTF-8 characters may break the final document.
  • All the content in a .docx file is stored in XML files so you should escape certain protected characters like the ampersand symbol (write & instead of &).
  • Make sure that your web server has activated the .docx MIME type in case you want your users to download directly the resulting Word documents to the browser (if not IE will believe that your .docx is a .zip file).

There is no a priori restrictions about the OS and server software as long as it may run PHP 5. That includes, of course, basically all LINUX and UNIX distributions as well as Windows and Mac OS. You may use Apache as web server or lighttp, nginX, IIS, etcetera.

phpdocx may use external data for your reports and documents coming from virtually any data source and it is the responsability of the user to prepare it so phpdocx can represent it adequately. phpdocx DOES NOT require MySQL or any other specific Database software for its deployment and correct functioning.

You DO NOT need any copy of Microsoft Office Word to generate your Word documents.

phpdocx PRO does also not need any kind of outbound connection to work so it does not depend directly of a working Internet connection or any kind of additional third party software.

Creating a Word document from scratch

Let´s start with the standard "hello world" document.

The required script reads as follows:

                            require_once 'path_to_phpdocx/classes/CreateDocx.inc';
                            $docx = new CreateDocx();
                            $docx->addText('Hello world!');
                            $docx->createDocx('../word_documents/hello_world');
                            

The first line: require_once 'path_to_phpdocx/classes/CreateDocx.inc' is a call to the main class in phpdocx, and path_to_phpdocx has to be sustituted by the actual path to the library relative to the current script.

You can see here the final result and download the corresponding Word document :

OK, this has been simple enough but not very rewarding. Let’s go one step further and introduce a little more of formatting:

                            require_once 'path_to_phpdocx/classes/CreateDocx.inc'; 

                            $docx = new CreateDocx();
                            $text = array();
                            $text[] =
                                array(
                                'text' => 'I am going to write'
                                );
                            $text[] =
                                array(
                                'text' => ' Hello World!',
                                'b' => 'on'
                                );
                             
                            $text[] =
                                array(
                                'text' => ' using bold characters.'
                                );
                            $docx->addText($text);
                            $docx->createDocx('../word_documents/hello_world_2');
                            

Well now this start to look a little nicer although we have still some work ahead:

At this point one may wonder if there is a simple way to "wrap" our document in a more beautiful frame including, for example, headers and footers and even a first page.

There are quite a few ways to do so:

  • Importing the headers and footers from an existing Word document.
  • Creating your own headers and footers via the addheader and addFooter methods.
  • Using a different base template with all the required formatting.
  • Using a custom template.

Like we have not yet talked about templates (base or custom) and the addHeader and addFooter methods required of certain concepts not yet introduced, we will restrict ourselves,by the time being (please, be patient), to the first of the available options.

We have already prepared a standard Word document (.docx, of course) with a nice header and footer that we would like to insert in our current document. Its relative path to this script is, for example, resources/niceHeaderAndFooter.docx.

So let’s proceed:

                            require_once 'path_to_phpdocx/classes/CreateDocx.inc';

                            $docx = new CreateDocx();
                             
                            //Importing header and footer from external .docx file
                            $docx ->importHeadersAndFooters('../word_documents/templateHeaderAndFooter.docx');
                            $text = array();
                            $text[] =
                                        array(
                                        'text' => 'I am going to write'
                                        );
                            $text[] =
                                        array(
                                        'text' => ' Hello World!',
                                        'b' => 'on'
                                        );
                             
                            $text[] =
                                        array(
                                        'text' => ' using bold characters.'
                                        );
                            $docx->addText($text);
                             
                            $docx->createDocx('../word_documents/hello_world_headersAndFooters');

                            

This is definitely starting to look much nicer:

If you prefer only to import the header you may have used:

                            $docx ->importHeadersAndFooters('../word_documents/templateHeaderAndFooter.docx', 'header');
                            

and equivalently

                            $docx ->importHeadersAndFooters('../word_documents/templateHeaderAndFooter.docx', 'footer');
                            

if you only wish to import the footer.

The footers and headers can include photos, tables, standard text, lists, links, shapes, etcetera. The import procedure also preserves the display properties of the headers and footers (first, even and odd pages).

Now to continue we are going to populate our word document with a series of standard objects:

  • Lists
  • Tables
  • Images
  • Charts

There are many other possibilities but we prefer to refer to the documentation for a complete set of examples in order not to clutter this tutorial with unneeded details.

Let us first include a simple unordered nested list after our "hello world" paragraph. In order to do so we should use the addList method:

                            //Call to PHPDocX
                            require_once 'path_to_phpdocx/classes/CreateDocx.inc';
                             
                            $docx = new CreateDocx();
                             
                            //Importing header and footer from external .docx file
                            $docx ->importHeadersAndFooters('../word_documents/templateHeaderAndFooter.docx');
                             
                            $text = array();
                            $text[] =
                                        array(
                                        'text' => 'I am going to write'
                                        );
                            $text[] =
                                        array(
                                        'text' => ' Hello World!',
                                        'b' => 'on'
                                        );
                            $text[] =
                                        array(
                                        'text' => ' using bold characters.'
                                        );
                            //We insert the the text into the Word document
                            $docx->addText($text);
                             
                            //Let us now to add a nested unordered list
                            $myList = array('item 1',
                                        'item 2',
                                        array('subitem 2_1',
                                            'subitem 2_2'),
                                        'item 3',
                                        array('subitem 3_1',
                                            'subitem 3_2',
                                            array('sub_subitem 3_2_1',
                                                'sub_subitem 3_2_1')),
                                        'item 4');
                             
                            $docx->addList($myList, 1);
                             
                            $docx->createDocx('../word_documents/hello_world_list');

                            

What we get looks like this:

If you had choosen the second parameter to be 2 instead of 1 you would have got a standard numbered list. Now you may wonder:

  • How can I get more sophisticated list styles?
  • How can I insert something more than plain text as an item for a list?

The answer to the first question is pretty simple: you may run the parseStyles() method (see example) in a separate script and generate a Word document with all the info about the list, paragraph and table styles that are available by default. We will see later that if you choose to use your own "base template" you may incorporate all the styles you wish. You may also use the createListStyle method to generate your own list styles in execution time.

The answer to the second question is a little more elaborate but still simple enough: you should create a Word fragment to achieve more sophisticated formatting:

The corresponding code reads:

                            //Call to PHPDocX
                            require_once 'path_to_phpdocx/classes/CreateDocx.inc';
                             
                            $docx = new CreateDocx();
                             
                            //Importing header and footer from external .docx file
                            $docx ->importHeadersAndFooters('../word_documents/templateHeaderAndFooter.docx');
                             
                            $text = array();
                                $text[] =
                                array(
                                'text' => 'I am going to write'
                                );
                            $text[] =
                                array(
                                'text' => ' Hello World!',
                                'b' => 'on'
                                );
                            $text[] =
                                array(
                                'text' => ' using bold characters.'
                                );
                            //We insert the the text into the Word document
                            $docx->addText($text);
                            //we prepare some formatted text for insertion in the list
                            $myItem = new WordFragment($docx);
                            $newText = array(
                                array(
                                    'text' => 'This is the text associated with the first item',
                                    'b' => 'on',
                                    'color' => 'b70000'
                                ),
                                array(
                                    'text' => ' now without bold'
                                ),
                                array(
                                    'text' => ' and blue',
                                    'color' => '0000b7'
                                )
                            );                            
                            $myItem->addText($newText);
                             
                            //Let us now include the Word fragment in a sample list
                            $myList = array($myItem,
                                'item 2',
                                array('subitem 2_1',
                                    'subitem 2_2'),
                                'item 3',
                                array('subitem 3_1',
                                    'subitem 3_2',
                                    array('sub_subitem 3_2_1',
                                        'sub_subitem 3_2_1')),
                                'item 4');
                             
                            $docx->addList($myList, array('val' => 1));
                             
                            $docx->createDocx('../word_documents/hello_world_list2');
                            

And you get:

This way to insert elements one within the other may be extended to other cases in a simple way:

  • Create a new Word Fragment (WordFragment class).
  • Include all the required content into the Word fragment with standard phpdocx methods.
  • Insert the resulting Word fragment:
    • within a table,
    • within a list (only inline content),
    • anywhere in the Word document with the insertWordFragmentBefore/After methods,
    • or in the headers and footers via the addHeader and addFooter methods.

Now we will try to insert a simple table so our Word document gets richer in contents.

                            //Call to PHPDocX
                            require_once 'path_to_phpdocx/classes/CreateDocx.inc';
                             
                            $docx = new CreateDocx();
                             
                            //Importing header and footer from external .docx file
                            $docx ->importHeadersAndFooters('../word_documents/templateHeaderAndFooter.docx');
                             
                            $text = array();
                            $text[] =
                                array(
                                'text' => 'I am going to write'
                                );
                            $text[] =
                                array(
                                'text' => ' Hello World!',
                                'b' => 'on'
                                );
                            $text[] =
                                array(
                                'text' => ' using bold characters.'
                                );
                            //We insert the the text into the Word document
                            $docx->addText($text);
                             
                            //we prepare some formatted text for insertion in the list
                            $myItem = new WordFragment($docx);
                            $newText = array(
                                array(
                                    'text' => 'This is the text associated with the first item',
                                    'b' => 'on',
                                    'color' => 'b70000'
                                ),
                                array(
                                    'text' => ' now without bold'
                                ),
                                array(
                                    'text' => ' and blue',
                                    'color' => '0000b7'
                                )
                            );                            
                            $myItem->addText($newText);
                             
                            //Let us now include the Word fragment in a sample list
                            $myList = array($myItem,
                                'item 2',
                                array('subitem 2_1',
                                    'subitem 2_2'),
                                'item 3',
                                array('subitem 3_1',
                                    'subitem 3_2',
                                    array('sub_subitem 3_2_1',
                                        'sub_subitem 3_2_1')),
                                'item 4');
                             
                            $docx->addList($myList, array('val' => 1));
                             
                            $tableData = array(
                                array(
                                'cell_1_1',
                                'cell_1_2',
                                'cell_1_3',
                                'cell_1_4'
                                ),
                                array(
                                'cell_2_1',
                                'cell_2_2',
                                'cell_2_3',
                                'cell_2_4'
                                ),
                                array(
                                'cell_3_1',
                                'cell_3_2',
                                'cell_3_3',
                                'cell_3_4'
                                )
                            );
                             
                            $tableProperties = array(
                                'border' => 'single',
                                'borderWidth' => 10//in eights of a point
                                );
                             
                            $docx->addTable($tableData, $tableProperties);
                             
                            $docx->createDocx('../word_documents/example_table');
                            

And you get:

This is certainly not the most beautiful table you have ever seen but we can solve that problem pretty easily by having a look at the available table styles in the document that we have generated before with the parseStyles() method.

For example we may use the "MediumGrid3-accent5PHPDOCX" accent table style (blame Word for the funky names):

                            /Call to PHPDocX
                            require_once 'path_to_phpdocx/classes/CreateDocx.inc';
                             
                            $docx = new CreateDocx();
                             
                            //Importing header and footer from external .docx file
                            $docx ->importHeadersAndFooters('../word_documents/templateHeaderAndFooter.docx');
                            $text = array();
                            $text[] =
                                array(
                                'text' => 'I am going to write'
                                );
                            $text[] =
                                array(
                                'text' => ' Hello World!',
                                'b' => 'on'
                                );
                             
                            $text[] =
                                array(
                                'text' => ' using bold characters.'
                                );
                            $docx->addText($text);
                             
                            //we prepare some formatted text for insertion in the list
                            $myItem = new WordFragment($docx);
                            $newText = array(
                                array(
                                    'text' => 'This is the text associated with the first item',
                                    'b' => 'on',
                                    'color' => 'b70000'
                                ),
                                array(
                                    'text' => ' now without bold'
                                ),
                                array(
                                    'text' => ' and blue',
                                    'color' => '0000b7'
                                )
                            );                            
                            $myItem->addText($newText);
                             
                            //Let us now include the Word fragment in a sample list
                            $myList = array($myItem,
                                'item 2',
                                array('subitem 2_1',
                                    'subitem 2_2'),
                                'item 3',
                                array('subitem 3_1',
                                    'subitem 3_2',
                                    array('sub_subitem 3_2_1',
                                        'sub_subitem 3_2_1'))
                                'item 4');
                             
                            $docx->addList($myList, array('val' => 1));
                             
                            $tableData = array(
                                array(
                                    'cell_1_1',
                                    'cell_1_2',
                                    'cell_1_3',
                                    'cell_1_4'
                                ),
                                array(
                                    'cell_2_1',
                                    'cell_2_2',
                                    'cell_2_3',
                                    'cell_2_4'
                                ),
                                array(
                                    'cell_3_1',
                                    'cell_3_2',
                                    'cell_3_3',
                                    'cell_3_4'
                                )
                            );
                             
                            $tableProperties = array('tableStyle' => 'MediumGrid3-accent5PHPDOCX');
                             
                            $docx->addTable($tableData, $tableProperties);
                             
                            $docx->createDocx('../word_documents/example_table_style');
                            

This certainly looks much nicer and pretty simple to implement:

Although this example clearly does not exhaust all the table formatting capabilities of phpdocx we leave the nitty-gritty details to the addTable method API documentation.

But one always want something more and eventually one may need to insert tables with "rowspans" and "colspans". What can we do about that?

The simplest way (although not the only one) to do that it is to parse an HTML table and associate a Word style to it.

Like our script is starting to get a little lengthly let us concentrate only in the relevant part of it. Let’s define a $myTable variable as follows:

                            $myHTML = '

We include a table with rowspans and colspans using the embedHTML method.

header 1 header 2 header 3 header 4
cell_1_1 cell_1_3 cell_1_4
cell_2_3 cell_2_4
cell_3_1 cell_3_2 cell_3_3 cell_3_4
'; $docx->embedHTML($myHTML, array('WordStyles' => array('<table>' => 'MediumGrid3-accent5PHPDOCX'));

This should render a table like this:

By the way, if you do not like the styles that come bundled with phpdocx (basically the quick styles that come with the standard Word 2007 distribution) you may import custom styles from other Word document using the importStyles() method or by using your own base template.

    WARNINGS:

  • If you use px instead of pt as your CSS units take into account a 0.75 relative scale factor

As you can foresee the embedHTML method may have multiple uses but for the sake of brevity we will ignore them by the time being and we will move forward to investigate how to include images and charts.

To insert an image is as simple as this:

                            $paramsImg = array(
                                'src' => '../img/image.png',//path to the image that we would like to insert
                                'scaling' => 90,//scaling factor, 100 corresponds to no scaling
                                'spacingTop' => 10,//top padding
                                'spacingBottom' => 10,//bottom padding
                                'spacingLeft' => 10,//left padding
                                'spacingRight' => 10,//right padding
                                'textWrap' => 1//corresponding to square format
                            );
                            $docx->addImage($paramsImg);
                            

This should render an image like this:

If you need to include more than one photo with a precise layout you may combine the addTable method with createWordMLFragment to generate the desired ouput. For example:

                            $text = 'We are going to locate three pictures in a row just below this text. And we are going to use Trebuchet MS font to change a little bit :-)';

                            $paramsText = array(
                                'font' => 'Trebuchet MS'
                            );

                            $docx->addText($text, $paramsText);

                            $images = array('aeg.png','aeg.png','aeg.png');
                            $wordImages = array();

                            foreach ($images as $image) {
                                $paramsImg = array(
                                    'src' => $image,//The image to be inserted
                                    'dpi' => 120,//We force the images to a 100 dpi resolution
                                    'scaling' => 90,//We scale them at 90% size
                                    'spacingTop' => 10,//top padding
                                    'spacingBottom' => 10,//bottom padding
                                    'spacingLeft' => 10,//left padding
                                    'spacingRight' => 10,//right padding
                                    'textWrap' => 1,//corresponding to square format
                                    'rawWordML' => true//The result will be stored in a WordML fragment
                                );
                                $imageFragment = new WordFragment($docx);
                                $imageFragment->addImage($paramsImg);
                                array_push($wordImages, $imageFragment);

                            }
                            $paramsTable = array(
                                'tableStyle' => 'NormalTablePHPDOCX',
                            );
                            $values = array($wordImages);
                            $docx->addTable($values, $paramsTable);
                            

This should now render the three inserted image like this:

To finish with the most basic functionality of phpdocx we are going now to insert a chart.

phpdocx virtually allows to include any chart that can be included through the standard Word interface:

  • 2D and 3D pie charts,
  • 2D and 3D bar graphs,
  • 2D and 3D col bars,
  • 2D and 3D area charts,
  • 2D and 3D line charts,
  • 2D and 3D surface charts,
  • 2D and 3D bubble charts,
  • radar charts,
  • donought charts,
  • scatter charts.

As an example we will include a radar type chart:

                            $legends = array(
                                'legend' => array('sequence 1', 'sequence 2', 'sequence 3'),
                                'Category 1' => array(9.3, 2.4, 2),
                                'Category 2' => array(8.5, 4.4, 1),
                                'Category 3' => array(6.5, 1.8, 0.5),
                                'Category 4' => array(8.5, 3, 1),
                                'Category 5' => array(6, 5, 2.6)
                            );
                            $args = array(
                                'data' => $legends,
                                'type' => 'radar',
                                'style' => 'radar',
                                'title' => 'Radar chart',
                                'sizeX' => 15, 
                                'sizeY' => 15,
                                'legendpos' => 't',
                                'border' => 1,
                                'vgrid' => 1
                            );
                            $docx->addChart($args);
                            

And you get:

In order to see all the available options you should visit the Full reference Documentation, nevertheless to illustrate the flexibility of phpdocx you may easily create a bar chart with the associated data data table just by setting the ’showtable’ option to 1 and setting the type to "colBar":

                                $legends = array(
                                    'legend' => array('sequence 1', 'sequence 2', 'sequence 3'),
                                    'Category 1' => array(9.3, 2.4, 2),
                                    'Category 2' => array(8.5, 4.4, 1),
                                    'Category 3' => array(6.5, 1.8, 0.5),
                                    'Category 4' => array(8.5, 3, 1),
                                    'Category 5' => array(6, 5, 2.6)
                                );
                                $args = array(
                                    'data' => $legends,
                                    'type' => 'colBar',
                                    'title' => 'Chart with table',
                                    'sizeX' => 15, 'sizeY' => 15,
                                    'legendpos' => 't',
                                    'border' => 1,
                                    'vgrid' => 1,
                                    'showtable' => 1
                                );
                                $docx->addChart($args);
                            

So this time we will obtain:

Using your own base template and setting up general config options

We have already commented that phpdocx users may use their own "base templates" in order to generate their custom documents or reports.

The procedure is quite simple. One only has to make a call to the desired template whenever a new docx is created:

                                require_once 'path_to_phpdocx/classes/CreateDocx.inc';
                                $docx = new CreateDocx('../word_documents/numberedHeadings.docx');//You should include the path to your base template
                                $docx->addText('This is a numbered Heading', array('pStyle' => 'Heading1PHPDOCX'));
                                $docx->addText('Hello world again!');
                                $docx->addText('This is a  Subheading', array('pStyle' => 'Heading2PHPDOCX'));
                                $docx->addText('No more Hello world, please!');
                                $docx->createDocx('../word_documents/new_baseTemplate');

                            

As you may see from the result:

You may get customized headers and footers as well as many other configuration options in just one shot.

For example you may also include a "front page" as structured content that will be preserved by phpdocx:

                                require_once 'path_to_phpdocx/classes/CreateDocx.inc';
                                $docx = new CreateDocx('../word_documents/frontPageTemplate.docx');//You should include the path to your base template

                                $docx->addText('This is a numbered Heading', array('pStyle' => 'Heading1PHPDOCX'));
                                $docx->addText('Hello world again!');
                                $docx->addText('This is a  Subheading', array('pStyle' => 'Heading2PHPDOCX'));
                                $docx->addText('No more Hello world, please!');
                                $docx->createDocx('../word_documents/front_page');;

                            

So we get:

Nevertheles to use the default template may show convenient because it has been prepared to have available all the standard Word style options.

If you use your own template make sure, by using the parseStyles() method that you have enough styles at your disposal.

    WARNINGS:

  • The contents of your baseTemplate will be ignored (only headers,footers and "front page", if it has been inserted as stuctured content, will survive in the final document). If you really want to work with an existing template for your document content you should use the createDocxFromTemplate class on which we will ellaborate on next section.

Before going ahead with templates we would like to comment on the fact that since phpdocx v2.5 there is a configuration file: classes/PHPDOCXConfig.inc where the following parameters can be globally set (although they can be override by the corresponding methods for each particular document):

  • Base Template
  • Default language
  • Default paper size (A4, A3, letter or legal)
How to prepare a template for phpdocx

It is quite often that rather than writing a full document from scratch we just need to do certain modifications on an existing document:

  • Include a client´s name
  • Redraw a chart depending on new dynamical data
  • Populate a table with certain dynamical data coming from a database, i.e. items in an invoice
  • Change certain images
  • Etcetera

For all those cases phpdocx allows to use an existing Word document and do all the required substitutions just by inserting the adequate placeholders variables.

For example, if we have a letter where the only "variable" part of it is a name we could:

  • Replace the name by the variable: $NAME$
  • Extract from a data source the actual name to be used in the resulting document and perform the substitution via the replaceVariableByText() method.

Let us carry out this process in greater detail.

First write, using your favourite Word editor, a very simple Word document like this:

Dear $NAME$, I would like to say something interesting but unfortunately I do not have much to say. Best regards, phpdocx Guru

    WARNINGS:

  • Do not forget to save your document with the .docx extension and call it, for example, myTestTemplate.docx.

For your convenience you may download the document here.

The required phpdocx script needed to carry away the replacement is as simple as this:

                                require_once 'path_to_phpdocx/classes/CreateDocx.inc';
                                $docx = new CreateDocxFromTemplate('../word_documents/myTestTemplate.docx');
                                $docx->replaceVariableByText(array('NAME' => 'John Smith'));
                                $docx->createDocx('../word_documents/test_template');
                                ?>
                            

And you will get as a result:

If you wish you may change the symbol used to enclosed the placeholder variable to, for example ‘#’ using the setTemplateSymbol(’#') method.

    WARNINGS:

  • Do not forget to save your document with the .docx extension and call it, for example, myTestTemplate.docx.

Since phpdocx v4.0 we have great flexibity because we may substitute a variable by HTML, a Word fragment, an external file, etcetera. This greatly simplifies the process to include new content into a Word document (although since 4.0 one may use any of the standard methods described before to insert content anywhere in the template without the need of placeholder variables).

In particular, replaceVariableByHTML() basically extends the functionality of the embedHTML() in the case of templates. But everything may be more easily explained by a simple example.

Let us assume that you want to include some information coming from a web page into your Word document. You may do so, preserving the format of the original HTML document in a very simple way:

                                require_once 'path_to_phpdocx/classes/CreateDocx.inc';
                                $docx = new CreateDocxFromTemplate('../word_documents/testHTML2mdc.docx');
                                $docx->addTemplate('../word_documents/testHTML2mdc.docx');

                                $docx->replaceVariableByHTML('ADDRESS', 'inline', '

C/ Matías Turrión 24, Madrid 28043 Spain

', array('isFile' => false, 'parseDivsAsPs' => true, 'downloadImages' => false)); $docx->replaceVariableByHTML('CHUNK_1', 'block', 'http://www.2mdc.com/PHPDOCX/example.html', array('isFile' => true, 'parseDivsAsPs' => true, 'filter' => '#capa_bg_bottom', 'downloadImages' => true)); $docx->replaceVariableByHTML('CHUNK_2', 'block', 'http://www.2mdc.com/PHPDOCX/example.html', array('isFile' => true, 'parseDivsAsPs' => false, 'filter' => '#lateral', 'downloadImages' => true)); $docx->createDocx('../docx/replaceTemplateVariableByHTML');

And you will get as a result:

The HTML content, as seen in the example, may come from a external HTML page or from a string. The filter parameter has been used to select different portions of the original HTML code and insert them in the Word document as desired. it does not only admits single id references one can introduce an array with different ids, classes and tags of his choice.

How to process a template with phpdocx

Now we are going to show you an example that you may see at work in this very same website: http://www.phpdocx.com/demo.

This demo requires three different templates that you may download, together with the PHP script, from this zip file available online.

Like you can download all the required files and the resulting Word document from our "Demo Page" we will not include in the following nor the screen capture neither the resulting .docx files.

Let us first have a look at the whole script:

                                require_once 'path to phpdocx';
                                $dir = 'path to the folder with the templates';
                                $docx = new createDocxFromTemplate($dir. 'template_' . $_POST['template'] . '.docx');

                                $variables = array(
                                    'VAR_DATE'  => date("n/d/Y"),
                                    'VAR_NAME'  => $data['fullName'],
                                    'VAR_TITLE' => $data['title'],
                                );
                                $docx->replaceVariableByText($variables);

                                // chart
                                $chartItems = array();
                                foreach($data['chart'] as $key => $value) {
                                    $name = trim($value['dataName']);
                                    $value = trim($value['dataValue']);
                                    if ($name && $value) {
                                        $chartItems[$name] = array($value);
                                    }
                                }       
                                if (empty($chartItems)) {
                                    // No chart
                                    $docx->deleteTemplateBlock('chart');
                                } else {           
                                    // add chart           
                                    $chartSettings = array(
                                        'type' => 'pie3DChart',
                                        'showPercent' => 1,
                                        'sizeX' => 10,
                                        'sizeY' => 6,
                                        'js'    => 'center',
                                    );
                                    switch ($data['template']) {
                                        case '2':
                                            $chartSettings['type'] = 'pieChart';
                                            break;
                                        case '3':
                                            $chartSettings = array(
                                                'type' => 'colChart',
                                                'font' => 'Times New Roman',
                                                'sizeX' => 14,
                                                'sizeY' => 7,
                                                'border'=> 'none',
                                                'jc' => 'center',
                                                'legendpos' => 'none',
                                            );
                                            $chartItems['legend'] = array('');
                                            break;
                                    }
                                    $chartSettings['data'] = $chartItems;

                                    $chart = new WordFragment($docx, 'document');
                                    $chart->addChart($chartSettings);
                                    $variables = array(
                                        'CHART_1' => $chart,
                                    );
                                    $docx->replaceVariableByWordFragment($variables, array('type' => 'block'));
                                }

                                // table
                                $tableItems = array();
                                foreach($data['items'] as $key => $value) {
                                    $item = trim($value['dataItem']);
                                    $price = trim($value['dataPrice']);
                                    if ($item && $price) {
                                        $tableItems[] = array(
                                            'VAR_ITEM'  => $item,
                                            'VAR_PRICE' => $price,
                                        );
                                    }
                                }
                                if (empty($tableItems)) {
                                    // No table
                                    $docx->deleteTemplateBlock('table');
                                } else {
                                    $docx->replaceTableVariable($tableItems);
                                }

                                // html
                                if (!$data['html']) {
                                    $docx->deleteTemplateBlock('html');
                                } else {
                                    $code = stripslashes($data['html']);
                                    $code = '<head><style type="text/css"<p{font-family: Arial;font-size:11pt;}li{font-family: Arial;font-size:11pt;}</style></head><body>' .  $code . '</body>';  
                                    $docx->replaceVariableByHTML('CHUNK_1', 'block', $code);
                                }

                                // add image
                                $docx->replacePlaceholderImage('IMAGE_1',$this->baseAssets . '/img/image_' . $data['image'] . '.jpg');
                                $docx->clearBlocks();
                                $docx->createDocxAndDownload('/tmp/demo_template');

                            

Let us analyse this script step by step.

The first chunk of code reads:

                                $dir = 'path to the folder with the templates';
                                $docx = new createDocxFromTemplate($dir. 'template_' . $_POST['template'] . '.docx');
                            

We just create a new phpdocx instance via the createDocXFromTemplate class to deal with custom templates. We load into phpdocx the template choosen by the user (in the corresponding web form).

In the following block of code we start the actual parsing of the selected template:

                                $variables = array(
                                    'VAR_DATE'  => date("n/d/Y"),
                                    'VAR_NAME'  => $data['fullName'],
                                    'VAR_TITLE' => $data['title'],
                                );
                                $docx->replaceVariableByText($variables);
                            

These lines of code perform a standard "variable by string" substitution. The first variable is replaced by the current date that is obtained using the standard PHP date() method while the VAR_NAME (in the header) and VAR_TITLE (front page) variables are replaced by the values introduced by the user in the corresponding web form.

Now things start to get more sophisticated with:

                                // chart
                                $chartItems = array();
                                foreach($data['chart'] as $key => $value) {
                                    $name = trim($value['dataName']);
                                    $value = trim($value['dataValue']);
                                    if ($name && $value) {
                                        $chartItems[$name] = array($value);
                                    }
                                }       
                                if (empty($chartItems)) {
                                    // No chart
                                    $docx->deleteTemplateBlock('chart');
                                } else {           
                                    // add chart           
                                    $chartSettings = array(
                                        'type' => 'pie3DChart',
                                        'showPercent' => 1,
                                        'sizeX' => 10,
                                        'sizeY' => 6,
                                        'js'    => 'center',
                                    );
                                    switch ($data['template']) {
                                        case '2':
                                            $chartSettings['type'] = 'pieChart';
                                            break;
                                        case '3':
                                            $chartSettings = array(
                                                'type' => 'colChart',
                                                'font' => 'Times New Roman',
                                                'sizeX' => 14,
                                                'sizeY' => 7,
                                                'border'=> 'none',
                                                'jc' => 'center',
                                                'legendpos' => 'none',
                                            );
                                            $chartItems['legend'] = array('');
                                            break;
                                    }
                                    $chartSettings['data'] = $chartItems;

                                    $chart = new WordFragment($docx, 'document');
                                    $chart->addChart($chartSettings);
                                    $variables = array(
                                        'CHART_1' => $chart,
                                    );
                                    $docx->replaceVariableByWordFragment($variables, array('type' => 'block'));
                                }

                            

We first create a new chart from scratch using the data introduced by the user in the web form, after that we create a Word fragment with the generated chart and insert it in place using the replaceVariableByWordFragment method.

By the way, you may notice that in case the user has not provided us with the required chart data the whole section is removed via the deleteTemplateBlock method.

The following chunk of code is particularly interesting because it allows us to populate a table with a custom number of rows depending on the user input:

                                // table
                                $tableItems = array();
                                foreach($data['items'] as $key => $value) {
                                    $item = trim($value['dataItem']);
                                    $price = trim($value['dataPrice']);
                                    if ($item && $price) {
                                        $tableItems[] = array(
                                            'VAR_ITEM'  => $item,
                                            'VAR_PRICE' => $price,
                                        );
                                    }
                                }
                                if (empty($tableItems)) {
                                    // No table
                                    $docx->deleteTemplateBlock('table');
                                } else {
                                    $docx->replaceTableVariable($tableItems);
                                }
                            

Once again we check if there is data to populate the table and in the contrary we remove the corresponding block of the document.

If the user has provided us with some data we format it as an array and insert it in the preformatted table with the replaceTableVariable() method.

This block of code:

                                // html
                                if (!$data['html']) {
                                    $docx->deleteTemplateBlock('html');
                                } else {
                                    $code = stripslashes($data['html']);
                                    $code = '<head><style type="text/css">p{font-family: Arial;font-size:11pt;}li{font-family: Arial;font-size:11pt;}</style></head><body>' .  $code . '</body>';
                                    $docx->replaceVariableByHTML('CHUNK_1', 'block', $code);
                                }
                            

checks if the user has included any text in the "Rich Text Editor Box" avalaible in the web form and if so includes it as HTML via the replaceVariableByHTML method.

Well, we are almost done. The end of the code replace an existing placeholder image with the image used by the user via the:

$docx->replacePlaceholderImage('IMAGE_1',$this->baseAssets . '/img/image_' . $data['image'] . '.jpg'); method.

And we finally clean any reamining BLOCK tags with the clearBlocks() method before sending the final docx to the browser.

We hope that this tutorial has been of help and that you are now able to grasp all the potential uses that you may give to phpdocx in your professional projects.

Enjoy!!

Appendix: debugging options

phpdocx uses log4php as an external library for debugging.

The configuration options for log4php can be found in the config/log4php.xml file.

The default setup is:

                                
                                    
                                        
                                        
                                    
                                    
                                        
                                        
                                    
                                
                            

So by default you only get warnings and higher logging levels.

If you would like to get on screen the maximum level of information provided by phpdocx you shoud replace "WARN" by "DEBUG";

If you prefer to get the info not directly on screen but in a log file you should you should change the appender element as follows: