PHP 使用fpdf,fpdi类库操作修改pdf文件,添加文字和图片水印,cd_FPDF引入解决fpdf,fpdi添加中文文字乱码问题(2023/8/1更新mpdf导出PDF中文不乱码实例)

2023-09-24 11 0

文章目录

  • 一、fpdi和fpdf
    • 1. 安装
    • 2. 中文乱码问题
      • 2.1 问题描述
      • 2.2 解决办法
        • (1)下载代码
        • (2)将上一步的源码放入vendor/setasigin/PDF_Chinese文件中
        • (3)修改vendor\setasign\fpdi\src\FpdfTpl.php, 将他基础的fpdf类改成 咱们刚才引入的代码
    • 3. 实例
    • 4. 常见问题
      • 4.1 错误:`Function get_magic_quotes_gpc() is deprecated`
      • 4.2 错误:`Undefined index: GB_widths`
    • 5. 结果演示
  • 二、纯cd_FPDF生成pdf
    • 1. 测试代码:
    • 2. 效果
  • 三、mPDF生成pdf
    • 1. 要求
    • 2. 安装
    • 3. 中文和符号乱码问题
    • 4. 使用mpdf将html页面转换pdf文件
    • 5. 使用mpdf修改现有的pdf文档
  • 完结

前言:最近遇到个需求,就是按学生的报名表自动生成合同,因为涉及内容动态填充的方式,
一开始我的想法是用GD类库绘图,最后也是成功了,但是因为合同涉及很多张图片,绘制的时间会很长,用户体验极差,后来就改用了这种直接修改pdf文件的办法,效率明显上升

一、fpdi和fpdf

不懂怎么使用的,可以直接去查看开发文档
开发文档地址:https://manuals.setasign.com/fpdi-manual/

1. 安装

  • composer命令安装:composer require setasign/fpdi
  • composer命令安装:composer require setasign/fpdf

2. 中文乱码问题

2.1 问题描述

在实际操作上就出现了问题。国外的fpdf 对中文支持并不是很好,在pdf上加入中文汉字的时候,会出现乱码。而且他只提供文件夹中的几种字体。而且这几种字体都是英文字体,所以无法正常支持汉字的写入。

2.2 解决办法

(1)下载代码

https://github.com/DCgithub21/cd_FPDF

(2)将上一步的源码放入vendor/setasigin/PDF_Chinese文件中

在这里插入图片描述

(3)修改vendor\setasign\fpdi\src\FpdfTpl.php, 将他基础的fpdf类改成 咱们刚才引入的代码
namespace setasign\Fpdi;include_once "../vendor/setasign/PDF_Chinese/chinese.php";class FpdfTpl extends \PDF_Chinese
{use FpdfTplTrait;
}

在这里插入图片描述

3. 实例

//引入类
use setasign\Fpdi\Fpdi;
use think\facade\Env;
use library\File;/** $user 用户信息* $path pdf文件路径*/
public function pdf($user, $path)
{$pdf = new Fpdi();//获取页数$pageCount = $pdf->setSourceFile($path);$pdf->AddGBFont('simhei', '黑体');$pdf->SetFont('simhei', '', 12);//遍历所有页面for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {//导入页面$templateId = $pdf->importPage($pageNo);//简单的创建页面$pdf->AddPage();/*复杂的创建页面//获取导入页面的大小$size = $pdf->getTemplateSize($templateId);//创建页面(横向或纵向取决于导入的页面大小)if ($size['width'] > $size['height']){$pdf->AddPage('L', array($size['width'], $size['height']));}else {$pdf->AddPage('P', array($size['width'], $size['height']));}*/// 在新增的頁面上使用引入的第$pageNo页$pdf->useTemplate($templateId);/*添加水印if($type == 1){//文字水印//设置字体//$pdf->SetFont('Arial','B','24');$family = ['courier', 'helvetica', 'times', 'symbol', 'zapfdingbats'];$pdf->SetFont('helvetica','U','50');//设置位置 - 加在中间位置$center_x = $size['width']/2;$center_y = $size['height']/2;$pdf->SetXY($center_x, $center_y);//写入水印 - 中文会乱码可以用iconv("utf-8","gbk",'内容')转换编码格式$pdf->Write(7, 'ROOT_ICO');}else{//图片水印$center_x = $size['width']/2 - 40;$center_y = $size['height']/2;$pdf->image("xxxx.png", $center_x, $center_y, 80, 0);//中间水印$pdf->image("xxxx.png", 0, 0,210);//全屏背景水印}*/// 第一页if ($pageNo == 1) {// 应缴纳总费用$pdf->SetTextColor(0, 0, 0);//字体颜色$pdf->SetXY(75, 179);//xy定位$pdf->Write(5, $user['pay']);// 费用名称$pdf->SetXY(25, 210);$pdf->Write(5,iconv("utf-8","gbk",$user['title']));} else if($pageNo == 2) {}}$fileName = time().'.pdf';if (strtoupper(substr(PHP_OS,0,3)) === 'WIN') {$url =  Env::get('ROOT_PATH')."public\uploads\contract\\".$fileName;} else {$url =  Env::get('ROOT_PATH').'public/uploads/contract/'.$fileName;}//I输出output,D下载download,F保存file_put_contents,S返回return// 輸出成本地端 PDF 檔案$pdf->Output('F', $url);//将文件上传至七牛云$res = File::save($fileName,file_get_contents($url));if($res) {// 删除本地文件@unlink($url);return $res['url'];}else{return false;}
}

