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博客

相关推荐
ZhengEnCi4 天前
Q02-Vue-React-index.html完全指南
vue.js·react.js·html
牧艺5 天前
HTML-in-Canvas 深度解析:让 Canvas 真正「吃上」HTML 这碗饭
前端·html·canvas
爱勇宝5 天前
我给自己做了一个新标签页:不登录、不打扰、打开就能用
前端·html·浏览器
越努力越幸运666 天前
多模态代码调试实战:Gemini3.5 精准捕获 HTML 隐性语法
html
两个人的幸福9 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
anOnion9 天前
构建无障碍组件之Menu Button pattern
前端·html·交互设计
米丘10 天前
微前端之 Web Components 完全指南
微服务·html
BingoGo11 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack11 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820712 天前
PHP 扩展——从入门到理解
php