Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPWord export giving Corrupt Word File

Tags:

php

ms-word

xml

I used the example code from PHPWord's site: http://phpword.codeplex.com/documentation And when I try and open it with Word I get the error "The Office Open XML file test.docx cannot be opened because there are problems with the contents." and when I click "Details" It simply says "The file is corrupt and cannot be opened." It does let me repair it and open it, but that wouldn't be very user friendly... Here is the code I'm using:

// Create a new PHPWord Object
$PHPWord = new PHPWord();

// Every element you want to append to the word document is placed in a section. So you need a section:
$section = $PHPWord->createSection();

// After creating a section, you can append elements:
$section->addText('Hello world!');

// You can directly style your text by giving the addText function an array:
$section->addText('Hello world! I am formatted.', array('name'=>'Tahoma', 'size'=>16, 'bold'=>true));

// If you often need the same style again you can create a user defined style to the word document
// and give the addText function the name of the style>:
$PHPWord->addFontStyle('myOwnStyle', array('name'=>'Verdana', 'size'=>14, 'color'=>'1B2232'));
$section->addText('Hello world! I am formatted by a user defined style', 'myOwnStyle');

// You can also putthe appended element to local object an call functions like this:
$myTextElement = $section->addText('Hello World!');



header('Content-Type: application/vnd.ms-word');
header('Content-Disposition: attachment;filename="test.docx"');
header('Cache-Control: max-age=0');
// At least write the document to webspace:
$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007');
$objWriter->save('php://output');

As you can see I did use php://output as the save there. Any ideas on how to get rid of the corruption. I did open the zip and saw that at the end of document.xml it appears there is blank line. Maybe that is causing it?

Thanks!

like image 607
oneadvent Avatar asked Dec 20 '11 14:12

oneadvent


3 Answers

Just add ob_clean(); before output it!

ob_clean();
$objWriter->save('php://output');

This will clean you'r output, and now you are safe to generate docx file :)

like image 153
Oliver Markovic Avatar answered Oct 26 '22 23:10

Oliver Markovic


Any Text you add should not contain HTML characters. Convert all applicable characters to HTML entities for example if you have to add the following "Me & my Code" first do this:

$Text_to_Add = htmlentities("Me & my Code");
$section->addText($Text_to_Add);

Use the Builtin function to save the file. docx files are zip files (you can open them in winrar or winzip) so you should not use php://output

$objWriter->save('helloWorld.docx');    
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=helloWorld.docx");
header("Content-Type: application/docx");
header("Content-Transfer-Encoding: binary");

This way the file will be created and then downloaded by user.

Side Note: docx files are actually XML files. So any xml reserve character will corrupt the file. A workaround is to convert your text as following

function xmlEntities($str)
{
    $xml = array('"','&','&','<','>',' ','¡','¢','£','¤','¥','¦','§','¨','©','ª','«','¬','­','®','¯','°','±','²','³','´','µ','¶','·','¸','¹','º','»','¼','½','¾','¿','À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','×','Ø','Ù','Ú','Û','Ü','Ý','Þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð','ñ','ò','ó','ô','õ','ö','÷','ø','ù','ú','û','ü','ý','þ','ÿ');
    $html = array('"','&','&','<','>',' ','¡','¢','£','¤','¥','¦','§','¨','©','ª','«','¬','­','®','¯','°','±','²','³','´','µ','¶','·','¸','¹','º','»','¼','½','¾','¿','À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','×','Ø','Ù','Ú','Û','Ü','Ý','Þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð','ñ','ò','ó','ô','õ','ö','÷','ø','ù','ú','û','ü','ý','þ','ÿ');
    $str = str_replace($html,$xml,$str);
    $str = str_ireplace($html,$xml,$str);
    return $str;
}


$Text_to_Add = htmlentities("Me & my Code");
$Test_to_Add_XML_Cleaned = xmlEntities($Text_to_Add);
$section->addText($Test_to_Add_XML_Cleaned);
like image 23
Usman Shaukat Avatar answered Oct 26 '22 23:10

Usman Shaukat


I know this is an old question but I had the exact same problem and just found the easiest solution of all. The problem I had is that I'm using Symfony, and that when generating the file, I had to edit the file with Notepad++ to see that there were error messages after the content, saying that the controller needed a Response().

So I ended up putting exit; just after the ->save(), and it worked fine.

like image 25
Cryborg Avatar answered Oct 26 '22 22:10

Cryborg