PHPWord导出提供损坏的Word文件

时间:2011-12-20 14:28:00

标签: php xml ms-word

我使用了PHPWord网站上的示例代码:http://phpword.codeplex.com/documentation 当我尝试用Word打开它时,我得到错误“Office Open XML文件test.docx无法打开,因为内容存在问题。”当我点击“详细信息”时,它只是说“文件已损坏,无法打开”。它确实让我修复它并打开它,但这不是非常用户友好...这是我正在使用的代码:     

// 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');

如你所见,我确实使用php://输出作为保存。关于如何摆脱腐败的任何想法。我确实打开了zip,看到在document.xml的末尾出现了空行。也许这是造成它的?

谢谢!

6 个答案:

答案 0 :(得分:12)

只需添加ob_clean();在输出之前!

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

这将清除您的输出,现在您可以安全地生成docx文件:)

答案 1 :(得分:8)

我知道这是一个老问题,但我遇到了完全相同的问题,只是找到了最简单的解决方案。我遇到的问题是我使用Symfony,在生成文件时,我不得不用Notepad ++编辑文件,看看内容后面有错误信息,说控制器需要一个Response()。

所以我最后把->save()放在react-leaflet之后,它运作良好。

答案 2 :(得分:7)

您添加的任何文字都不应包含HTML字符。将所有适用的字符转换为HTML实体,例如,如果您必须首先添加以下“我和我的代码”,请执行以下操作:

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

使用Builtin功能保存文件。 docx文件是zip文件(你可以在winrar或winzip中打开它们)所以你不应该使用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");

这样,文件将被创建,然后由用户下载。

备注:docx文件实际上是XML文件。所以任何xml保留字符都会破坏文件。解决方法是将文本转换为以下内容

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);

答案 3 :(得分:0)

     $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;

答案 4 :(得分:0)

此解决方案适合我

    $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;

答案 5 :(得分:0)

  1. setCompatibility()之前添加createWriter()

    \PhpOffice\PhpWord\Settings::setCompatibility(false);
    
  2. exit;之后添加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;