這次碰上的問題主要是有個網頁委託內容包含需動態產生word檔以供使用者下載,因此我從先前接觸過的PHPExcel而找到PHPWord這套library。先前使用PHPExcel時多半是為了利用簡單的方式來讀取excel檔中的內容,而並未自行產出一個獨立的excel檔,而這次算是剛好反過來了,要利用已有的內容來產生一個word檔。
起初利用PHPWord 0.6.2-1 Beta所提供的examples成功建立word檔後覺得還蠻放心的,後來隨即也想到若是包含中文字時會不會有編碼問題,因此測了一下,果然變成亂碼了。後來隨即在官方討論區找到此篇文章:how to properly handle UTF-8 ? (UTF8) ,原來不只我遇到了這個問題~而根據底下的回覆表示以簡體中文編碼為例,須將source code中的$givenText = utf8_encode($text);註解並換成$text = iconv('gbk','utf-8','福建省泉州市惠南工业区北一路');即可解決問題,但這個方法只適用於範例中的Template.php才行,用在Basic Table.php則會出現亂碼。
// 原始寫法 $givenText = utf8_encode($text); // 修改後 //$givenText = utf8_encode($text); $text = iconv('gbk','utf-8','福建省泉州市惠南工业区北一路');
後來我將source code中所有包含utf8_encode的文件都以iconv的方式去取代,結果算是成功沒出現亂碼了,但是word會在開啟時跳出錯誤警告,表示此檔案已損毀是否要進行修復(修復後沒大礙就是了)。憑著吹毛求疵斤斤計較的精神,也擔心使用者若看到損毀時會有疑慮,因此我又開始找其他方式去做,而最後找到的方法就是直接將有包含utf8_encode的文件都註解掉,改成直接賦予對應值,如下範例:
// 原始寫法 $givenText = utf8_encode($text); // 修改後 //$givenText = utf8_encode($text); $givenText = $text;
另外範例中用來產生word的php也記得先改成utf-8,之後即可輕鬆產生包含中文內容的docx檔~
至於該如何直接產生word供使用者一點擊就下載,方法我也都找到了,只是Template在PHPWord中的寫法與其他比較不一樣,因此方法也有被侷限住,一般的如Basic Table可以用以下方法來達到不存檔而下載,只要在最後Save File部分動一點手腳即可:
// Save File $objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); // 原本是儲存到當前目錄下,名為BasicTable.docx // $objWriter->save('BasicTable.docx'); // 先寫入header,再利用$objWriter->save('php://output'); // 將結果直接show出來,即可成功進行下載動作 $filename = 'abc.docx'; header("Cache-Control: public"); header("Content-Description: File Transfer"); header("Content-Disposition: attachment; filename=$filename"); header("Content-Type: application/octet-stream; "); header("Content-Transfer-Encoding: binary"); $objWriter->save('php://output');
而Template無法使用上述方法,須使用下面範例才行:
// Save File // 原本是儲存到當前目錄下,名為Solarsystem.docx // $document->save('Solarsystem.docx'); // 先將檔案暫存起來 $temp_file = tempnam(sys_get_temp_dir(), 'PHPWord'); $document->save($temp_file); // 一樣是寫入header,但最後以不同指令呈現出來,最後再刪掉伺服器上的暫存檔 $objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); $filename = 'abc.docx'; header("Cache-Control: public"); header("Content-Description: File Transfer"); header("Content-Disposition: attachment; filename=$filename"); header("Content-Type: application/octet-stream; "); header("Content-Transfer-Encoding: binary"); readfile($temp_file); // or echo file_get_contents($temp_file); unlink($temp_file); // remove temp file
到這裡我所需要的功能大致上齊全了,只剩下PHPWord沒辦法產生word2003(*.doc)的檔案,也是一個令人頭痛的問題。
沒有留言:
張貼留言