📜 ⬆️ ⬇️

Creating a Microsoft Word printable with PHP

Prehistory

I am engaged in writing a crm module in one dealer center. The whole project is done on the web. One of the recent tasks was to create a printed form, or rather a commercial offer. And everything would be fine, but the document should be printed and handed over to the client, and the main catch was that this document was multi-page and contained two footers, the top one and the side one. (This was the official form of the organization). Solution option under the cut.

My solution

And with these footers, and there was a problem. I could not find a simple solution using HTML javascript. Using HTML, you can control the location of the blocks when printing, transfer the block if it does not enter the target and everything in that spirit. How to calculate the approximate end of the page and fit a block with a footer there (using javascript) I also imagine poorly, since there are quite a few nuances on the user's side. Therefore, it was decided to go a little different way, namely contact with Microsoft Word.
Glory to the leadership of this organization, Microsoft Office 2007 is installed on every workstation.

So, a template was assembled in Word, which contained a fully-filled commercial offer, with automatically generated fields and footers. It remained only to substitute in the right places customer data, a table with the specification of the goods and contacts of the manager. How to do it?

I did not use third-party libraries, it turned out that the Microsoft Word document (this is about * .docx) is nothing more than a regular zip with a bunch of xml files and other image-like resources. Unpacking docx we get the following:
image
')
Actually, of all these files, we need only one, this is document.xml. It contains all the information we are interested in, namely the content of our document. Since this file will serve as a template, we carefully extract it and place it next to our packed document. Then we just have to take its contents, change the data, pack it in Word in the right place and send it to the user in the browser.
To do this, we use Zip - the extension makes it easy to read and write both to the compressed ZIP archives themselves and to the files inside them.

$zip = new ZipArchive; if ($zip->open('template.docx') === TRUE) { /*     (   )       $content*/ $handle = fopen("document.xml", "r"); $content = fread($handle, filesize("document.xml")); fclose($handle); /*        */ $content = str_replace("{customer_r}","  ",$content); /*    document.xml*/ $zip->deleteName('word/document.xml'); /*     */ $zip->addFromString('word/document.xml',$content); $zip->close(); } 

After the done operations we send the received document to the user in the browser.

If you do not spoil the xml, then the user will receive a fully valid document. If you carelessly inadvertently, when you open it, Word curses you about the presence of invalid characters, tells you exactly where, and will try to correct it.
You can add any information, such as a table.
The table cell can be easily calculated (as well as the whole row):

 <w:tc><w:tcPr><w:tcW w:w="4783" w:type="dxa"/></w:tcPr><w:pw:rsidR="00BB344C" w:rsidRDefault="00BB344C"><w:r><w:t>  </w:t></w:r><w:bookmarkStart w:id="0" w:name="_GoBack"/><w:bookmarkEnd w:id="0"/></w:p></w:tc></w:tr> 


Well, that's all.
If you know other ways to solve this problem, please share.
I would be very grateful.

Source: https://habr.com/ru/post/204484/


All Articles