项目需求:有一个空白的PDF表单,需要将数据填充进去,然后下载下来。空白的PDF表单如下所示:
PDF表单各个域名的字段如下图:
使用扩展:PDFtk【我使用的系统是CentOS7,安装步骤如下所示】
第一步:安装依赖:
yum install gcc gcc-c++ libXrandr gtk2 libXtst libart_lgpl
第二步:安装libgcj,由于镜像找不到,所以无奈我只能从网上花钱down了一下;为方便大家使用,特此分享。
链接:https://pan.baidu.com/s/1uevPeVS7P6c3D5FNHp1rbQ
提取码:feoa
将下载后的扩展上传到服务器中
rpm -ivh --nodeps libgcj-4.4.7-16.el6.x86_64.rpm
第三步:安装PDFtk
wget https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/pdftk-2.02-1.el6.x86_64.rpm
yum install pdftk-2.02-1.el6.x86_64.rpm
最后一步:查看是否PDFtk是否安装成功
which pdftk
显示以下,则表示安装成功。
最后我在GitHub上面找到一位大神封装好的方法,composer到项目里面,直接实例化类即可【https://github.com/mikehaertl/php-pdftk】
composer require mikehaertl/php-pdftk
以下是我在项目中具体的代码
require_once '../../common/global_company.conf.php';//这个是我框架中的加载基类【不必在意】
require_once GLOBAL_PATH . 'library/vendor/autoload.php';//加载从github上composer下来的库【composer require mikehaertl/php-pdftk】
use mikehaertl\pdftk\Pdf;//使用这个类
require_once GLOBAL_PATH . "common/route.php";//【不必在意】
/**
* 生成申请书并且下载下来
* 2019-09-12
*/
function _createPdf(){
$id = checkParam("id","3",1);//订单id
$mysql = new Mysql();
$orderInfo = $mysql->fetchRow("select userId,orderNum,types,from_country,to_country,address,pinyin,company,birth from tj_order where id={$id} and status=1 and isDel=1");//订单信息
if(empty($orderInfo)){
jReturn(ErrorCode::MISSING_ARGS,"订单信息错误");
}
$mysql = new Mysql();
$userInfo = $mysql->fetchRow("select openid,name,phone,IDNumber from tj_user where id={$orderInfo['userId']}");//用户信息
if(empty($userInfo)){
jReturn(ErrorCode::MISSING_ARGS,"用户信息错误");
}
if($orderInfo['types']==3){//出入境
$pdfurl = "jktj.pdf";//PDF的空白表单【也就是模板PDF表单,等待填充数据,需要有这个空白的PDF文件】
$data = [
'id'=>$orderInfo['orderNum'],//预约编号
'name'=>$userInfo['name'],//姓名
'pinyin'=>$orderInfo['pinyin'],//拼音
'nationality'=>$orderInfo['from_country'],//国籍
'destination'=>$orderInfo['to_country'],//前往国家
'phone'=> $userInfo['phone'],//电话
'company'=> $orderInfo['company'],//电话
];
}
if($orderInfo['types']==4){//预防接种
$pdfurl = "yfjz.pdf";//PDF的空白表单【也就是模板PDF表单,等待填充数据,需要有这个空白的PDF文件】
$data = [
'name'=>$userInfo['name'],//姓名
'shengri'=>$orderInfo['birth'],//生日
'phone'=>$userInfo['phone'],//电话
'guojia'=>$orderInfo['to_country'],//前往国家
'dizhi'=>$orderInfo['address'],//通讯地址
'id'=>$userInfo['IDNumber'],//身份证号
];
}
$path = str_replace('\\', '/', realpath(dirname(__FILE__) . '/../../../'))."/static/pdf/";
if (!is_dir($path)){ //判断目录是否存在 不存在就创建
mkdir($path,0777,true);
}
$pdfname = $userInfo['openid'].$id.'.pdf';//生成的pdf文件
$url = $path.$pdfname;
if(file_exists($pdfname)){//判断pdf文件是否已经生成了,若生成了直接下载,若没有生成,生成再下载
$file = fopen($url,"r"); // 打开文件 // 输入文件标签
Header("Content-type:application/pdf;charset=UTF-8");
Header("Accept-Ranges: bytes");
Header("Accept-Length: ".filesize($url));
Header("Content-Disposition: attachment; filename=".$pdfname); // 输出文件内容
echo fread($file,filesize(iconv('utf-8','gbk',$url)));
fclose($file);
require APP::R('center');
jReturn(ErrorCode::OK,"OK");
}else{
$pdf = new Pdf($pdfurl);
$res = $pdf->fillForm($data)
->needAppearances()
->saveAs($url);
if($res){
$file = fopen($url,"r"); // 打开文件 // 输入文件标签
Header("Content-type:application/pdf;charset=UTF-8");
Header("Accept-Ranges: bytes");
Header("Accept-Length: ".filesize($url));
iconv('utf-8','gb2312',$url);
Header("Content-Disposition: attachment; filename=".$pdfname); // 输出文件内容
echo fread($file,filesize(iconv('utf-8','gbk',$url)));
fclose($file);
require APP::R('center');
jReturn(ErrorCode::OK,"OK");
}else{
$msg = $pdf->getError();
jReturn(ErrorCode::MISSING_ARGS,"生成失败",$msg);
}
}
}
【注意事项】实例化Pdf类时,使用 时,即下面的代码,可能会出现以下错误提示
$pdf = new Pdf($pdfurl);
$res = $pdf->fillForm($data)
->needAppearances()
->saveAs($url);
错误提示:Could not run command pdftk A='test.pdf' fill_form '/tmp/php_pdftk_xfdf_hAurzU.xfdf' output '/tmp/tmp_php_pdftk_elVze6.pdf' drop_xfa need_appearances
【错误原因】自己当时很奇怪,花了很长时间在库中看他的源码,才知道原因。
在此库的源码中,用到proc_open、proc_close这个两个函数,因为这两个PHP函数不够安全,所以PHP讲这个两个函数禁用了。自此错误原因找到,下面就开始解禁这两个函数。
1.在服务器上找到php.ini文件,
2.在文件中找到disable_functions项,
3.找到相应的函数,删掉即可,
4.重启PHP服务
此次中方法经验,一部分来自于https://blog.csdn.net/u010392801/article/details/51011500,踩过的坑,本人已经帮你们踩过,遇到新问题,欢迎大家在评论区多多提出来。谢谢