您的当前位置:首页>全部文章>文章详情

Thinkphp6使用mPdf实现生成pdf文件

发表于:2023-01-12 15:51:58浏览:79次TAG: #ThinkPHP #PHP #生成PDF文件

新项目有一个将数据导出PDF文件格式的需求,研究一段时间后发现利用PHP编码生成PDF文件是一个非常耗时的工作,还好已经有很多函数库可以使用了,并且能够从你提供的HTML文件生成PDF文档,mPDF就是一个不错的选择,mPDF能基本兼容HTML标签和CSS3样式。
1、首先需要安装依赖库。

composer require mpdf/mpdf

2、接下来编写PHP代码。
controller/Index.php

<?php
namespace app\controller;
use app\BaseController;
use Mpdf\Mpdf;

class Index extends BaseController
{
    //创建pdf文件
    public function makePdf($id) {
        //用html形式生成pdf
        $html = '<p style="text-align: center;">
         <span style="color: rgb(153, 0, 0); font-size: 15px; text-align: center;">
             <img src="https://imgs-qn.iliangcang.com/ware/slider/1775.jpg" title="191335ODA5NzgyNzMwMzAy.jpg" alt="QQ截图20200306180410.jpg"/>
             </span>
    </p>
    <p style="text-align: center;">
        <span style="color: rgb(153, 0, 0); font-size: 15px; text-align: center;">
        一年一度春节伴手礼大赛,带什么全家最开心?
        </span>
    </p>
    <p style="text-align: center;">
        <img src="http://img.baidu.com/hi/jx2/j_0034.gif"/>
        <img src="http://img.baidu.com/hi/jx2/j_0040.gif"/>
    </p>';

        //tempDir指定临时文件目录,需要有可写入的权限,否则会报错
        $pathDir = CMS_ROOT . 'public/pdf/'
        $mpdf = new Mpdf(['mode'=>'utf-8',
            'format' => 'A4',
            'tempDir' => $pathDir
        ]);
        $mpdf->SetDisplayMode('fullpage');
        //自动分析录入内容字体
        $mpdf->autoScriptToLang = true;
        $mpdf->autoLangToFont = true;
        //pdf文件存储路径
        $fileUrl = $pathDir."pdf_"$id".pdf";
        //以html为标准分析写入内容
        $mpdf->WriteHTML($html);
        //生成文件
        $mpdf->Output($fileUrl);
        //判断是否生成文件成功
        if (is_file($fileUrl)){
            return to_assign(0,"文件生成成功");
        } else {
            return to_assign(1,"文件生成失败");
        }
    }

    //下载pdf文件
    public function downPdf($id) {
        $fileUrl = CMS_ROOT . "public/pdf/pdf_"$id".pdf";
        return download($fileUrl,"文件_".$id.".pdf");
    }
}

函数使用和说明:

$mpdf = new mPDF($mode='',$format='A4',$default_font_size=0,$default_font='',$mgl=15,$mgr=15,$mgt=16,$mgb=16,$mgh=9,$mgf=9, $orientation='P');

对应的参数如下:

'format'            => 'A4',
'default_font_size' => 0,
'default_font'      => '',
'margin_left'       => 15,
'margin_right'      => 15,
'margin_top'        => 16,
'margin_bottom'     => 16,
'margin_header'     => 9,
'margin_footer'     => 9,
'orientation'       => 'P',

注意:mpdf对复杂的table布局,基本可以完全兼容,简单的div+css也可以,但是建议table。
mpdf中文乱码问题解决:
mpdf6.1以后可以用:

    $mpdf=new \mPDF('zh-cn','A4','','',32,25,27,25,16,13); $mpdf->WriteHTML("测试中文显示"); $mpdf->Output();

mpdf6.0可以用:

$this->autoLangToFont = true; 
$mpdf=new \mPDF('+aCJK','A4','','',32,25,27,25,16,13); $mpdf->WriteHTML($content); $mpdf->Output();

具体实例:

    use mPDF; //引入
    $mpdf = new mPDF('utf-8', 'A4', 16, '', 10, 10, 15, 1);
    $mpdf->SetDisplayMode('fullpage');
    $mpdf->autoScriptToLang = true;
    $mpdf->autoLangToFont = true;
    //引入样式
    $stylesheet = file_get_contents('mpdfstyletables.css');
    $mpdf->WriteHTML($stylesheet,1);

    $file = 'images/seal/150.png';
    $mpdf->WriteHTML($html, 2);
    $mpdf->Image($file, 140, 200); //追加盖章图片,貌似可以获取远程的,非必要请使用服务器本地的.
    $mpdf->Output('mpdf.pdf', 'I'); //D是下载

