PHP调用passthru执行pdftk填充PDF时中日Unicode字符乱码如何解决?
问题根因
你遇到的乱码是典型的UTF-8字符被错误识别为Latin-1单字节编码的问题,核心原因有两个:
- FDF 1.2 格式默认仅支持ASCII编码,直接写入UTF-8格式的中日文字符,会被pdftk按单字节编码解析,最终显示乱码
- PDF模板的表单域默认字体未配置中日文字形,即使编码正确也可能显示为空白或方块
具体解决步骤
步骤1:调整FDF文件的Unicode编码格式
FDF默认不直接支持UTF-8编码的Unicode字符,有两种处理方案:
- 手动转换:将需要写入的中、日文字符串转为带BOM头的UTF-16BE编码,再转为十六进制格式,字段值用尖括号
<>包裹而非括号()。示例转换代码:
function str2fdf_unicode(string $utf8Str): string { // 增加UTF-16BE BOM头,再转编码 $utf16beStr = "\xFE\xFF" . mb_convert_encoding($utf8Str, 'UTF-16BE', 'UTF-8'); // 转为十六进制字符串 return bin2hex($utf16beStr); } // 调用示例,原/V (中文内容) 修改为: // /V <<?php echo str2fdf_unicode('Chinese : 这是一个测试文本'); ?>>
- 扩展生成:如果使用PHP内置FDF扩展生成FDF文件,调用
fdf_set_value()时将最后一个参数设为1,即可自动处理Unicode编码,无需手动转换:
$fdf = fdf_create(); fdf_set_value($fdf, 'input_name', 'Chinese : 这是一个测试文本', 1); // 其他字段设置省略 fdf_save($fdf, $fdf_fn); fdf_close($fdf);
步骤2:配置PDF模板表单域字体
PDF模板的表单域默认字体通常没有中日文字形,即使编码正确也会显示异常:
- 用Adobe Acrobat等PDF编辑工具打开模板文件
- 选中所有需要填充中日文字符的表单域,将默认字体设置为思源黑体、微软雅黑、宋体等支持中日文的字体
- 保存模板时勾选「嵌入所有字体」选项,避免渲染时缺失字形
步骤3:调整pdftk执行参数
部分旧版本pdftk的参数顺序会影响渲染结果,建议将flatten参数放在命令末尾,示例:
passthru("pdftk $abs_pdf_path fill_form $fdf_fn output $certFileName owner_pw foopass allow DegradedPrinting flatten");
验证方法
完成上述调整后重新生成FDF文件,再执行填充命令,中日文字符即可正常显示。
内容的提问来源于stack exchange,提问作者Anuja Nair
相关产品推荐
相关产品推荐

