phpword 使用TemplateProcessor方式实现在word模板中动态插入表格
发表于:2025-02-19 00:38:07浏览:51次
为了使用PHPWord
的TemplateProcessor
类读取一个 Word 模板,并在模板中指定的 ${TABLE} 标记位置插入一个新的表格,我们可以按照以下步骤操作。这个过程包括加载模板、创建表格,然后通过 setComplexBlock 方法将表格插入到指定标记位置。下面是一个具体的示例代码,展示了如何实现这一点:
首先,请确保你已经通过 Composer 安装了 PHPWord 库。
composer require phpoffice/phpword
php代码如下:
use PhpOffice\PhpWord\TemplateProcessor;
use PhpOffice\PhpWord\Element\Table;
use PhpOffice\PhpWord\Style\Cell;
public function contract_word($id)
{
$detail = Db::name('Contract')->where('id', $id)->find();
$detail['subject_title'] = Db::name('Enterprise')->where(['id' => $detail['subject_id']])->value('title');
$detail['yi_address'] = Db::name('Enterprise')->where(['id' => $detail['subject_id']])->value('tax_address');
$detail['yi_bank'] = Db::name('Enterprise')->where(['id' => $detail['subject_id']])->value('tax_bank');
$detail['yi_banksn'] = Db::name('Enterprise')->where(['id' => $detail['subject_id']])->value('tax_banksn');
$detail['jia_address'] = Db::name('Customer')->where(['id' => $detail['customer_id']])->value('tax_address');
$detail['jia_bank'] = Db::name('Customer')->where(['id' => $detail['customer_id']])->value('tax_bank');
$detail['jia_banksn'] = Db::name('Customer')->where(['id' => $detail['customer_id']])->value('tax_banksn');
$filename = $detail['name']."_简版_销售合同.docx";
// 导出word文件路径+文件名
$path = CMS_ROOT . "public/storage/word/".$filename;
// 模板文件路径+文件名
$templatePath = CMS_ROOT . "public/static/home/file/contract1.docx";
$tmp = new TemplateProcessor($templatePath);
// 准备要插入表格的数据
$rows = [
['产品名称', '规格', '单位', '数量', '含税单(元/KG)', '不含税总金额(元)', '含税总金额(元)'],
];
$list = unserialize($detail['content']);
$product_num=0;
foreach ($list as $key => $value) {
$rows[]=[$value['product_title'],$value['product_specs'],$value['product_unit'],$value['product_num'],$value['product_price'],$value['product_subnotax'],$value['product_subtotal']];
$product_num+=$value['product_num'];
}
$rows[]=['合计','','','','','',$detail['cost']];
// 获取页面宽度(以 twips 为单位),假设使用 A4 纸张大小和默认页边距
$pageWidthTwips = 8500;
$columnWidthTwips = [1300,1000,800,1100,1300,1500,1500];
// 创建表格
$table = new Table(['unit' => \PhpOffice\PhpWord\SimpleType\TblWidth::TWIP, 'width' => $pageWidthTwips]);
//单元格属性
$borderSize = 6; // 边框粗细
$borderColor = '000000'; // 黑色边框颜色
$cellStyle = [
'borderTopSize' => $borderSize, 'borderTopColor' => $borderColor,
'borderBottomSize' => $borderSize, 'borderBottomColor' => $borderColor,
'borderLeftSize' => $borderSize, 'borderLeftColor' => $borderColor,
'borderRightSize' => $borderSize, 'borderRightColor' => $borderColor,
'valign' => 'center', // 垂直居中
'unit' => \PhpOffice\PhpWord\SimpleType\TblWidth::TWIP,
];
$textStyle = ['name' => '黑体', 'size' => 10.5]; // 设置字体为黑体
foreach ($rows as $index => $rowData) {
$tableRow = $table->addRow();
foreach ($rowData as $key => $cellData) {
$cellStyle['gridSpan'] = 1;
$cellStyle['width'] = $columnWidthTwips[$key];
// 创建带有样式的单元格并添加文本
$tableCell = $tableRow->addCell(null, $cellStyle); // 使用上面定义的宽度
$tableCell->addText($cellData, $textStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
}
}
$cny = cny($detail['cost']);
$tableRow = $table->addRow();
$cellStyle['gridSpan'] = 1;
$cellStyle['width'] = 1300;
$mergedCell = $tableRow->addCell(null, $cellStyle);
$mergedCell->addText('大写合计', $textStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
$cellStyle['gridSpan'] = 6;
$cellStyle['width'] = 7200;
$mergedCell = $tableRow->addCell(null, $cellStyle);
$mergedCell->addText($cny, $textStyle, ['alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
// 使用 setComplexBlock 方法替换 ${TABLE} 标签为生成的表格
$tmp->setComplexBlock('${TABLE}', $table);
$tmp->setValue('START', date('Y年m月d日', $detail['start_time']));
$tmp->setValue('END', date('Y年m月d日', $detail['end_time']));
$tmp->setValue('SIGN', date('Y年m月d日', $detail['sign_time']));
$tmp->setValue('TAX', $detail['tax']);
$tmp->setValue('JIA', $detail['customer']);
$tmp->setValue('JIA_ADDRESS', $detail['jia_address']);
$tmp->setValue('JIA_BANK', $detail['jia_bank']);
$tmp->setValue('JIA_BANKSN', $detail['jia_banksn']);
$tmp->setValue('YI', $detail['subject_title']);
$tmp->setValue('YI_ADDRESS', $detail['yi_address']);
$tmp->setValue('YI_BANK', $detail['yi_bank']);
$tmp->setValue('YI_BANKSN', $detail['yi_banksn']);
$tmp->setValue('CODE', $detail['code']);
$tmp->saveAs($path);
//下载文件
if (is_file($path)){
$file = fopen($path, "rb");
Header( "Content-type: application/octet-stream ");
Header( "Accept-Ranges: bytes ");
Header( "Content-Disposition: attachment; filename= $filename");
while (!feof($file)) {
echo fread($file, 8192);
ob_flush();
flush();
}
fclose($file);
} else {
return to_assign(1,"文件生成失败");
}
}
关键点解释:
- TemplateProcessor: 用于处理Word文档模板,允许你用动态内容替换占位符。
- Table: 创建一个新的表格对象,并根据需要填充数据。
- setComplexBlock: 这个方法用于替换模板中的复杂块(如表格)。你需要提供占位符名称(如${TABLE})和要插入的对象(如新创建的表格)。