下面是pdf实际效果,文件在100-200K,比较小,有盖章图片会大一点,请注意网页定义的像素和pdf显示效果有差异,建议生成之后打印看实际效果。

虽然不是特别自由,但是可以满足业务人员,自由修改文字,变更合同
图片alt

对应的HTML模板代码:

<table style="border-collapse: collapse; width: 900px; height: 56px; font-family: 宋体; font-size: 18px; position: relative;">
    <tbody>
        <tr style="height:75px;text-align:center" class="firstRow">
            <td style="font-weight: bold;font-size:40px;text-align:center" colspan="8">
                购 销 合 同
            </td>
        </tr>
        <tr style="height:75px;">
            <td colspan="8"></td>
        </tr>
        <tr style="height:32px;text-align:left">
            <td style="font-weight: normal;" colspan="4">
                买方:{buyer_company_name}
            </td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal; text-align: right; word-break: break-all;">
                合同编号:
            </td>
            <td style="font-weight: normal;" colspan="2">
                {order_key}
            </td>
        </tr>
        <tr style="height:32px">
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;text-align:right">
                签订地点:
            </td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
        </tr>
        <tr style="height:32px">
            <td style="font-weight: normal;" colspan="4">
                卖方:{supply_company_name}
            </td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal; text-align: right; word-break: break-all;">
                签订时间:
            </td>
            <td style="font-weight: normal; word-break: break-all;" colspan="2">
                {current_time}
            </td>
        </tr>
        <tr style="height:32px">
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
            <td style="font-weight: normal;"></td>
        </tr>
        <tr style="height:75px;">
            <td colspan="8"></td>
        </tr>
        <tr style="height:32px;text-align:left">
            <td style="    font-weight: normal;" colspan="8">
                第一、订单号码、产品规格型号、数量、单价、金额;
            </td>
        </tr>
        <tr style="height:32px;text-align:center;font-size:14px">
            <td style="border: 1px solid #ccc;font-weight: normal; width: 13%;text-align:center;font-size:14px;">
                货物名称
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal; width: 16%;text-align:center;font-size:14px;">
                品牌
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal; width: 10%;text-align:center;font-size:14px;">
                型号规格
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal; width: 2%;text-align:center;font-size:14px;">
                单位
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;width: 9%;text-align:center;font-size:14px;">
                数量
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;width: 13%;text-align:center;font-size:14px;">
                含税单价(元)
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;width: 12%;text-align:center;font-size:14px;">
                金额(元)
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;width: 25%;text-align:center;font-size:14px;">
                备注
            </td>
        </tr>
        <tr style="height:32px;text-align:center;font-size:14px;text-align:center">
            <td style="border: 1px solid #ccc;font-weight: normal;text-align:center;font-size:14px;">
                {product_name}
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;text-align:center;font-size:14px;">
                {product_brand}
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;text-align:center;font-size:14px;">
                {product_type}
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;text-align:center;font-size:14px;">
                吨
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;text-align:center;font-size:14px;">
                {product_number}
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;text-align:center;font-size:14px;">
                {order_amount}
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;text-align:center;font-size:14px;">
                {order_amount}
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;text-align:center;font-size:14px;">
                {buyer_remark}
            </td>
        </tr>
        <tr style="height:32px;text-align:left;font-size:14px">
            <td style="border: 1px solid #ccc;font-weight: normal;font-size:14px;" colspan="5">
                合计人民币金额(大写):{order_amount_capital}
            </td>
            <td style="border: 1px solid #ccc;font-weight: normal;font-size:14px;" colspan="3">
                RMB {order_amount}
            </td>
        </tr>
        <tr style="height:75px;">
            <td colspan="8"></td>
        </tr>
        <tr style="text-align:left">
            <td style="   font-weight: normal;" colspan="8">
                <p style="margin:3px">
                    <span style="font-family:宋体">第二、交(提)货时间及地点、付款方式:                            <br/>  交(提)货 方式:买方到卖方指定仓库自提,出库费用及货权移交后的仓储费用由买方负责。                            <br/>  交(提)货时间和付款方式: 买方将全部货款于签订合同日16:30之前汇入供方指定账户,卖方收到货款后,买方可到卖方指定仓库提货。                        </span>
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style="font-weight: normal;" colspan="8">
                <p style="margin:3px">
                    <span style="font-family: 宋体">第三条、 质量、包装标准:按《中华人民共和国国家标准》的规范GB/T 470-2008或按生产厂家提供的质量保证书为准。</span>
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style="  font-weight: normal;" colspan="8">
                <p style="margin:3px">
                    <span style="font-family: 宋体">第四条、合理损耗标准及计算方法:允许合理磅差±2‰,超出合理磅差范围部分由买卖双方协商解决,交货尾差±5%,卖方提供相对应的生产厂出厂磅码单,按磅码单抄码重量结算。 </span>
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style="  font-weight: normal;" colspan="8">
                <p style="margin:3px">
                    <span style="font-family: 宋体">第五条、检验标准、方法、地点及期限:按国家标准验收。如有异议,买方须在收货七天内提出,同时买方应保存异议货品留待卖方或第三方鉴定处理。 </span>
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style="   font-weight: normal;" colspan="8">
                <p style="margin:3px">
                    <span style="font-family: 宋体">第六条、结算方式及期限:款到发货,买方应于提货前以电汇/汇票等方式支付全部货款;卖方开具17%增值税发票。</span>
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style="  font-weight: normal;" colspan="8">
                <p style="margin:3px">
                    <span style="font-family: 宋体">第七条、违约责任:本合同受《中华人民共和国合同法》保护。买卖双方如有一方无法履行合同(不可抗力除外),由此造成的经济损失由违约方承担。遇不可抗力因素,不能履行本合同时,应及时通知对方,双方协商解决。</span>
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style=" font-weight: normal;" colspan="8">
                <p style="margin:3px">
                    <span style="font-family: 宋体">第八条、合同争议的解决方式:本合同在履行过程中发生的争议,由双方当事人协商解决;协商不成任何一方均可向合同签订所在地有管辖权的人民法院提起诉讼。</span>
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style=" font-weight: normal;" colspan="8">
                <p style="margin:3px">
                    <span style="font-family: 宋体">第九条、其他约定事项:本合同以传真方式签订,经双方盖章后生效,传真件与原件具有同等法律效力;与本合同有关的货权转移凭据及其传真件同具法律效力;有效期:自买卖双方签订合同之日起,至货款、发票结清之日为止。</span>
                </p>
            </td>
        </tr>
        <tr style="height:75px;">
            <td colspan="8"></td>
        </tr>
        <tr style="text-align:left">
            <td style=" border: 1px solid #ccc; text-align:center;  font-weight: normal;" colspan="5">
                <p style="text-align:center">
                    <span style="font-family:宋体">买      方</span>
                </p>
            </td>
            <td style=" border: 1px solid #ccc; text-align:center;  font-weight: normal;" colspan="3">
                <p style="text-align:center">
                    <span style="font-family:宋体">卖      方</span>
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style=" border: 1px solid #ccc;   font-weight: normal;" colspan="5">
                <p style="margin:3px">
                    <span style="font-family:宋体">单位名称(章): </span>{buyer_company_name}
                </p>
            </td>
            <td style="  border: 1px solid #ccc;  font-weight: normal;" colspan="3">
                <p style="margin:3px">
                    <span style="font-family:宋体">单位名称(章): </span>{supply_company_name}
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style=" border: 1px solid #ccc;   font-weight: normal;" colspan="5">
                <p style="margin:3px">
                    <span style="font-family:宋体">单位地址:</span>{buyer_company_address}
                </p>
            </td>
            <td style=" border: 1px solid #ccc;   font-weight: normal;" colspan="3">
                <p style="margin:3px">
                    <span style="font-family:宋体">单位地址:</span>{buyer_company_address}
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style=" border: 1px solid #ccc;   font-weight: normal;" colspan="5">
                <p style="margin:3px">
                    <span style="font-family:宋体">法定代表人:</span>{buyer_representative}
                </p>
            </td>
            <td style="  border: 1px solid #ccc;  font-weight: normal;" colspan="3">
                <p style="margin:3px">
                    <span style="font-family:宋体">法定代表人:</span>{supply_representative}
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style=" border: 1px solid #ccc;   font-weight: normal;" colspan="5">
                <p style="margin:3px">
                    <span style="font-family:宋体">委托代理人:</span>{buyer_representative_commissioned}
                </p>
            </td>
            <td style="  border: 1px solid #ccc;  font-weight: normal;" colspan="3">
                <p style="margin:3px">
                    <span style="font-family:宋体">委托代理人:</span>{supply_representative_commissioned}
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style="  border: 1px solid #ccc;  font-weight: normal;" colspan="5">
                <p style="margin:3px">
                    <span style="font-family:宋体">电    话:</span>{buyer_mobile}
                </p>
            </td>
            <td style=" border: 1px solid #ccc;   font-weight: normal;" colspan="3">
                <p style="margin:3px">
                    <span style="font-family:宋体">电    话:</span>{supply_mobile}
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style=" border: 1px solid #ccc;   font-weight: normal;" colspan="5">
                <p style="margin:3px">
                    <span style="font-family:宋体">传    真:</span>{buyer_fax}
                </p>
            </td>
            <td style="  border: 1px solid #ccc;  font-weight: normal;" colspan="3">
                <p style="margin:3px">
                    <span style="font-family:宋体">传    真:</span>{supply_fax}
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style=" border: 1px solid #ccc;   font-weight: normal;" colspan="5">
                <p style="margin:3px">
                    <span style="font-family:宋体">开户银行:</span>{buyer_opening_bank}
                </p>
            </td>
            <td style="  border: 1px solid #ccc;  font-weight: normal;" colspan="3">
                <p style="margin:3px">
                    <span style="font-family:宋体">开户银行:</span>{supply_opening_bank}
                </p>
            </td>
        </tr>
        <tr style="text-align:left">
            <td style=" border: 1px solid #ccc;   font-weight: normal;" colspan="5">
                <p style="margin:3px">
                    <span style="font-family:宋体">帐    号:</span>{buyer_bank_account}
                </p>
            </td>
            <td style="  border: 1px solid #ccc;  font-weight: normal;" colspan="3">
                <p style="margin:3px">
                    <span style="font-family:宋体">帐    号:</span>{supply_bank_account}
                </p>
            </td>
        </tr>
    </tbody>
