dompdf中文乱码、换行解决方案

前言

  因为工作需要,需要使用PHP生成PDF,开始接触dompdf这个类库,dompdf可以把HTML文件生成PDF。

  无奈使用的过程中遇到很多坑,细数dompdf的一些坑,中文乱码,中文换行,页面设置问题,生成文档,无奈还是使用,只能硬着头皮去找解决方案,网上许多方法只讲了一部分,没有发现一个好完整的解决方案,大多是随意复制粘贴,或者答非所问。

  最后自己东拼西凑,终于整理出完整的解决方案,今天就记录下这些坑的解决方案,以免以后又踩坑,不废话直接进入正题。


使用环境

  0、版本不同,可能会导致解决方案行不通,故记录使用环境。
  1、Apache/2.4.33 (Win64) PHP/5.6.35
  2、ThinkPHP5.0.21
  3、dompdf v0.8.2


安装dompdf

  1、使用命令行进入到项目根目录

	cd C:\wamp64\www\tp5

  2、使用composer安装dompdf

	composer require dompdf/dompdf

  3、检查是否安装成功,在C:\wamp64\www\tp5\vendor看是否有dompdf文件夹。


使用dompdf

  0、因为dompdf有许多中文的坑,刚开始最好不要使用中文测试,免得心情糟糕。

  1、引入Dompdf

	use Dompdf\Dompdf;

   2、获得HTML内容、相对于项目入口的目录

	$html = file_get_contents('templates/1.html');

   3、加载html

	$dompdf->loadHtml($html);

   4、设置页面属性 A4的纸张,

	$dompdf->setPaper('A4', 'portrait');

   5、渲染PDF

	$dompdf->render();

   6、在浏览器中下载,这行代码会自动在浏览器中下载

	$dompdf->stream();

中文乱码问题

   0、重点来了,相信这个问题不解决,大家也不会再考虑使用这个类库,一堆乱码看着简直心情糟糕透了。

   1、下载类库语言安装脚本
    https://github.com/dompdf/utils.git

  2、将里面的load_font.php文件拷贝到项目根目录,和verdor同级
    目录:C:\wamp64\www\tp5

  3、下载一个宋体字体 simsun.ttf,也放到项目根目录,这时load_font.php和simsun.ttf应该在同一级目录
    目录:C:\wamp64\www\tp5

  4、开始安装字体,使用命令行进入当前目录,并安装字体

	cd C:\wamp64\www\tp5
	php load_font.php simsun.ttf simsun

  命令说明 php load_font.php 调用这个文件,并传入字体路径,字体名字
  注意这一步,最后的simsun最好不要添加引号,看有一些例子写了引号,导致后面声明字体使用不上。

  5、安装结果图,显示这些东西基本就完成字体安装。
安装完成后结果图

  6、去类库字体目录检查是否安装成功
    C:\wamp64\www\tp5\vendor\dompdf\dompdf\lib\fonts
    找到是否有simsun.ttf和simsun.ufm2个文件

  7、一般来说到上一步就安装成功,不放心可以进行终极检查
    进入到这个目录:C:\wamp64\www\tp5\vendor\dompdf\dompdf\lib\fonts
    找到这个文件:dompdf_font_family_cache.php
    看下是否有以下这段,没有就添加上,有就最好。

	  'simsun' => array(
	    'normal' => $fontDir . '/simsun',
	    'bold' => $fontDir . '/simsun',
	    'italic' => $fontDir . '/simsun',
	    'bold_italic' => $fontDir . '/simsun',
	  )

  8、在HTML中使用我们安装的字体,你可以在这个HTML任何地方写这个字体样式,不过为了全文显示正常最好还是在这写。

	<body style="font-family:simsun">中文字体</body>

  这样我们就可以愉快的使用中文字体了。


中文换行问题

  0、当我开心解决了中文乱码问题之后,又发现了换行问题,中文不会换行,在网上找到寻找到了解决方案不过有点出入,版本不一样的问题。

  1、寻找到Text.php文件
    我的目录:C:\wamp64\www\tp5\vendor\dompdf\dompdf\src\FrameReflower\Text.php

  2、找到相关代码

