
如何在 mpdf 中正确显示 html 复选标记(✓)符号:mpdf 6.0 默认无法正确解析经典 asp 提交的 `%u2714` 类 url 编码 unicode 字符,导致复选标记显示为乱码;需在 php 端将 `%uxxxx` 转换为标准 html 实体 `xxxx;` 并解码为 utf-8。
在使用 mPDF(v6.0)将 Classic ASP 生成的 HTML 表格导出为 PDF 时,✔(即 ✓)在浏览器中正常渲染,但在 PDF 中却显示为 %u2714 —— 这并非字体缺失问题,而是 字符编码传输失真所致。
根本原因在于:Classic ASP 在通过 POST 提交 HTML 字符串时,若服务器或客户端编码配置不一致(如未显式声明 UTF-8),某些浏览器/环境会将 Unicode 字符(如 ✓)自动转义为非标准的 %u2714 格式(类似 JavaScript 的 escape() 输出),而 mPDF 的 WriteHTML() 并不原生识别该格式,仅支持标准 HTML 实体(✔ 或 ✔)及 UTF-8 原生字节流。
✅ 推荐解决方案:标准化 Unicode 编码
在 PHP 接收 $output = $_POST["output"] 后,立即执行标准化处理,无需依赖额外字体(即使已配置 Symbola.ttf):
// 方案一:精准修复复选标记(快速验证用)
$output = str_replace('%u2714', '✔', $output);
// 方案二:通用化处理所有 %uXXXX 编码(生产环境推荐)
$output = preg_replace('/%u([0-9A-F]{4})/', '$1;', $output); // 转为十六进制实体
$output = html_entity_decode($output, ENT_COMPAT, 'UTF-8'); // 解码为 UTF-8 字节流⚠️ 注意:preg_replace 中正则 ([0-9A-F]{4}) 限定 4 位十六进制,确保匹配合法 Unicode 码点(如 2714),避免误替换。html_entity_decode(..., 'UTF-8') 是关键——它将 ✔ 实体真正转换为 UTF-8 编码的 ✓ 字节,mPDF 才能正确渲染。
✅ 配合优化:确保 mPDF 正确加载 UTF-8 内容
在初始化 mPDF 时,确认以下设置已启用(你当前代码基本正确,但建议显式强化):
立即学习“前端免费学习笔记(深入)”;
$mpdf = new \mPDF([
'mode' => 'utf-8',
'format' => 'A4-L',
'margin_left' => 5,
'margin_right' => 5,
'margin_top' => 20,
'margin_bottom' => 20,
]);
$mpdf->autoScriptToLang = true;
$mpdf->autoLangToFont = true;
$mpdf->setDirectionality('ltr'); // 若无 RTL 内容,可显式设为 ltr同时,移除 HTML 中冗余的字体强制声明:
你 ASP 中
? 验证与调试技巧
- 在 PHP 中 echo htmlspecialchars($output); 查看原始 POST 内容,确认是否含 %u2714;
- 使用 mb_detect_encoding($output) 检查字符串实际编码,确保为 UTF-8;
- 若仍失败,临时添加调试 CSS 强制字体:
$style .= " .checkmark { font-family: 'dejavusans'; } "; // HTML 中:✔
✅ 总结
| 问题根源 | 解决动作 | 关键代码 |
|---|---|---|
| %u2714 非标准编码被 mPDF 忽略 | 将 %uXXXX → XXXX; → UTF-8 字节 | preg_replace() + html_entity_decode() |
| 字体声明未生效或未注册 | 移除冗余 font-family,信任 mPDF UTF-8 渲染能力 | 删除内联 style='font-family:symbola' |
| 编码链路断裂(ASP→PHP→mPDF) | 全程显式声明 UTF-8,禁用自动转换干扰 | new mPDF(['mode'=>'utf-8']) |
完成上述处理后,复选标记 ✓ 将在 PDF 中清晰、居中、无乱码地呈现,且方案兼容所有 Unicode 符号(如 ✗、★、→ 等),无需为每个符号单独替换。











