项目需求是这样的:用户签订合同,并读取用户信息生成合同,将合同保存为png图片保存
环境:windows(2012,linux要配置java环境,偷懒)+ apache(2.4.48) + php(7.1) + mysql(5.5.62)
框架:tp5.0.24,网站目录在public下面,环境直接用宝塔塔建的,phpenv 本地测试了也可以,其他的没有测试
第一步:向word写入用户信息
1. 将 PhpOffice 整个文件夹复制到 extend 文件夹下(如下图)
2. 接下来就是代码了,直接上:
public function word_write()
{
import('PhpOffice\PhpWord\TemplateProcessor', '.php');
$temp_path = $_SERVER['DOCUMENT_ROOT'] . '/xieyi_fuwu_copy.docx';
$document = new \PhpOffice\PhpWord\TemplateProcessor($temp_path);
$data = [
['key' => 'name', 'value' => '小度哇'],
['key' => 'idcard', 'value' => '341022188810222345'],
['key' => 'phone', 'value' => '18888888888'],
['key' => 'time', 'value' => date('Y年m月d日')],
];
foreach ($data as $k => $v) {
$document->setValue($v['key'], $v['value']);
}
$file_path = $_SERVER['DOCUMENT_ROOT'] . '/file/' . date('Ymd');
if (!file_exists($file_path)) {
mkdir($file_path, '0777');
}
$document->saveAs($file_path.'/'.time().'.docx');
}
第二步:world 转为 pdf
-
修改php.ini 添加:extension=php_com_dotnet.dll 去除注释:com.allow_dcom = true 重启php环境 -
安装office,一定要安装office,(office 2007 需要手动安装 Microsoft Save as PDF and XPS )【https://files-cdn.cnblogs.com/files/XiaoMingBlingBling/SaveAsPDFandXPS.rar】 -
配置office组件服务:win+R打开运行菜单,输入dcomcnfg 找到 [组件服务] — [计算机]— [我的电脑] — [DCOM配置] — [Microsoft Wrord 97-2003文档] 右键 [Microsoft Wrord 97-2003文档] 设置属性 [标识] 为 [交互式用户] -
可以写代码了
function index3()
{
$filenamedoc = $_SERVER['DOCUMENT_ROOT'] . '/xieyi_fuwu_copy.docx';
$filenamepdf = $_SERVER['DOCUMENT_ROOT'] . '/xieyi_fuwu_copy.pdf';
if (!file_exists($filenamedoc )) {
return 'word原文件不存在';
}
if (file_exists($filenamepdf)) {
unlink($filenamepdf);
}
$word = new \COM("word.Application") or die("Could not initialise Object");
$word->Documents->Open($filenamedoc);
$word->ActiveDocument->ExportAsFixedFormat($filenamepdf, 17, false, 0, 0, 0, 0, 7, true, true, 2, true, true, false);
$word->Quit(false);
unset($word);
return '转换成功';
}
第三步:PDF 转为图片
-
安装 ImageMagic 扩展,可以参考:https://www.cnblogs.com/jinxiblog/p/8053008.html,这个链接里面写的,我的就是按照这个来的,宝塔的话就不需要了,直接在 [软件管理]—[php7.1]—[安装扩展] 找到imagemagick,直接安装就可以了,如下图 -
安装 ghostscript.exe (ghostscript.exe安装好之后需要添加到环境变量里面,并且将 gs9.54.0\bin\gswin64.exe 复制一份修改为gs.exe),我的上篇文章里面有提到过 ghostscript.exe 的坑,采坑的可以参考下 -
上代码
public function index4()
{
$from_path = $outPath = $_SERVER['DOCUMENT_ROOT'] . '/xieyi_fuwu_copy.pdf';
$target_path = $_SERVER['DOCUMENT_ROOT'] . '/xieyi_fuwu_copy.png';
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 '转化成功';
} catch (\Exception $e) {
return '转化失败:'.$e->getMessage();
}
}
第四步:添加签名
这里我直接用tp添加图片水印的方式处理了
public function add_sign()
{
$image = \think\Image::open($_SERVER['DOCUMENT_ROOT'] . '/xieyi_fuwu_copy.png');
$image->water($_SERVER['DOCUMENT_ROOT'].'/qianming.png')->save($_SERVER['DOCUMENT_ROOT'].'/xieyi_fuwu_copy2.png');
}
第五步:整合
最后,整合了上述代码,封装成类,直接上代码,我就放在了index模块下面了,放在其他地方及得改命名空间,上代码
<?php
namespace app\index\controller;
use Imagick;
use ImagickPixel;
class Word2img
{
protected $sign_img;
protected $user_id;
protected $file_name;
protected $data;
public function __construct($sign_img, $user_id, $data)
{
$this->sign_img = $sign_img;
$this->user_id = $user_id;
$this->file_name = $user_id . time();
$this->data = $data;
}
public function get_img()
{
$save_path = $this->word_write();
if (!$save_path) {
return json_encode(['code' => -1, 'msg' => '文字写入word失败']);
}
$pdf_path = $this->word2pdf($save_path);
if ($pdf_path == -1) {
return json_encode(['code' => -1, 'msg' => 'world转为pdf失败']);
}
$img_path = $this->pdf2img($pdf_path);
if ($img_path == -1) {
return json_encode(['code' => -1, 'msg' => 'pdf转为图片失败']);
}
$age_path = $this->add_water($img_path);
if ($age_path == -1) {
return json_encode(['code' => -1, 'msg' => '添加签名失败']);
}
return json_encode(['code' => 1, 'msg' => '生成签名图片成功', 'data' => $age_path]);
}
public function word_write()
{
import('PhpOffice\PhpWord\TemplateProcessor', '.php');
$temp_path = $_SERVER['DOCUMENT_ROOT'] . '/temp/agreement_free.docx';
$document = new \PhpOffice\PhpWord\TemplateProcessor($temp_path);
foreach ($this->data as $k => $v) {
$document->setValue($v['key'], $v['value']);
}
$file_path = $_SERVER['DOCUMENT_ROOT'] . '/file/' . date('Ymd');
if (!file_exists($file_path)) {
mkdir($file_path, '0777', true);
}
$save_path = $file_path . '/' . $this->file_name . '.docx';
$document->saveAs($save_path);
return $save_path;
}
function word2pdf($word_path)
{
if (!file_exists($word_path)) {
return -1;
}
$pdf_file = $_SERVER['DOCUMENT_ROOT'] . '/file/' . date('Ymd');
if (!file_exists($pdf_file)) {
mkdir($pdf_file, 0777, true);
}
$pdf_path = $pdf_file . '/' . $this->file_name . '.pdf';
if (file_exists($pdf_path)) {
unlink($pdf_path);
}
$word = new \COM("word.Application") or die("Could not initialise Object");
$word->Documents->Open($word_path);
$word->ActiveDocument->ExportAsFixedFormat($pdf_path, 17, false, 0, 0, 0, 0, 7, true, true, 2, true, true, false);
$word->Quit(false);
unset($word);
return $pdf_path;
}
public function pdf2img($pdf_path)
{
if (!file_exists($pdf_path)) {
return -1;
}
$img_file = $_SERVER['DOCUMENT_ROOT'] . '/file/' . date('Ymd');
if (!file_exists($img_file)) {
mkdir($img_file, 0777, true);
}
$img_path = $img_file . '/' . $this->file_name . '.png';
try {
$img = new Imagick();
$img->setCompressionQuality(100);
$img->setResolution(120, 120);
$img->readImage($pdf_path);
$canvas = new Imagick();
$imgNum = $img->getNumberImages();
foreach ($img as $k => $sub) {
$sub->setImageFormat('png');
$sub->stripImage();
$sub->trimImage(0);
$width = $sub->getImageWidth() + 20;
$height = $sub->getImageHeight() + 100;
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($img_path);
} catch (\Exception $e) {
return -1;
}
return $img_path;
}
public function add_water($img_path)
{
if (!file_exists($img_path)) {
return -1;
}
$date = date('Ymd');
$save_file = $_SERVER['DOCUMENT_ROOT'] . '/file/' . $date;
if (!file_exists($save_file)) {
mkdir($save_file, 0777, true);
}
$water_path = $_SERVER['DOCUMENT_ROOT'] . $this->sign_img;
if (!file_exists($water_path)) {
return -1;
}
$save_path = $save_file . '/' . $this->file_name . '_end.png';
$image = \think\Image::open($img_path);
$image->water($water_path, \think\Image::WATER_SOUTHWEST)->save($save_path);
return '/file/' . $date. '/' . $this->file_name . '_end.png';
}
}
调用代码
function get_img()
{
$sign_img = '你的签名图片路径';
$user_id = 1;
$user_data = [
['key' => 'name', 'value' => '十三'],
['key' => 'idcard', 'value' => '341022199909092525'],
['key' => 'phone', 'value' => '18888888888'],
['key' => 'time', 'value' => date('Y年m月d日')],
];
$word2img = new Word2img($sign_img, $user_id, $user_data);
$get_agreement_img = json_decode($word2img->get_img(), true);
if ($get_agreement_img['code'] != 1) {
return ajax_return(-1, $get_agreement_img['msg']);
}
$agreement_img = $get_agreement_img['data'];
}
注意,用宝塔搭建环境的话,防跨站攻击一定不要勾选,不要勾选,不要勾选。。。。。。
结束
|