// split the text into words
	$words = preg_split('/([\s-]+)/u', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
    $wc = count($words);

  3、替换以上代码,或者注释掉以上代码,添加我们的代码。

	preg_match_all("/./u", $text, $array);
    $words = array(0);
    $wc = count($words);

  4、小提示,可能因为版本的变迁,文件、代码位置不一样,大家最好使用目录全文搜索那一段代码,而不是直接去找那个文件。


页面设置问题

  0、不知道什么原因,网上大多的例子都是横向设置,我还纠结半天什么鬼,内容在一个页面显示不了分了好几页,只能说英文不好容易踩坑。

  1、设置页面

  	//网上你可能看到很多这样的例子,我要竖着的看啊,坑。
	$dompdf->setPaper('A4', 'landscape');

	//找了类库说明,发现还有一个参数,这下终于可以正常显示了。
	$dompdf->setPaper('A4', 'portrait');

  2、为了更好将HTML转换成PDF,建议将HTML宽高设置成和A4大小接近,避免不必要的麻烦。个人还是要根据实际pdf显示情况来调节。

    body {
        margin: 0;
        width: 820px;
       	height: 1160px;
    }

PDF生成问题

  0、又解决了一个问题,这下真的万事大吉了嘛,nono,dompdf目前还是存在样式问题,没有得到很好的解决,所以这点需要的注意。

  1、对元素浮动支持不是很友好。float

  2、目前不支持css3的属性,所以不要奢望做出很复杂的样式。


自定义注入变量方法

  0、为什么要注入变量,直接使用TP5里的注入方法不就可以了?我们是直接读取模板文件,而不通过页面渲染出来,所以我自己写个方法,用来向HTML中注入一些变量。有很多方法可以实现,有兴趣大家慢慢探索。

  1、批量生成pdf如果需要头尾模板分离的话,可以使用HTML拼接的方式。

	$html = file_get_contents('public/letters/templates/html/header.html');
	$html .= file_get_contents($path);
	$html .= file_get_contents('public/letters/templates/html/footer.html');

2、HTML模板按照以下方式写要替换的变量,代表要替换的变量。

	{test}

3、变量注入方法,将模板和所有的变量传入这个方法,返回一个新的模板。

   	/**
     * 轻量级变量注入方法、可以自行完善
     */
    public function inject($html,$common)
    {
        //匹配模式
        $pattern = '/\{([\w]+)\}/';

        //捕获所有的模板变量
        preg_match_all($pattern,$html,$matches);

        //变量替换
        for($i=0;$i<count($matches[1]);$i++){
            if(isset($common[$matches[1][$i]])){
                $html = preg_replace('/\{'.$matches[1][$i].'\}/',$common[$matches[1][$i]],$html);
            }
        }
        return $html;
    }

4、完整例子代码:

	 	//模板路径
       $path = 'public/templates/1.html';

       //文件生成路径
       $filePath='public/pdf/test.pdf';

       //声明一个DomPDF对象
       $dompdf = new Dompdf();

       //HTML组合
       $html = file_get_contents('public/templates/html/header.html');
       //中间需要替换的部分
       $html .= file_get_contents($path);

       $html .= file_get_contents('public/templates/html/footer.html');

       //注入的变量
       $data['test'] = 'test';

       //HTML注入变量
       $html = $this->inject($html,$data);

       //加载HTML内容
       $dompdf->loadHtml($html);

       //设置PDF纸张、方向 portrait、landscape
       $dompdf->setPaper('A4', 'portrait');

       // 渲染pdf
       $dompdf->render();

       //生成一个pdf文件
       file_put_contents($filePath,$dompdf->output());

结语

  以上是我最近折腾dompdf的完整经历,从一个问题到一个问题,还好最终都一一解决了。

  很多问题也不能只靠网上百度,也要学会自己思考,阅读源代码结合自己一些编程经验找到解决方案。

  这也是本人第一篇比较长分享文章了,希望能帮助同样使用这个类库的人。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值