4. 常见问题

4.1 错误:Function get_magic_quotes_gpc() is deprecated

解决:修改\vendor\setasign\PDF_Chinese\fpdf.php位置代码

if(get_magic_quotes_runtime()) @set_magic_quotes_runtime(0);

改为

if(@ini_get("magic_quotes_runtime")) @ini_set("magic_quotes_runtime",0);

4.2 错误:Undefined index: GB_widths

解决:修改\vendor\setasign\PDF_Chinese\chinese.php位置代码
添加代码

global $Big5_widths, $GB_widths;

结果
在这里插入图片描述

5. 结果演示

在这里插入图片描述

二、纯cd_FPDF生成pdf

如果你觉得上面改来改去过于麻烦,你也可以选择直接使用cd_FPDF来生成,经过测试也是可行的

github源码位置:https://github.com/DCgithub21/cd_FPDF

官方demo代码地址: https://github.com/DCgithub21/cd_FPDF/blob/master/example.php

1. 测试代码:

require 'chinese.php';
$pdf = new PDF_Chinese();
$pdf->AddGBFont('simhei', '黑体');
$pdf->AddPage();
$pdf->SetFont('simhei', '', 13);//自动换行
$pdf->MultiCell(180,10,iconv("utf-8","gbk","中文自动换行中文自动换行中文自动换行中文自动换行中文自动换行中文自动换行中文自动换行中文自动换行中文自动换行中文自动换行中文自动换行"));//显示一格
$pdf->Cell(40,10,iconv("utf-8","gbk","第一个单元格"));
$pdf->Ln();//换行
$pdf->Cell(40,10,iconv("utf-8","gbk","第二个单元格"));
$pdf->Ln();//换行//输出表格
//Cell方法最后一个参数表示是否显示边框
$pdf->Cell(60,10,iconv("utf-8","gbk","姓名"),1);
$pdf->Cell(60,10,iconv("utf-8","gbk","性别"),1);
$pdf->Ln();
$pdf->Cell(60,10,iconv("utf-8","gbk","张三"),1);
$pdf->Cell(60,10,iconv("utf-8","gbk","男"),1);
$pdf->Ln();
$pdf->Cell(60,10,iconv("utf-8","gbk","李四"),1);
$pdf->Cell(60,10,iconv("utf-8","gbk","女"),1);
$pdf->Ln();//插入图片
//Image参数:文件,x坐标,y坐标,宽,高
$pdf->Image('test.jpg',null,null,50,50);$pdf->Output();//直接输出,即在浏览器显示
//$pdf->Output('example.pdf','F');//保存为example.pdf文件

2. 效果

在这里插入图片描述
ps:用法和前面类似,常见问题参考前面提到的第4点

三、mPDF生成pdf

即使我给出了前面的方法,发现还是有很多人不会用遇到各种各样的问题来找我,这我就分享出最近发现的一个新的生成pdf文件的方法——mPDF,他使用起来更加简单,对中文支持也很好

github源码位置:https://github.com/mpdf/mpdf

开发文档:https://mpdf.github.io/

1. 要求

注意文档的使用要求和对应版本
在这里插入图片描述

2. 安装

composer require mpdf/mpdf

3. 中文和符号乱码问题

