博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP生成PDF并转换成图片爬过的坑
阅读量:6941 次
发布时间:2019-06-27

本文共 4676 字,大约阅读时间需要 15 分钟。

  需求描述:根据订单通过模板合同生成新的PDF合同通过e签宝签约后转为图片给用户下载。

  需求整理:

    1.如何生成PDF文件:使用TCPDF扩展生成。思考:

      ⑴为了方便将模板中的固定占位符替换为订单中的内容,使用静态html页面保存合同模板的方式保存

      ⑵使用TCPDF将html转换为pdf文档,可以尽量保证合同格式的一致性

    2.将生成的PDF合同通过e签宝的签约流程进行图章签署。具体流程忽略:对比e签宝签约流程

    3.将签约后的新PDF合同转换为图片。思考:

      ⑴使用php的Imagick扩展实现(坑之所在)

 

  实现流程:

    1.安装TCPDF扩展,这个都是原生的PHP代码库比较简单,依赖composer。在要安装的目录命令行直接敲:

composer require smalot/pdfparser

    2.安装Imagick扩展,这个流程比较多。可以参考下面链接(感谢感谢):

    https://www.cnblogs.com/jinxiblog/p/8053008.html  --windows环境安装(我是windows开发环境,使用这个没毛病)

    https://www.osyunwei.com/archives/5327.html    --linux环境安装(没测试过,留给以后测试)

    https://blog.csdn.net/webben/article/details/64125470    --linux环境安装(没测试过,留给以后测试)

    3.第一个坑,Imagick装好就行了吗?并不然,网上找了很多资料后表面Imagick的运行机制大概是php通过Imagick扩展调用本机安装的Imagemagic提供的接口来处理图片,另外如果你要readImage的是一个PDF文件那么还有一个前提就是Imagemagic应用本身还会调用ghostscript这个玩意。

因为我们的需求是将PDF转换为图片而不是普通的图片文件处理,所以ghostscript也是我们必须要安装的。linux下同理。如果没安装的话会出现诸如下面的错误:

 