</table>

需要注意的是,这个页面是前端先把页面直接table布局先写出来,再慢慢调整修改。

实例二:

/**
 * PHP 使用 mpdf 导出PDF文件
 * @param $content  string PDF文件内容 若为html代码,css内容分离 非id,class选择器可能失效,解决办法直接写进标签style中
 * @param $filename string 保存文件名
 * @param $css   string css样式内容
 */
function export_pdf($content, $filename, $css = '')
{
 //实例化mpdf
 $_obj_mpdf = new mPDF('utf-8', 'A4', '', '宋体', 0, 0, 20, 10);
 //设置PDF页眉内容 (自定义编辑样式)
 $header = '<table width="95%" style="margin:0 auto;border-bottom: 1px solid #4F81BD; vertical-align: middle; font-family:serif; font-size: 9pt; color: #000088;">
    <tr><td width="10%"></td><td width="80%" align="center" style="font-size:16px;color:#A0A0A0">页眉</td><td width="10%" style="text-align: right;"></td></tr></table>';
 //设置PDF页脚内容 (自定义编辑样式)
 $footer = '<table width="100%" style=" vertical-align: bottom; font-family:serif; font-size: 9pt; color: #000088;"><tr style="height:30px"></tr><tr>
    <td width="10%"></td><td width="80%" align="center" style="font-size:14px;color:#A0A0A0">页脚</td><td width="10%" style="text-align: left;">
    页码:{PAGENO}/{nb}</td></tr></table>';
 //添加页眉和页脚到PDF中
 $_obj_mpdf->SetHTMLHeader($header);
 $_obj_mpdf->SetHTMLFooter($footer);
 $_obj_mpdf->SetDisplayMode('fullpage');//设置PDF显示方式
 $_obj_mpdf->WriteHTML('<pagebreak sheet-size="210mm 297mm" />');//设置PDF的尺寸 A4纸规格尺寸:210mm*297mm
 !empty($css) && $_obj_mpdf->WriteHTML($css, 1);//设置PDF css样式
 $_obj_mpdf->WriteHTML($content);//将$content内容写入PDF
 $_obj_mpdf->DeletePages(1, 1);//删除PDF第一页(由于设置PDF尺寸导致多出的一页)
 //输出PDF 直接下载PDF文件
 //$_obj_mpdf->Output($filename . '.pdf', true);
 //$_obj_mpdf->Output($filename . '.pdf', 'D');
 $_obj_mpdf->Output();//输出PDF 浏览器预览文件 可右键保存
 exit;
}
$html = '<b style="color: red">新年快乐!</b>';
$wordname = 'test-file';
export_pdf($html, $wordname);