Reputation: 529
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!
Upvotes: 10
Views: 27940
Reputation: 954
Above Answers are great.
But for me I applied all above solutions but still I was getting issue. Finally I got solution by debugging each line.
Here are my findings.
If you add Row $phpWord->addRow()
; without any line content after that you will also get Corrupt Word File issue.
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$phpWord->setDefaultParagraphStyle(array('space' => array('line' =>10)));
$section = $phpWord->addSection(['marginLeft' => 600, 'marginRight' => 600]);
$textrun = $section->addTextRun();
$table_shipment_Detail = $section->addTable();
$table_shipment_Detail->addRow();
if($consignee->iec_no != ""){
$table_shipment_Detail->addCell(800)->addText("IEC:".$consignee->iec_no);
}
if($consignee->gst_no != ""){
$table_shipment_Detail->addCell(800)->addText("GST:".$consignee->gst_no);
}
if($consignee->tax_id != ""){
$table_shipment_Detail->addCell(1500)->addText("TAX ID:".$consignee->tax_id);
}
If you see above example, I have use $table_shipment_Detail->addRow();
but $consignee->iec_no, $consignee->tax_id, $consignee->tax_id
are blank so when doc created it throws Corrupt Word File issue.
so I had to replace above code with following snippet.
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$phpWord->setDefaultParagraphStyle(array('space' => array('line' =>10)));
$section = $phpWord->addSection(['marginLeft' => 600, 'marginRight' => 600]);
$textrun = $section->addTextRun();
$table_shipment_Detail = $section->addTable();
if($consignee->iec_no != "" || $consignee->gst_no != "" || $consignee->tax_id != ""){
$table_shipment_Detail->addRow();
}
if($consignee->iec_no != ""){
$table_shipment_Detail->addCell(800)->addText("IEC:".$consignee->iec_no);
}
if($consignee->gst_no != ""){
$table_shipment_Detail->addCell(800)->addText("GST:".$consignee->gst_no);
}
if($consignee->tax_id != ""){
$table_shipment_Detail->addCell(1500)->addText("TAX ID:".$consignee->tax_id);
}
I hope this will help someone.
Upvotes: 2
Reputation: 34
I did try all the methods but got errors. This fixed it. I was using the .PHP file under the
<!DOCTYPE html>
<html>
<head>
</head>
...........
<body>
<?PHP CODE ?>
</body>
</html>
```
The HTML encoding here was giving problems, once I removed all HTML HEAD and BODY and DOCTYPE TAGS and left pre PHP Code
```
<?PHP .... ?>
```
Worked like a charm !!!
Cheers
Upvotes: 0
Reputation: 6341
While using PHPWord TemplateProcessor
I faced the same issue.
By enabling setOutputEscapingEnabled
from PhpOffice\PhpWord\Settings
fixes the issue for me.
PhpOffice\PhpWord\Settings::setOutputEscapingEnabled(true);
$templateProcessor->saveAs($filepath);
As reported by Māris Kiseļovs
But You had to call
setOutputEscapingEnabled
before replacing values in template document
Upvotes: 6
Reputation: 41
Add setCompatibility()
before createWriter()
\PhpOffice\PhpWord\Settings::setCompatibility(false);
Add exit;
after the save()
// XML Writer compatibility
\PhpOffice\PhpWord\Settings::setCompatibility(false);
// Saving the document as OOXML file...
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
ob_clean();
$objWriter->save('php://output');
exit;
Upvotes: 4
Reputation: 11
This solution worked for me
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection(
array('paperSize' => 'Legal', 'marginLeft' => 2834.645669291, 'marginRight' => 1417.322834646, 'marginTop' => 2834.645669291, 'marginBottom' => 1417.322834646)
);
//$html = $_POST['description'];
$html = $_POST['description'];
\PhpOffice\PhpWord\Shared\Html::addHtml($section, $html, false, false);
// Save file
// Saving the document as OOXML file...
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
//$objWriter->save('test.docx');
$temp_file_uri = tempnam('', 'xyz');
$objWriter->save($temp_file_uri);
//download code
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=helloWorld.docx');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Content-Length: ' . filesize($temp_file_uri));
readfile($temp_file_uri);
unlink($temp_file_uri); // deletes the temporary file
exit;
Upvotes: 0
Reputation: 301
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.
Upvotes: 13
Reputation: 171
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 :)
Upvotes: 17
Reputation: 25
$h2d_file_uri = tempnam('', 'htd');
//exit($h2d_file_uri);
$objWriter = PHPWord_IOFactory::createWriter($php_Word, 'Word2007');
$objWriter->save($h2d_file_uri);
// Download the file:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment;filename=BMP_QuotationNo_'.$html[0['quoteno'].'.docx');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($h2d_file_uri));
ob_clean();
flush();
$status = readfile($h2d_file_uri);
unlink($h2d_file_uri);
exit;
Upvotes: 0
Reputation: 1331
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);
Upvotes: 17