Dompdf库html生成pdf时editor编辑器中文本长度被截断不会自动换行问题处理

Dompdf 生成 PDF 时,编辑器文本(如富文本编辑器内容)出现长度截断、不自动换行的问题,核心原因是 CSS 换行规则未生效文本中存在连续无空格字符(如长数字、英文单词、特殊符号),导致 Dompdf 无法识别换行边界。

试过替换样式文件等多种方式,然而都不能较好的解决,查阅文档发现其实是Dompdf类库本身对html支持就比较弱,因此考虑换了对html支持较好的mpdf类库,问题解决。

一、mPDF类库(专注 HTML 转 PDF,中文优化)

mPDF 专为 HTML 转 PDF 设计,对 CSS 样式的支持度优于 Dompdf,尤其在中文换行、字体渲染上做了针对性优化,配置简单。

1. 安装方式

通过 Composer 安装:

复制代码
composer require mpdf/mpdf
2. 核心优势
  • 对中文换行、字符边界识别更精准,无需额外添加零宽空格。
  • 支持 CSS 浮动、Flex 布局、背景图等复杂样式。
  • 内置多种中文字体(如 simheisimsun),开箱即用。
  • 内存占用比 TCPDF 低,生成速度快。
3. 适配合同 PDF 生成示例
复制代码
use Mpdf\Mpdf;

function test_html_to_pdf_mpdf($html, $filename = 'document.pdf', $type = 'I')
{
    // 1. 初始化 mPDF 实例(A4 纸,边距 19mm)
    $mpdf = new Mpdf([
        'mode' => 'utf-8',
        'format' => 'A4',
        'margin_left' => 19,
        'margin_right' => 19,
        'margin_top' => 19,
        'margin_bottom' => 20,
        'margin_header' => 0,
        'margin_footer' => 0,
        'default_font' => 'simsun' // 直接使用内置宋体
    ]);
    
    // 2. 加载 HTML 内容
    $mpdf->WriteHTML($html);
    
    // 3. 输出 PDF(对应原逻辑的类型)
    switch (strtoupper($type)) {
        case 'I': // 直接预览
            $mpdf->Output($filename, 'I');
            break;
        case 'F': // 保存到本地
            $mpdf->Output($filename, 'F');
            echo file_get_contents($filename);
            break;
        case 'D': // 直接下载
            $mpdf->Output($filename, 'D');
            break;
        default: // 返回文件流
            $pdfContent = $mpdf->Output('', 'S');
            return base64_encode($pdfContent);
    }
    exit;
}

// 调用函数(使用原 HTML 内容,连字符已替换为非断字版本)
$html = '
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <style>
        body { font-family: simsun; line-height: 1.5; }
        p { margin: 0 0 1em 0; hyphens: none; }
        .title { text-align: center; font-weight: bold; font-size: 16px; }
    </style>
</head>
<body>
    <p class="title">框架合同-个人代理专用</p>
    <p>甲方:</p>
    <p>甲方电话:15701234567</p>
    <p><br/></p>
    <p>乙方:/p>
    <p>乙方电话:15701234561</p>
    <p><br/></p>
    <p>第一条:这是个人代理合同模板,这是个人代理合同模板这是个人代理合同模板这是个人代理合同模板这是个人代理合同模板这是个人代理合同模板这是个人代理合同模板这是个人代理合同模板这是个人代理合同模板</p>
    <p><br/></p>
    <p>这个文件是为了测试协议内容的-test,这个文件是为了测试协议内容的,这个文件是为了测试协议内容的</p>
    <p><br/></p>
    <p>甲方签字:</p>
    <p><br/></p>
    <p>乙方签字:</p>
</body>
</html>';

test_html_to_pdf_mpdf($html, 'hetong_test_mpdf.pdf', 'I');
4. 关键注意事项
  • mPDF 内置 simsun(宋体)、simhei(黑体)等中文字体,无需手动配置字体路径,解决了 Dompdf 的字体兼容问题。
  • hyphens: none 样式支持完整,即使不替换连字符,也可通过 CSS 禁用断字(建议仍替换为非断字连字符以确保兼容)。
  • 支持 HTML5 语义化标签(如 <header><footer>),迁移成本低。

二、增加字体:simsun

由于我之前用dompdf生成pdf时使用的simsun字体,为了兼容旧的模板文件,需要在mPDF类库中安装 simsun(宋体)字体,通过 "字体字体文件准备→注册字体→配置使用(见具体代码)" 三个步骤,确保字体能被正确识别并应用于 PDF 生成,具体操作如下:

1、准备 simsun 字体文件

1.1) 可从网络下载simsun.ttf字体文件

1.2) 上传字体到项目目录在项目中创建一个存放自定义字体的目录(避免放在 vendor 目录,防止 Composer 更新覆盖),例如:

复制代码
/www/wwwroot/myweb/storage/fonts/  # 项目内的字体目录

simsun.ttf 上传到该目录。

2、在 mPDF 中注册 simsun 字体

