Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

manipulating template in PHPWord

I am using a word document generator for PHP for the reports module of the web-app i am developing. I choose PHPWord because the free version of PHPDocX has very limited functionality plus it has a footer that it is only a free version. I have a template given by the client. What I want is I want to load the template and add dynamic elements to it like additional text or tables. My code is here:

<?php
require_once '../PHPWord.php';

$PHPWord = new PHPWord();

$document = $PHPWord->loadTemplate('Template.docx');
$document->setValue('Value1', 'Great');

$section = $PHPWord->createSection();
$section->addText('Hello World!');
$section->addTextBreak(2);

$document->setValue('Value2', $section);

$document->save('test.docx');
?>

I tried to create a new section and tried to assign it to one variable in the template(Value2) but this error appeared:

[28-Jan-2013 10:36:37 UTC] PHP Warning:  utf8_encode() expects parameter 1 to be string, object given in /Users/admin/localhost/PHPWord_0.6.2_Beta/PHPWord/Template.php on line 99
like image 958
John Micah Fernandez Miguel Avatar asked Jan 28 '13 10:01

John Micah Fernandez Miguel


3 Answers

setValue expects the second parameter to be a plain string. It's not possible to provide a section object.

I've dived into the code and there's not an easy way to have a section object returning a value that could be used by the setValue function.

As I had the same issue, I've wrote a patch for the Template.php file that allows you to clone table rows before replacing their tags with setValue. Each row gets an unique id, allowing you to identify the template tags for each different row.

This is how it works:

Add this function to your Template.php file (found inside the PHPWord directory)

public function cloneRow($search, $numberOfClones) {
    if(substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {
        $search = '${'.$search.'}';
    }
    $tagPos      = strpos($this->_documentXML, $search);
    $rowStartPos = strrpos($this->_documentXML, "<w:tr", ((strlen($this->_documentXML) - $tagPos) * -1));
    $rowEndPos   = strpos($this->_documentXML, "</w:tr>", $tagPos) + 7;

    $result = substr($this->_documentXML, 0, $rowStartPos);
    $xmlRow = substr($this->_documentXML, $rowStartPos, ($rowEndPos - $rowStartPos));
    for ($i = 1; $i <= $numberOfClones; $i++) {
        $result .= preg_replace('/\$\{(.*?)\}/','\${\\1#'.$i.'}', $xmlRow);
    }
    $result .= substr($this->_documentXML, $rowEndPos);
    $this->_documentXML = $result;
}

In your template file add to each table one row that you will use as a template row. Let's assume you've added a tag ${first_name} in this row.

To get a table with 3 rows call: $document->cloneRow('first_name', 3);

The working copy of your template is now updated with a table containing 3 rows. Each tag inside the row has been appended with a # and row number.

To set your values, use setValue $document->setValue('first_name#1', 'Name on the first row'); $document->setValue('first_name#2', 'Name on the second row'); $document->setValue('first_name#3', 'Name on the third row');

I hope this is useful! I'll keep an updated version of the code and documentation here: http://jeroen.is/phpword-templates-with-repeating-rows/

like image 157
Jeroen Moors Avatar answered Sep 24 '22 18:09

Jeroen Moors


According to the documentation, you can't add content to the file when you are working with templates.

It is not possible to add new PHPWord elements to a loaded template file.

Documentation

like image 3
Daniel Cisneros Medina Avatar answered Sep 22 '22 18:09

Daniel Cisneros Medina


Totally new version CloneRow and setValue

Now you can clone merged cells. Many bugs with OOXML tags was fixed.

And new method setValue - now ignoring trash-tags inside your pattern. Like

{My<trash ooxml tags>Pattern}

You can find code, docs and examples here: https://github.com/Arisse/PHPWord_CloneRow

like image 1
Korimizu Avatar answered Sep 20 '22 18:09

Korimizu