我有一個PHP腳本,它從MySQL數據庫中讀取信息,並使用模板將其放入一個DOCX文件中。在模板中,有佔位符稱爲<<<variable_name>>>
其中variable_name
是MySQL字段的名稱。DOCX編碼問題
DOCX文件是Zip檔案,所以我的PHP腳本使用ZipArchive庫打開DOCX並編輯document.xml
文件,用正確的數據替換佔位符。
這工作得很好,直到今天,當我遇到一些編碼問題。任何非ANSI字符都不能正確編碼,並使輸出DOCX損壞。 MS Word提供錯誤消息「非法XML字符」。
當我解壓縮文檔並在記事本++中打開document.xml
時,我可以看到有問題的字符。通過進入編碼菜單,並選擇「ANSI編碼」,我可以正常看到字符:它們是英鎊(£)符號。當N ++設置爲「以UTF-8編碼時,它們顯示爲十六進制值。
通過選擇」轉換爲UTF-8「的N ++選項,UTF-8中的字符顯示OK,MS Word打開文檔但我不想在每次創建時手動解壓我的DOCX壓縮文件 - 腳本的全部要點是生成文檔快捷方便。以UTF-8,使「£」字符出現正確
我的代碼(從另一個問題部分複製於SO):
if (!copy($source, $target)) // make a duplicate so we dont overwrite the template
print "Could not duplicate template.\n";
$zip = new ZipArchive();
if ($zip->open($target, ZIPARCHIVE::CHECKCONS) !== TRUE)
print "Source is not a docx.\n";
$content_file = substr($source, -4) == '.odt' ? 'content.xml' : 'word/document.xml';
$file_contents = $zip->getFromName($content_file);
// Code here to process the file, get list of substitutions to make
foreach ($matches[0] as $x => $variable)
{
$find[$x] = '/' . $matches[0][$x] . '/';
$replace[$x] = $$matches[1][$x];<br>\n";
}
$file_contents = preg_replace($find, $replace, $file_contents, -1, $count);
$zip->deleteName($content_file);
$zip->addFromString($content_file, $file_contents);
$zip->close();
chmod($target, 0777);
我曾嘗試:
$file_contents = iconv("Windows-1252", "UTF-8", $file_contents);
和:
$file_contents_utf8 = utf8_encode($file_contents_utf8);
,試圖讓PHP腳本以UTF-8編碼文件。
如何使用ZipArchive
庫在保存時將PHP腳本編碼爲UTF-8文件?