php 模板替换,使用PHPWord对Word文件做模板替换
因工作需要,使用了版本比較舊的PHPWord項目
官方已不見維護更新,上次版本更新是在Fri Jul 8, 2011 at 8:00 AM
如果PHP版本>=5.3.3,強烈推薦使用PHPOffice/PHPWord這個開源項目
本篇針對的為舊版本的PHPWord
基本安裝
問題總結(jié)
Autoloader自動加載部分情況下失敗
在使用Yii 1配置自動加載時無法正常加載類庫,需對其PHPWord/Autoloader.php做部分調(diào)整,這兒借鑒了PHPExcel的Autoloader:
/**
* PHPWord_Autoloader
*/
class PHPWord_Autoloader
{
/**
* Register the Autoloader with SPL
*
*/
public static function Register() {
$functions = spl_autoload_functions();
foreach ( $functions as $function)
spl_autoload_unregister($function);
$functions = array_merge(array(array('PHPWord_Autoloader','Load')),$functions);
foreach ( $functions as $function)
$x = spl_autoload_register($function);
return $x;
} // function Register()
/**
* Autoload a class identified by name
*
* @param string $pClassName Name of the object to load
*/
public static function Load($pClassName){
if ((class_exists($pClassName,FALSE)) || (strpos($pClassName, 'PHPWord') !== 0)) {
// Either already loaded, or not a PHPWord class request
return FALSE;
}
$pClassFilePath = PHPWORD_BASE_PATH .
str_replace('_',DIRECTORY_SEPARATOR,$pClassName) .
'.php';
if ((file_exists($pClassFilePath) === FALSE) || (is_readable($pClassFilePath) === FALSE)) {
// Can't load
return FALSE;
}
require($pClassFilePath);
} // function Load()
}
模板替換時無法識別模板標簽
表現(xiàn)
使用/復(fù)制官方樣例的模板文件替換正常
自己手動敲出模板標簽替換異常
原因
PHPWord的替換規(guī)則是將Word文件解析成XML進行替換處理,當Word解析成XML時字符分離了,導(dǎo)致匹配不上模板標簽;
具體分析可參考一下資料:
解決辦法
改進Template類:
可參考Github: Arisse/PHPWord_CloneRow對Template類進行改造。
因為下面仍需要修改Template類,這兒暫時就不貼代碼了,下面一并貼出改造后的代碼。
中文亂碼
編輯PHPWord/Template.php,找到代碼$replace = utf8_encode($replace);,刪除或者注釋掉這行代碼,添加$replace = iconv( 'gbk','utf-8', $replace);,比如代碼改為如下:
/**
* Set a Template value
*
* @param mixed $search
* @param mixed $replace
*/
public function setValue($search, $replace) {
if(substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {
$search = '${'.$search.'}';
}
if(!is_array($replace)) {
//$replace = utf8_encode($replace);
$replace =iconv('gbk', 'utf-8', $replace); // 注釋掉上面行后添加這行
}
$this->_documentXML = str_replace($search, $replace, $this->_documentXML);
}
空格輸出
在想要輸出換行的地方用
代替即可.
標記符號輸出
參考百度經(jīng)驗: 如何在word中選擇打鉤的方框
僅以輸出□和?為例,其它符號與之類似。
注:PHP文件需要使用UTF-8編碼
在Word文件中按照參考文件方式插入?;
復(fù)制符號到PHP文件;
正常的輸出替換。
具體代碼見如下的項目代碼。
Template類代碼
// code
/**
* Set a Template value
*
* @param mixed $search
* @param mixed $replace
*/
public function setValue($search, $replace, $limit=-1) {
if(substr($search, 0, 1) !== '{' && substr($search, -1) !== '}') {
$search = '{'.$search.'}';
}
if(!is_array($replace)) {
// $replace = utf8_encode($replace);
// $replace = iconv( 'gbk','utf-8', $replace);
$replace = str_replace("\n","
",$replace);
}
preg_match_all('/\{[^}]+\}/', $this->_documentXML, $matches);
foreach ($matches[0] as $k => $match) {
$no_tag = strip_tags($match);
if ($no_tag == $search) {
$match = '{'.$match.'}';
$this->_documentXML = preg_replace($match, $replace, $this->_documentXML, $limit);
if ($limit == 1) {
break;
}
}
}
}
// code
項目代碼
// @author Heier xheier@outlook.com
public function actionExportPersonTable() {
// 獲取數(shù)據(jù)部分代碼
// ...
$PHPWord = new PHPWord();
// Word模板目錄
$personBasePath = Yii::app()->basePath.'/person/';
// 刪除目錄下臨時文件-十分鐘以前
$this->delfile( $personBasePath, 10 );
// 模板文件名
$tempName = $personBasePath . '/moban.docx';
$word = $PHPWord->loadTemplate( $tempName );
// 項目使用的是GBK編碼,需要做轉(zhuǎn)換
$username = iconv('gbk', 'utf-8', getUserNameById($personData[0]['user_id']) );
$personal_type = $personData[0]['personal_type'];
// 模板替換開始
// 可以輸出打勾的方框
$deptA=$deptBP=$deptB=$deptC=$deptD = '□';
if( $DirectorLevel == 'A' ) {
$deptA = '?';
} elseif( $DirectorLevel == 'B+' ) {
$deptBP = '?';
} elseif( $DirectorLevel == 'B' ) {
$deptB = '?';
} elseif( $DirectorLevel == 'C' ) {
$deptC = '?';
} elseif( $DirectorLevel == 'D' ) {
$deptD = '?';
}
$word->setValue('deptA', $deptA);
$word->setValue('deptBP', $deptBP);
$word->setValue('deptB', $deptB);
$word->setValue('deptC', $deptC);
$word->setValue('deptD', $deptD);
// 設(shè)置其它替換
// ...
// 生成臨時文件以供下載
$tmpFileName = md5( time().'Heier' );
$word->save($personBasePath . '/' . $tmpFileName .'.docx');
$file = $personBasePath . '/' . $tmpFileName .'.docx';
// 下載Word文件
ob_start(); //打開緩沖區(qū)
$fp = fopen($file,"r");
$file_size = filesize($file);
$downFileName = 'XXX.docx';
header("Cache-Control: public");
header("Content-type: application/octet-stream");
header("Accept-Ranges: bytes");
header("Content-Disposition: attachment; filename={$downFileName}");
header("Pragma:no-cache");
header("Expires:0");
$buffer = 1024;
$file_count = 0;
//向瀏覽輸出回數(shù)據(jù)
while(!feof($fp) && $file_count < $file_size){
$file_con = fread($fp,$buffer);
$file_count += $buffer;
echo $file_con;
}
ob_end_flush();//輸出全部內(nèi)容到瀏覽器
}
參考文檔匯總
關(guān)于我
總結(jié)
以上是生活随笔為你收集整理的php 模板替换,使用PHPWord对Word文件做模板替换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网易云音乐加了Hi网易云音乐加到视频
- 下一篇: mac php mcrypt,MacOS