TP6 html生成ptf并加盖骑缝章

如题,最近项目需要用到自动生成PDF合同并为合同加盖电子骑缝章功能,折腾了好几天,查了不少资料,终于搞定,罗列代码如下:

1、函数方法:

php 复制代码
use Dompdf\Dompdf;
use Dompdf\Options;
use setasign\Fpdi\Fpdi;
use Spatie\PdfToImage\Pdf;

use think\Image;

/*
 * html转pdf
 *
 * $html: html内容
 * $filename: 即将生成PDF文件的存储路径
 * $type: 生成pdf的类型  I:直接预览PDF文件  F:PDF文件保存到本地  S:返回PDF文件流  D:直接下载PDF文件
 * $imagePath:引入图片文件的路径
 *
 */
if (!function_exists('html_to_pdf')) {//86 341
    function html_to_pdf($html, $filename = 'document.pdf', $type = 'I', $imagePath='', $img_x='120', $img_y='360')
    {
        $options = new Options();
        //设置使用远程图片填充pdf内容
        $options->set('isRemoteEnabled', true);
        $options->set('defaultFont', 'simsun');//设置默认字体

        //设置html文件编码
        $html = mb_convert_encoding($html, 'UTF-8','UTF-8,GBK,GB2312,BIG5');

        $dompdf = new Dompdf($options);
        //加载html文件
        $dompdf->loadHtml($html,'UTF-8');

        //设置纸张大小和方向
        $dompdf->setPaper('A4', 'portrait');//竖向显示
        $dompdf->render();//渲染pdf;

        //png公章图片的原始路径和截图后小图的保存路径
        //$imagePath = 'storage/business/seal/img/zhang04.png';
        //$savePath = 'storage/business/seal/img/zhang04_';

           加盖 骑缝章 & 公章  Start //
        if($imagePath) { //如果存在导入图片,才执行 盖骑缝章和公章 的操作
            //构造盖骑缝章的操作
            $savePath = str_replace('.png', '_', $imagePath);

            // 将PDF内容写入文件
            file_put_contents($filename, $dompdf->output());

            // 加载现有的PDF文件
            $pdf = new FPDI();

            $pageCount = $pdf->setSourceFile($filename);

            unlink($filename);//删除生成的初始pdf文件

            $cutimgData = cutimg($imagePath, $savePath, $pageCount);

            for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
                // 导入页面
                $templateId = $pdf->importPage($pageNo);
                $size = $pdf->getTemplatesize($templateId);
                $pdf->AddPage($size['orientation'], [$size['width'], $size['height']]);
                // 填充页面
                $pdf->useTemplate($templateId);
                //  $pdf->useTemplate($stamp, [0, 0], [$w, $h], [$x, $y]);

                $x = 41 * $cutimgData['width'] / 485;//161为要调用的公章子图片的宽度像素
                if ($pageNo == $pageCount) {
                    $x = 41 * $cutimgData['end_width'] / 485;
                }
                //添加盖章 - 骑缝章
                $pdf->Image($savePath . 'part_' . $pageNo . '.png', $size['width'] - $x, $size['height'] / 2 - 41, $x, 41); // 右下角位置和大小
            }

            //添加盖章 -  【备注: 如果需要操作多份动态合同,则公章的 x轴 y轴 位置需要前端传过来】
            $pdf->Image($imagePath, (int)$img_x/3, (int)$img_y/3, 41, 41);

            // 保存带有图章的PDF
            $pdfContent = $pdf->Output($filename, $type);//I:直接预览PDF文件、 D:直接下载PDF文件  F:PDF文件保存到本地  S:返回PDF文件流
            if ($type == 'S') {
                $pdfContent = base64_encode($pdfContent);

                return $pdfContent;
            }
            if($type == 'I'){
                exit;
            }

            return '';
        }

           加盖骑缝章 & 公章  End //
        // I:直接预览PDF文件  F:PDF文件保存到本地  S:返回PDF文件流  D:直接下载PDF文件
        switch(strtoupper($type)) {
            case 'I':  // Send to standard output 直接预览PDF文件
                echo $dompdf->stream($filename, ['Attachment' => false]);
                break;
            case 'F':// Save to local file  PDF文件保存到本地
                file_put_contents($filename,$dompdf->output());
                echo $dompdf->output();
                break;
            case 'D':// Download file  直接下载PDF文件
                //将生成的pdf保存到服务器
                $dompdf->stream($filename, ['Attachment' => true]);
                echo $dompdf->output();
                break;
            default ://S  Return as a string  返回PDF文件流
                $pdfContent = $dompdf->output();
                $pdfContent = base64_encode($pdfContent);

                return $pdfContent;
        }
        exit;
    }
}


/*
 * 将图片平均裁剪为N份
 */
function cutimg($imagePath,$savePath, $num='2'){
    // 创建Image对象
    $image = Image::open($imagePath);

    // 获取图片宽度和高度
    $width = $image->width();
    $height = $image->height();

    // 计算每份图片的宽度和高度
    $partWidth = intval($width / $num);

    // 切割图片
    $end_partWidth = $partWidth;
    for ($y = 0; $y < $num; $y++) {
        // 计算切割区域的坐标
        $startX = $y * $partWidth;

        if($y + 1 == $num){//最后一个图片宽度取剩余宽度
            $partWidth = $width - $partWidth * $y;
            $end_partWidth = $partWidth;
        }

        // 切割图片并保存
        $image = Image::open($imagePath);
        $partImage = $image->crop($partWidth, $height, $startX, 0);
        $partImage->save($savePath . 'part_'  .( $y + 1 ). '.png');
    }

    return ['width'=>$partWidth,'end_width'=>$end_partWidth];
}

2、项目调用:

php 复制代码
$hostName = "http://".$_SERVER['HTTP_HOST'];

$html = '<html lang="en"><head><meta charset="UTF-8"><title>合同</title>
                 <link rel="stylesheet" href="'.$hostName.'/static/css/admin/main.css"></head><body><div style="width: 210mm">'
            . $html
            . '</body></div>';


 //宋体 微软雅黑
$font_arr = ['宋体','微软雅黑','Arial'];
foreach($font_arr as $k=>&$v){
    $html = str_replace($v,'simsun', $html);
}


$pdf_url = 'storage/contract/pdf/template_01.pdf';//生成合同pdf文件存储路径

seal_img = '1.png';//seal_img 公章png图片的路径

// img_x 公章X坐标位置  img_y 公章Y坐标位置
html_to_pdf($html, $pdf_url, 'F', $seal_img, $img_x,$img_y);//F:PDF文件保存到本地

echo pdf_url;

备注:html生成PDF所需要的其他配置安装,见上篇博文:

TP6将HTML转换为PDF文件,非法UTF-8编码和中文乱码问题_php html转pdf 中文-CSDN博客

相关推荐
ServBay2 天前
告别面条代码,PSL 5.0 重构 PHP 性能与安全天花板
后端·php
anOnion2 天前
构建无障碍组件之Switch Pattern
前端·html·交互设计
JaguarJack4 天前
FrankenPHP 原生支持 Windows 了
后端·php·服务端
BingoGo4 天前
FrankenPHP 原生支持 Windows 了
后端·php
JaguarJack5 天前
PHP 的异步编程 该怎么选择
后端·php·服务端
BingoGo5 天前
PHP 的异步编程 该怎么选择
后端·php
JaguarJack6 天前
为什么 PHP 闭包要加 static?
后端·php·服务端
ServBay7 天前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
用户962377954487 天前
CTF 伪协议
php
willow8 天前
html5基础整理
html