mPDF 需要通过代码注册自定义字体,告知字体文件路径、名称及样式(常规、粗体等),步骤如下:

2.1)初始化 mPDF 时配置字体目录

在生成 PDF 的代码中,通过 fontDir 参数指定自定义字体目录,让 mPDF 能找到 simsun 字体文件:

复制代码
use Mpdf\Mpdf;
use Mpdf\Config\FontVariables;
use Mpdf\Font\FontData;

function test_html_to_pdf_mpdf($html, $filename = 'hetong_test_mpdf.pdf', $type = 'I')
{
    // 1. 配置自定义字体目录(存放 simsun.ttc 或 simsun.ttf 的路径)
    $fontDir = [
        __DIR__ . '/../../storage/fonts/', // 项目自定义字体目录(根据实际路径调整)
        // 保留 mPDF 内置字体目录(可选)
        __DIR__ . '/../../vendor/mpdf/mpdf/ttfonts/'
    ];

    // 2. 注册 simsun 字体(关键步骤)
    $defaultFontConfig = (new FontVariables())->getDefaults();
    $fontData = $defaultFontConfig['fontdata'];
    // 扩展字体数据,添加 simsun 配置
    $fontData['simsun'] = [ // 字体名称(后续 CSS 中使用)
        'R' => 'simsun.ttc', // 常规(Regular)字体文件(若为 ttf 则写 simsun.ttf)
        'useOTL' => 0xFF, // 启用 OpenType 特性(支持中文)
        'useKashida' => 75,
    ];
    // 若有粗体变体,可添加 'B' => 'simsunb.ttf'

    // 3. 初始化 mPDF,应用字体配置
    $mpdf = new Mpdf([
        'mode' => 'utf-8',
        'format' => 'A4',
        'margin_left' => 19,
        'margin_right' => 19,
        'margin_top' => 19,
        'margin_bottom' => 20,
        'fontDir' => $fontDir, // 自定义字体目录
        'fontdata' => $fontData, // 注册的字体数据
        'default_font' => 'simsun', // 设置 simsun 为默认字体
        'tempDir' => __DIR__ . '/../../storage/mpdf-tmp' // 自定义临时目录(避免权限问题)
    ]);

    // 4. 处理 HTML 并生成 PDF
    $html = mb_convert_encoding($html, 'UTF-8', 'GBK,UTF-8');
    $mpdf->WriteHTML($html);

    // 输出逻辑...
    switch (strtoupper($type)) {
        case 'I': $mpdf->Output($filename, 'I'); break;
        case 'F': $mpdf->Output($filename, 'F'); echo file_get_contents($filename); break;
        case 'D': $mpdf->Output($filename, 'D'); break;
        default: $pdfContent = $mpdf->Output('', 'S'); return base64_encode($pdfContent);
    }
    exit;
}
2.2)关键配置说明
  • fontDir:数组形式,可同时指定多个字体目录(自定义目录 + 内置目录),确保 mPDF 能找到所有字体文件。
  • fontdata 中的 'simsun':字体名称,后续在 CSS 中通过 font-family: simsun; 引用。
  • 'R' => 'simsun.ttc'R 表示常规样式,值为字体文件的实际名称(需与 fontDir 目录中的文件名一致)。
  • useOTLuseKashida:启用 OpenType 布局特性,确保中文排版正常(避免字符重叠、乱码)。

三、类库对比与选择建议

特性 TCPDF mPDF Dompdf(原类库)
HTML 兼容性 高(支持 HTML5/CSS3) 高(专注 HTML 转 PDF) 中(基础标签支持)
中文处理 内置字体,稳定 中文优化,换行精准 需手动配置字体,易出问题
连字符换行控制 支持非断字连字符,稳定 支持 CSS 禁用断字 + 字符替换 兼容差,hyphens 失效
生成速度
内存占用 较高
高级功能(水印 / 加密) 支持 支持 基础支持
相关推荐
农场主John6 小时前
vscode断点使用
ide·vscode·编辑器
Caesar Zou6 小时前
解决 Codex 在 WSL/SSH/VSCODE 登录时报 “Token exchange failed: 403 Forbidden” 问题
ide·vscode·编辑器
「QT(C++)开发工程师」8 小时前
【LUA教程】LUA脚本语言中文教程.PDF
开发语言·pdf·lua
苏琢玉9 小时前
收藏版:Phinx 数据库迁移完全指南
数据库·mysql·php
我命由我1234512 小时前
PDFBox - PDF 页面坐标系、PDF 页面尺寸获取、PDF 页面位置计算
java·服务器·开发语言·笔记·后端·java-ee·pdf
m0_7482402513 小时前
C++仿Muduo库Server服务器模块实现 基于Reactor模式的高性
服务器·c++·php
坐吃山猪16 小时前
第2章-类加载子系统
开发语言·php
寺中人18 小时前
Resource Hacker:强大的软件资源编辑器
编辑器·软件·resource hacker·汉化版·资源编辑器
JaguarJack18 小时前
2025 年必须尝试的 5 个 Laravel 新特性
后端·php·laravel