Postscript delegate failed `/Uploads/Download/2016-09/57d0fb5b3612d.pdf': No such file or directory @ error/pdf.c/ReadPDFImage/664

 

  看看Imagick下面官方说明:

 

    4.安装ghostscript,官网上根据自己的环境下载不同安装包,如果phpinfo()中的php是X86的话记得要选32位的安装包下载,装完后记得重启。本人重启了n次才突然间成功

        --下载链接

 

    5.到这里基本的依赖已经安装完毕,贴下本地实验代码如下:

 

require_once 'vendor/autoload.php'; //PDF文件生成$tcpdf = new TCPDF();$tcpdf->SetCreator('Hello');$tcpdf->SetAuthor('walter');$tcpdf->SetTitle('test pdf');$tcpdf->SetSubject('subject');$tcpdf->SetKeywords('walter,pdf,php');$tcpdf->setHeaderData('logo_example.png',20,'标题','子标题',array(0,64,255),array(0,64,128));$tcpdf->setFooterData(array(0,64,0),array(0,64,128));$tcpdf->setHeaderFont(['stsongstdlight', '', '10']);    //设置字体$tcpdf->setFooterFont(['helvetica', '', '8']);       //设置字体 $tcpdf->SetDefaultMonospacedFont('courier');        //设置字体$tcpdf->SetMargins(15,27,15);$tcpdf->setHeaderMargin(5);$tcpdf->setFooterMargin(10);$tcpdf->SetAutoPageBreak(true,25);$tcpdf->setImageScale(1.25);$tcpdf->setFontSubsetting(true);$tcpdf->SetFont('stsongstdlight','',14);    //设置字体//$tcpdf->AddPage();$html = file_get_contents('contract.html');$tcpdf->writeHTMLCell(0,0,'','',$html,0,1,0,true,'',true);    //写入html$tcpdf->Output(__DIR__.DIRECTORY_SEPARATOR.'contract.pdf','F');  //生成pdf文件并保存到本地//pdf合并转换一张图片function pdf2png($from_path,$target_path){    try{        $img = new Imagick();        $img->setCompressionQuality(100);        $img->setResolution(120,120);        $img->readImage($from_path);        $canvas = new Imagick();        $imgNum = $img->getNumberImages();        foreach ($img as $k => $sub){            $sub->setImageFormat('png');            $sub->stripImage();            $sub->trimImage(0);            $width = $sub->getImageWidth() + 10;            $height = $sub->getImageHeight() + 10;            if ($k + 1 == $imgNum) $height += 10;            $canvas->newImage($width,$height,new ImagickPixel('white'));            $canvas->compositeImage($sub,Imagick::COMPOSITE_DEFAULT,5,5);        }        $canvas->resetIterator();        $canvas->appendImages(true)->writeImage($target_path);        return true;    }catch (Exception $e){        echo $e->getMessage();        echo $e->getTraceAsString();        return false;    }//pdf文件转换为一张图片$pdf_path = __DIR__.DIRECTORY_SEPARATOR.'contract.pdf';if (is_file($pdf_path)){    var_dump(pdf2png($pdf_path,__DIR__.DIRECTORY_SEPARATOR.'contract.png'));}else{    echo 'file not exist';}

 

  

 

    至此本地测试没毛病一切OK

             PDF文件                                  生成的图片         

    

    6.正式服务器上测试(最大的坑来了),生成PDF文件一切OK,到了转换图片的时候就:

      

    一遍空白!!!!!!神坑

    一遍度娘乱七八糟的资料后发现根本没有这方面的资料。偶尔在百度提问里面看到有人又类似说法是,Imagick->readImage的时候中文编码的问题。虽然不太对但是在万能的有人提过类似的问题

    

    经过不停的踩坑发现是ghostscript这个坑货的问题,在linux下安装ghostscript的时候没有对应生成cidfmap文件来支持各种字体,在windows环境安装的时候已经在lib目录下面生成了这个配置文件。所以需要在linux环境下新建一个cidfmap文件并且将我们要支持的字体放到linux下来:

        --参考链接

 

    这样就行了吗?还没有.......看看代码里面我生成pdf时设置了什么字体?这些是adobe公司默认的字体,但是比较不统一。你代码里面要设什么字体就得把对应的ttf字体文件放到linux下重新对应cidfmap的字体格式设置一遍。

$tcpdf->SetFont('stsongstdlight','',14);$tcpdf->setHeaderFont(['stsongstdlight', '', '10']);$tcpdf->setFooterFont(['helvetica', '', '8']);$tcpdf->SetDefaultMonospacedFont('courier');

 

  为了避免麻烦我在windows的字体库里面拿了一个simhei字体(简体字)放到linux下配置好,最后发现这个字体不是TCPDF扩展内置的(坑)。还好tcpdf库提供了一个添加字体的脚本,具体路径如下:

 

    把要新增的simhei字体放进来命令行输入如下命令:

 

#\tools>php ./tcpdf_addfont.php -b -i simhei.ttf>>> Converting fonts for TCPDF:*** Output dir set to D:\phpStudy2016\WWW\mugua\muguaadmin\public\task\pdf\vendor\tecnickcom\tcpdf/fonts/+++ OK   : D:\phpStudy2016\WWW\mugua\muguaadmin\public\task\pdf\vendor\tecnickcom\tcpdf\tools\simhei.ttf added as simhei>>> Process successfully completed!

 

 

 

 恭喜你,爬坑完毕字体终于可以正常使用,生成的图片再也不是空白了

转载于:https://www.cnblogs.com/walterfong/p/10008596.html

你可能感兴趣的文章
HDOJ---1068 Girls and Boys[匈牙利算法]
查看>>
POJ-2528 Mayor's posters (点树+离散) 线段树 ----------------------转
查看>>
Create a Git Mirror (for your hg repository) / hg tip
查看>>
[转]sql server 存储过程中变量表与临时表的分析比较
查看>>
无法启动程序“http://localhost:3303/Default.aspx”
查看>>
SQL 把字符创分割成两个字符串
查看>>
java使用JNDI 获取weblogic配置的数据源 连接数据库
查看>>
大年初七回杭州
查看>>
Java--选择排序,冒泡排序
查看>>
MySQL 时间戳(Timestamp)函数
查看>>
免费的jquery ui 收集
查看>>
启动Windows virtual pc XPMODE
查看>>
Java网络02 Servlet开胃酒
查看>>
编写简单的c运行库(二)
查看>>
UML介绍--用例图
查看>>
Web网页中内嵌Activex的Activex插件开发 .
查看>>
asp.net正则表达式
查看>>
使用node-webkit实现打包工具的小结
查看>>
ComboBoxEdit 数据绑定 使用模板
查看>>
Android使用属性动画ValueAnimator动态改变SurfaceView的背景颜色
查看>>