简单使用

<?phprequire_once __DIR__ . '/vendor/autoload.php';$mpdf = new \Mpdf\Mpdf();
$mpdf->WriteHTML('<h1>Hello world!</h1>');
$mpdf->Output();

但是在实际使用时会遇到中文和符号乱码(变成了小方块)的问题,最开始会想到是字体的问题,但是指定了字体后,并没有解决问题。
在这里插入图片描述

查看了文档后发现需要指定两个参数:

$this->pdf = new Mpdf(['autoScriptToLang' => true,'autoLangToFont'   => true,
]);

刷新页面,发现中文此时已经可以正常显示了
在这里插入图片描述
但是当中文的标点符号靠近英文的时候,中文符号就又会变回小方块。

再添加一个配置项代码,解决符号的问题:

$this->pdf = new Mpdf(['autoScriptToLang' => true,'autoLangToFont'   => true,'useSubstitutions' => true,
]);

至此,解决了中文和标点符号乱码的问题。
在这里插入图片描述

4. 使用mpdf将html页面转换pdf文件

demo

public function test_pdf(){$mpdf = new \Mpdf\Mpdf(['mode' => 'UTF-8', 'format' => 'A4', 'default_font_size' => 40, 'default_font' => '', 'margin_left' => 20, 'margin_right' => 20]);$pdf->SetAuthor('作者');$pdf->SetTitle('标题');$pdf->SetSubject('项目');$pdf->SetKeywords('关键词,关键词');$pdf->SetMargins('10', '10', '10');// 设置左、上、右的间距$pdf->SetAutoPageBreak(TRUE, '15');// 设置是否自动分页  距离底部多少距离时分页$mpdf->autoScriptToLang = true;//支持中文设置 $mpdf->autoLangToFont = true;//支持中文设置$mpdf->useSubstitutions = true;//支持中文符号 $pdf->AddPage();$pdf->SetFont('stsongstdlight', '', 14, '', true);// 设置字体$pdf->SetWatermarkImage('背景图路径', 0.1, [230, 180]);//设置背景$pdf->showWatermarkImage = true;$mpdf->WriteHTML('<h1>你好啊,世界!hello word</h1><p style="color: blue;fontsize:14px;">http://www.baidu.com</p>');$path = FILE_UPLOAD.date('YmdHis').'_'.mt_rand(1,5).'.pdf';         $mpdf->Output();//直接在页面显示pdf页面内容 //$mpdf->Output($path,'f');//保存pdf文件到指定目录  
}

效果
在这里插入图片描述

5. 使用mpdf修改现有的pdf文档

这里仅介绍了mPDF 7.x版本的使用,其他版本可以参考:https://www.5axxw.com/questions/content/dja7yz

方法名称使用引入的pascal-cased模式\Mpdf命名空间类名为Mpdf()

导入文件和模板的示例

<?php
require_once __DIR__ . '/vendor/autoload.php';$mpdf = new \Mpdf\Mpdf();// 设置源文件
$mpdf->SetImportUse(); // <--- mPDF版本所需 < 8.0
$mpdf->SetSourceFile(__DIR__ . '/hs.pdf'); // PDF文件的绝对路径// 导入页面1
$tplIdx = $mpdf->ImportPage(1);// 使用导入的页面,并将其放置在点10,10,宽度为200mm(这是所包含的pdf的图像)
$mpdf->UseTemplate($tplIdx, 10, 10, 200);// 现在在导入的页面上方写一些文本
$mpdf->SetTextColor(0, 0, 255);
$mpdf->SetFont('Arial', 'B', 8);
$mpdf->SetXY(95, 16);
$mpdf->Write(0, 'Mindfire');
$mpdf->Output('newpdf.pdf');

ps:编辑PDF文件不需要$mpdf->AddPage();,除非向生成的输出PDF添加另一页

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

代码编程
赞赏

相关文章

【数据结构周周练】034 奇偶排序算法原理详解(上海大学832计算机组成原理与数据结构原题)
考研结束,一起聊聊考研中的故事
【积跬步以至千里】关于文化自信与支持国产的个人理解,附加WPS关闭广告或消息推送
【数据结构周周练】033 冒泡排序算法原理详解及代码分享
【数据结构周周练】032 折半插入排序算法原理详解及代码分享
【数据结构周周练】031 直接插入排序算法原理详解及代码分享