How to generate a word docx from a template with PHP ?
Hey folks,
A lot of clients of mine asked for docx generation in the past.
The only solution that I knew of in PHP is the SOAP client phplivedocx.
first of all It was kinda slow and I didn’t want to relly on a service and more importantly It was missing the “nested block” feature.
So I decided to create my own class !
Have fun & fork me if you need another feature !
http://github.com/djpate/docxgen
DOCXGEN
Features
- Create valid docx based on a template
- Nested blocks on infinite levels
How to create your template
Simply open up word 2007+
If you want to map a single field you can just use #NAME# but you could use anything you like since it’s just a search & replace
To create a block
[start blockname] your content [start somenestedblock] [end somenestedblock] [end blockname]
- blockname should be unique
- blockname has to match w+ reg ex (a-zA-Z_)
- fields mapped in block has to be unique
Please check out full template in the repo
How to setup
require("phpDocx.php"); $phpdocx = new phpdocx("mytemplate.docx");
How to assign values
$phpdocx->assign("#TITLE1#","Hello !"); // basic field mapping $phpdocx->assignBlock("members",array(array("#NAME#"=>"John","#SURNAME#"=>"DOE"),array("#NAME#"=>"Jane","#SURNAME#"=>"DOE"))); // this would replicate two members block with the associated values $phpdocx->assignNestedBlock("pets",array("#PETNAME#"=>"Rex"),array("members"=>1)); // would create a block pets for john doe with the name rex $phpdocx->assignNestedBlock("pets",array("#PETNAME#"=>"Rox"),array("members"=>2)); // would create a block pets for jane doe with the name rox $phpdocx->assignNestedBlock("toys",array("#TOYNAME#"=>"Ball"),array("members"=>1,"pets"=>1)); // would create a block toy for rex $phpdocx->assignNestedBlock("toys",array("#TOYNAME#"=>"Frisbee"),array("members"=>2,"pets"=>1)); // would create a block toy for rox
How to save
$phpdocx->save("somefile.docx");
More info
Why this pclzip ?
I’m using pclzip for the zip process because the zip utility provided with php can cause issue with office
What’s the licence ?
GPL
Anything else ?
I’m using three function from the TBS library so congrats to them

About your problem to add image, i resolved the problem with these steps:
1- Declare in template docx image file with name FILE.png
2- Define docx object and add parameter with assignNestedBlock or assignBlock:
$phpdocx->assignNestedBlock(“imgmodels”,array(array(“FILE.png”=>”$entry”)),array(“files”=>1));
3- Add the image in media/ directory by using:
$phpdocx->addImage(“$entry”,$dir . “/” . $entry);
For that, i modified your class in assignNestedBlock() and assignBlock() functions by adding the following lines:
foreach($row as $id => $val){
# If Id is image, it gets the reference id to be replaced by the value
if (preg_match(“/img/”,$blockname)) {
if (preg_match(“/name=\”$id\”.+r:embed=\”(\S+)\” cstate=\”print\”/”,$current_block,$matcharray)) {
$id = $matcharray[1];
// The keyword phpdocx_ is added by addImage function
$val = “phpdocx_” . $val;
}
$current_block = str_replace(“\”$id\”",”\”" . $this->filter($val) . “\”",$current_block);
} else {
$current_block = str_replace($id,$this->filter($val),$current_block);
}
}
Thanks
Benoît
can you do a pull request on github?
Hello,
Thanks very much for your class !
I need to customize header then i modify the class with the following line:
Save() function:
$this->content = file_get_contents($this->tmpDir.”/word/document.xml”);
// Parameters can be used in header
$this->header = file_get_contents($this->tmpDir.”/word/header1.xml”);
$this->clean();
$this->content = $this->parseBlocks($this->content);
foreach($this->assigned_field as $field => $value){
$this->content = str_replace($field,$value,$this->content);
$this->header = str_replace($field,$value,$this->header);
}
compact() function:
file_put_contents($this->tmpDir.”/word/header1.xml”,$this->header);
Thanks !
Benoît
Great!! This is a tool, which I’ve been looking for days!
I hope, you’re still active in this project?
Well, I’ve got a problem with the german Umlauts. I cannot create any files with ä,ö or ü in it, because Word tells me there’s a problem in the docx file content. Do you know how I can fix it?
Good work!
I make a port of phpdocx for odt (Open Office) documents, and i built on top some interface stuff to mySQL.
The resulting class is otdphpsql.php, and that class allows to add, delete, modify reports at run time only using a DB table.
Hope this will be util.
Nice work !
How do i add a page break? I am creating letters and each letter must be on a seperate page. How can i achieve this?
Nice, thanks !!
It’s buggy when you insert a block or nested blocks with a lot of information… I don’t know if its phpdocx or pclzip :s… any ideas???
Hello,
Your script could allow entering text in the file. without making comparisons with text already on the file
Insert text at the beginning .. the end .. in the middle …
it was very good:)
And simply, why don’t use the real PHPdocx?
http://www.phpdocx.com
Greetings
Hi there..!.. this is working really good.!.. I hope u get done the img feature soon.. =)..
I started working on it but for some reason it’s not working I’m investigating…
This looks a lot simpler than Livedocx – I might give it a go. Thanks for creating it.
What happens if you create a table and put [start blockname] in the cell at the start of a row, and [end blockname] in the next row of the table?
Can you use this technique to create a variable number of table rows? And do the block control [phrases] have to appear in a line all on their own?
Thanks
Alan
Nevermind, Must be a typo on my template or my code cuz’ today is working fine =)…
Thanks a lot for the new Download Method… hope you could finish the images method this week… I’ll be following your progress in github..
Good luck and Good Day sir.. =)
Nice man.!.. Thanks a lot. I really love this class… And is nice to know that your working on it.. =)
BTW, there’s a problem with the assignblock. When i use two blocks, works fine, but when i need more than 2 it just throws a warning: “Undefined index: bloquec”…
Don’t know if it’s just me, or is a bug but would be nice to check it out…
Could you start an issue on github so I can check it out.
I need your template and your code
Will love to know how to add imgs to my doc… =(
I’ll try to add this feature on monday. I just checked and it shouldn’t be too hard to impletement….
good work!
any progress on the adding image feature yet?
I’ve been kinda of busy but will try to give it a go soon !