php 生成PDF过程笔记mpdf

经过一路的测试和刷选,后来选择mpdf,支持中文字体和自定义字体,但这东西不支持tfoot,虽然也是有点痛苦,总算了解了他的使用方法,算是皮毛吧,也够用了就是。

tcpdf 支持中文字体

dompdf 支持css和样式,H5

anam-hossain/phantommagick 好用,HTML转PDF,但是需要安装phantomjs

https://github.com/anam-hossain/phantommagick

spatie/browsershot 依赖Puppeteer 好用,HTML转PDF

html2pdf 这个不会自动换行,支持中文,支持tfoot,少部分css样式

https://github.com/spipu/html2pdf

着重讲mpdf,下面是开源地址

https://github.com/mpdf/mpdf

使用文档

https://mpdf.github.io/

安装简单

composer require mpdf/mpdf

接着引入,一个简单的示例

<?php
require_once __DIR__ . '/vendor/autoload.php';

$mpdf = new \Mpdf\Mpdf();
$mpdf->WriteHTML('<h1>Hello world!</h1>');
$mpdf->Output();

复杂点的选择

require ROOT_PATH.'/vendor/autoload.php';
$tempDir = __DIR__.'/Cache/tmp';
if(!is_dir($tempDir)){    
    mkdir($tempDir,0777,true);
};
$mpdf = new \Mpdf\Mpdf([
'mode' => 'utf-8',
//'format' => 'A4-L', //横向A4
'debug' => true,
//'tabSpaces' => 4,
//'ignore_invalid_utf8' => true,
'orientation' => 'L', //横向
"autoScriptToLang"=>true, //自动适配语言(支持中文)
"autoLangToFont"=>true, //自动选字体
"default_font_size"=>10, //默认字号px
"default_font"=>'simsun', //自定义字体,这个后面讲解
//"tempDir"=>$tempDir, //缓存目录
'margin_top' => 0, //上边距
'margin_left' => 7, //左边距
'margin_right' => 7, //右边距
//'mirrorMargins' => true,
"setAutoTopMargin"=>"stretch", //自动适应顶边距
//"setAutoBottomMargin"=>"stretch",
"autoMarginPadding"=>0 //边距和pad
]);
//$mpdf->default_font='STFangsong'; //courier SimHei

$mpdf->defaultheaderline = 0; //删除header底线
$mpdf->defaultfooterline = 0; //删除footer顶线

上面提到的字体,首先 把ttf字体放在

/vendor/mpdf/mpdf/ttfonts

目录里面,然后编辑文件 /vendor/mpdf/mpdf/src/Config/FontVariables.php

找到 'fontdata' => [] 区域,把自己的字体放在里面,以宋体等几个字体为例,添加配置如下:

"simsun" => [
	'R' => "simsun.ttf", //宋体
],
"simhei" => [
	'R' => "simhei.ttf", //黑体
],
"stsongstdlight" => [
	'R' => "STSongStdLight.ttf", //据说中文
],
"droidsansfallback" => [
	'R' => "DroidSansFallback.ttf", //安卓专用中文字体
],
"华文黑体" => [
	'R' => "华文黑体.ttf",
],
"华文宋体" => [
	'R' => "华文宋体.ttf",
],

你看见里面有一个sun-exta字体配置吧,那个是mpdf默认的中文字体。

这样你在pdf文档的html代码里面就可以css定义font-family:simsun即可

或者像上面那样"default_font"=>'simsun'指定自定义的字体,或者mpdf自带字体,比如sun-exta

接着说下内容组织方面,这功能太多了,不好全面描述。

样式表css代码

$csscode=<<<EOD
<style type="text/css">
*{

}
.pdftable table{
    display:table;
    table-layout: fixed;
    border:0px;
    margin:0px;
    border-collapse:collapse;
    border-spacing:0;
    width: 100%;
}
.pdftable table, td, th
{
    border:1px solid black;
}
.pdftable tr{
    width: 100%;
}
</style>
EOD;
$mpdf->WriteHTML($csscode,\Mpdf\HTMLParserMode::HEADER_CSS); //写样式

每页重复出现的头部

