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

相关推荐
AI源码1 小时前
鲜花商城(HTML 版)
前端·html
修船大队长2 小时前
CanNm 从休眠唤醒后重复消息报文的周期与数量分析
开发语言·php
李纲明3 小时前
WordPress 安全加固基线:更新策略、文件权限、登录面收缩和备份验证(含回滚注意)
运维·安全·php·wordpress
Novproxy_Z3 小时前
IPv4 与 IPv6 代理在跨境自动化场景下的选型与风险
运维·自动化·php
kimnoic4 小时前
PHP 8.3 数据库备份失败怎么排查
开发语言·php
Sunny_GMF4 小时前
Markdown 导出 HTML 实战:2.6MB 编辑器快照如何瘦身 71%(DOM 净化 + CSSOM 运行时裁剪)
编辑器·html·ai编程·harmonyos
CRMEB系统商城4 小时前
CRMEB开源商城系统(PHP)v8.0,打造全新AI二开商城底座!
开发语言·人工智能·小程序·开源·php
云川之下4 小时前
【存储】搭建nfs 存储示例
开发语言·php
天空属于哈夫克34 小时前
企业微信消息回调处理:如何避免慢查询拖垮整个服务?
数据库·php·企业微信
zd8451015005 小时前
基于 HTML 与 Modbus TCP 构建设备仪器上位机:可行性分析与代码结构设计
前端·tcp/ip·html