$headhtml=<<<EOD
<div style="width:100%;" class="pdfhead">
    <table style="width: 100%;">
    <tr>
    <td style="border:1px; text-align: center;width:100%;font-size: 23px;font-family:simhei">
    我是一个大标题
    </td>
    </tr>
    </table>
    <br /><br /><br />
    <table style="width: 100%; border:0;border-spacing:0;border-collapse:collapse;">
      <tr>
        <td style="border:0px; text-align: right; width: 10%">我是文档:</td>
        <td style="border:0px; text-align: left; width: 70.5%"> 001</td>
        <td style="border:0px; text-align: left; width: 19.5%">第  {PAGENO}  页,共  {nbpg}  页</td>
      </tr>
    </table>
</div>
EOD;
$mpdf->SetHTMLHeader($headhtml); //写入头

接着内容不用我多说了吧,爱怎么组织都行,这里看个表格吧。

其中thead,每个分页,表格头都会重复出现的

$htmlcode=<<<EOD
<div style="width:100%;" class="pdftable">
<table style="width:100%;">
<thead>
  <tr style="width:100%;">
    <th rowspan="2" style="width: 16mm">序号</th>
    <th rowspan="2" style="width: 48.3mm">工号</th>
    <th rowspan="2" style="width: 22.1mm">姓名</th>
    <th rowspan="2" style="width: 20.4mm">绩效</th>
    <th rowspan="2" style="width: 21.1mm">底薪</th>
    <th colspan="2" style="width: 43.1mm">分类</th>
    <th rowspan="2" style="width: 17.7mm">总计</th>
  </tr>
  <tr>
    <th style="border-left:0;width: 21.5mm">夜班</th>
    <th style="border-left:0;width: 21.5mm">双休</th>
  </tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>007</td>
<td>张同学</td>
<td>5000</td>
<td>5000</td>
<td>2000</td>
<td>1500</td>
<td>13500</td>
</tr>
<tr><td colspan="8" style="text-align:left;border:0;width:100%;">我是底座</td></tr>
</tbody>
</table>
</div>
EOD;
$mpdf->WriteHTML($htmlcode,\Mpdf\HTMLParserMode::HTML_BODY); //写内容

最后应该就是尾巴,说累了,就简单点吧。

$mpdf->SetHTMLFooter('<div>我是小尾巴</div>');

其它一些特异功能也是有的。

文字水印

$mpdf->watermark_font='simsun';
$mpdf->SetWatermarkText('每页水印',0.1);
$mpdf->showWatermarkText = true;

图片水印(用于盖章或者你公司的LOGO之类,总之酷毕了)

$mpdf->SetWatermarkImage('/test.png', 1, array(60,60), array(75,3)); 
//分别为图片路径、未知、宽高、坐标XY
$mpdf->showWatermarkImage = true; 

其它特异功能不一一介绍,用到再描述

最后,输出到浏览器或者生成下载。

$mpdf->output(); //只输出到浏览器
$mpdf->output('document.pdf','D'); //下载

简单吧

附自定义字体方法二

//自定义字体目录和字体定义

$defaultConfig = (new Mpdf\Config\ConfigVariables())->getDefaults();
$fontDirs = $defaultConfig['fontDir'];

$defaultFontConfig = (new Mpdf\Config\FontVariables())->getDefaults();
$fontData = $defaultFontConfig['fontdata'];

$mpdf = new \Mpdf\Mpdf([
    'fontDir' => array_merge($fontDirs, [
        __DIR__ . '/custom/font/directory',
    ]),
    'fontdata' => $fontData + [
        'frutiger' => [
            'R' => 'Frutiger-Normal.ttf',
            'I' => 'FrutigerObl-Normal.ttf',
        ]
    ],
    'default_font' => 'frutiger'
]);

附二,自定义输出

function myMpdfOutput($mpdf, $name)
{
	if ($mpdf->state < 3)
		$mpdf->Close();

	$numpages = $mpdf->docPageNumTotal();

	//We send to a browser
	header('Content-Type: application/pdf');
	if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
		// don't use length if server using compression
		header('Content-Length: ' . strlen($this->buffer));
	}
	header('Content-disposition: inline; filename="' . $name . '"');
	header('Cache-Control: public, must-revalidate, max-age=0');
	header('Pragma: public');
	header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
	header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');

	echo str_replace('{nbpg}', $numpages, $mpdf->buffer);
}
点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注