安装 TCPDF
composer require tecnickcom/tcpdf
use Imagick;
use TCPDF;
/**
* 生成PDF文档并转为jpg
* @param int $task_id 任务Id
* @return string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function generateReports($task_id = 1)
{
$taskInfo = $this->getTaskInfo($task_id);
if (!empty($taskInfo['report_url']) && 0) {
$report_url = $taskInfo['report_url'];
} else {
$taskLogList = $taskInfo['taskLogList'];
foreach ($taskLogList as $key => $item) {
if (empty($item['list']) || count($item['list']) < 2) {
unset($taskLogList[$key]);
}
if (!empty($item['list'][1]['sign_time'])) {
$hours = (($item['list'][1]['sign_time'] - $item['list'][0]['sign_time']) / 3600);
if ($hours < 2) {
unset($taskLogList[$key]);
}
} else {
unset($taskLogList[$key]);
}
}
$taskLogList = array_values($taskLogList);
$taskLogCount = count($taskLogList);
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// 设置文件信息
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor("ZhiShun");
$pdf->SetTitle("参与社会公益服务工作记录表");
$pdf->SetSubject('ZhiShun');
$pdf->SetKeywords('ZhiShun, PDF, 参与社会公益服务工作记录表');
// 删除预定义的打印 页眉/页尾
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
// 设置默认等宽字体
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
$pdf->SetMargins(PDF_MARGIN_LEFT, 0, PDF_MARGIN_RIGHT);
$pdf->setCellPaddings(0, 0, 0, 0);
$pdf->SetLineStyle(['width' => 0, 'color' => [255, 255, 255]]);
// 设置自动分页符
$pdf->SetFont('zh_cnhp15cn', 'I', 20);
$pdf->AddPage();
$pdf->SetAutoPageBreak(true);
$pdf->Cell(0, 30, '服务工作记录表', 0, 1, 'C');
$pdf->SetFont('zh_cnhp15cn', 'I', 16);
$pdf->Cell(0, 20, '姓名:' . $taskInfo['service']['username'] . ' 身份证号码:' . $taskInfo['service']['idcard'] .
' 联系电话:' . $taskInfo['service']['mobile'], 0, 1, 'C');
// 设置边框颜色
$pdf->SetDrawColor(0, 0, 0);
$pdf->SetLineWidth(0.1);
$pdf->Cell(36, 7, '服务类型', 1, 0, 'C');
$pdf->Cell(36, 7, '日期', 1, 0, 'C');
$pdf->Cell(55, 7, '地点', 1, 0, 'C');
$pdf->Cell(17, 7, '时长', 1, 0, 'C');
$pdf->Cell(36, 7, '见证人', 1, 0, 'C');
// dump(json_decode(json_encode($taskLogList)));exit;
if (!empty($taskLogList)) {
if($taskLogCount<5) {
$pdf->Ln();
$pdf->Cell(36, 60, '', 1, 0, 'C');
$pdf->Ln(0, true);
$pdf->Cell(36, 52, '道路交通', 0, 0, 'C');
$pdf->Ln(12, true);
$pdf->Cell(36, 52, '安全劝导', 0, 0, 'C');
}else{
$pdf->Ln();
$pdf->Cell(36, 12*$taskLogCount, '', 1, 0, 'C');
$pdf->Ln(0, true);
$pdf->Cell(36, 12*$taskLogCount-8, '道路交通', 0, 0, 'C');
$pdf->Ln(12, true);
$pdf->Cell(36, 12*$taskLogCount-8, '安全劝导', 0, 0, 'C');
}
foreach ($taskLogList as $key => $item) {
if (!empty($item['list'][1]['sign_time'])) {
$hours = (($item['list'][1]['sign_time'] - $item['list'][0]['sign_time']) / 3600);
if ($hours >= 2) {
$hours = '2小时';
} else {
$hours = '打卡时间不足,无法计算';
}
} else {
$hours = '缺勤,无法计算';
}
if ($key == 0) {
$pdf->Ln(-12, true);
$pdf->Cell(36, 12, '', 0, 0, 'C');
// 日期
$pdf->Cell(36, 12, $item['label'], 1, 0, 'C', false, '', 1);
// 地点
$pdf->Cell(55, 12, $item['list'][0]['place_text'], 1, 0, 'C', false, '', 1);
// 时长
$pdf->Cell(17, 12, $hours, 1, 0, 'C', false, '', 1);
// 见证人
$pdf->Cell(36, 12, $taskInfo['traffic_text'], 1, 0, 'C', false, '', 1);
} else {
$pdf->Ln(12, true);
$pdf->Cell(36, 12, '', 0, 0, 'C');
$pdf->Cell(36, 12, $item['label'], 1, 0, 'C', false, '', 1);
$pdf->Cell(55, 12, $item['list'][0]['place_text'], 1, 0, 'C', false, '', 1);
$pdf->Cell(17, 12, $hours, 1, 0, 'C', false, '', 1);
$pdf->Cell(36, 12, $taskInfo['traffic_text'], 1, 0, 'C', false, '', 1);
}
}
if($taskLogCount<5){
for ($i=0;$i<(5-$taskLogCount);$i++){
$pdf->Ln(12, true);
$pdf->Cell(36, 12, '', 0, 0, 'C');
// 日期
$pdf->Cell(36, 12, '', 1, 0, 'C', false, '', 1);
// 地点
$pdf->Cell(55, 12, '', 1, 0, 'C', false, '', 1);
// 时长
$pdf->Cell(17, 12, '', 1, 0, 'C', false, '', 1);
// 见证人
$pdf->Cell(36, 12, '', 1, 0, 'C', false, '', 1);
}
}
} else {
$pdf->Ln();
$pdf->Cell(36, 60, '', 1, 0, 'C');
$pdf->Ln(0, true);
$pdf->Cell(36, 52, '道路交通', 0, 0, 'C');
$pdf->Ln(12, true);
$pdf->Cell(36, 52, '安全劝导', 0, 0, 'C');
for ($i=0;$i<5;$i++){
if ($i == 0) {
$pdf->Ln(-12, true);
}else{
$pdf->Ln(12, true);
}
$pdf->Cell(36, 12, '', 0, 0, 'C');
// 日期
$pdf->Cell(36, 12, '', 1, 0, 'C', false, '', 1);
// 地点
$pdf->Cell(55, 12, '', 1, 0, 'C', false, '', 1);
// 时长
$pdf->Cell(17, 12, '', 1, 0, 'C', false, '', 1);
// 见证人
$pdf->Cell(36, 12, '', 1, 0, 'C', false, '', 1);
}
}
$pdf->Ln();
$pdf->Cell(36, 12, '接受安全教育', 1, 0, 'C', false, '', 1);
$pdf->Cell(36, 12, '', 1, 0, 'C');
$pdf->Cell(55, 12, '', 1, 0, 'C');
$pdf->Cell(17, 12, '', 1, 0, 'C');
$pdf->Cell(36, 12, '', 1, 0, 'C');
$pdf->Ln();
$pdf->Cell(180, 50, '', 1, 0, 'C');
$pdf->Ln(0, true);
$pdf->Cell(30, 15, '评价:', 0, 0, 'C');
$pdf->Cell(10, 30, '好', 0, 0, 'C');
$pdf->Cell(30, 30, '良好', 0, 0, 'C');
$pdf->Cell(30, 30, '合格', 0, 0, 'C');
$pdf->Cell(30, 30, '不合格', 0, 0, 'C');
$pdf->Ln(30, true);
$pdf->Cell(150, 15, '年 月 日', 0, 0, 'R');
$pdf->Ln(7, true);
$pdf->Cell(145, 15, '(印章)', 0, 0, 'R');
$pdf->Ln(22, true);
$pdf->Cell(20, 10, '备注:', 0, 0, 'L');
$pdf->Ln();
$pdf->Cell(150, 10, '1、自 年 月 日起3个工作日内到交警部门报到。', 0, 0, 'L');
$pdf->Ln();
$pdf->Cell(150, 10, '2、公益服务时长不少于5/7/9日,每天不少于2个小时,保证在15个工作日', 0, 0, 'L');
$pdf->Ln();
$pdf->Cell(150, 10, '内完成。自 年 月 日 至 年 月 日。', 0, 0, 'L');
$pdf->Ln();
$pdf->Cell(150, 10, '3、参与社会公益活动后,积极撰写参与公益活动的心得体会或悔过书, ', 0, 0, 'L');
$pdf->Ln();
$pdf->Cell(150, 10, '并提交检察机关。 ', 0, 0, 'L');
$pdf->Ln();
$pdf->Cell(150, 10, '4、报到地点及联系方式:', 0, 0, 'L');
$pdf->Ln();
$pdf->Cell(150, 10, '交警一大队:交警直属一大队事故处理中队', 0, 0, 'L');
$pdf->Ln();
$pdf->Cell(150, 10, '211办公室', 0, 0, 'L');
$pdf->Ln();
$pdf->Cell(150, 10, '警官 0000--0000000、0000000', 0, 0, 'C');
$report_url = ROOT_PATH . 'public/report/task_' . $task_id . $taskInfo['service_id'] . $taskInfo['traffic_id'] . $taskInfo['place_id'] . $taskInfo['user_id'];
$pdf->Output($report_url . ".pdf", "F");
$this->pdf2image($report_url . ".pdf", $report_url);
$report_url = str_replace(ROOT_PATH . 'public', '', $report_url) . '.jpeg';
$this->where('id', $task_id)->setField('report_url', $report_url);
}
return getFileFullUrl($report_url);
}
/**
* PDF2Image
* @param string $pdf 待处理的PDF文件
* @param string $path 待保存的图片路径
* @param int $page 待导出的页面 -1为全部 0为第一页 1为第二页
* @return string 保存好的图片路径和文件名
*/
function pdf2image($pdf, $path, $page = -1)
{
$fileArray = [];
// dump(extension_loaded('Imagick'));exit;
if (!extension_loaded('Imagick')) {
$this->error = 'Imagick扩展不存在';
return false;
}
if (!file_exists($pdf)) {
$this->error = dirname($pdf) . '文件不存在';
return false;
}
$images = new Imagick();
$images->setResolution(300, 300);
$images->setCompressionQuality(100);
try {
if ($page == -1) {
$images->readImage($pdf);
} else {
$images->readImage($pdf . "[" . $page . "]");
}
} catch (\Exception $e) {
write_log($e->getMessage());
}
foreach ($images as $key => $item) {
$item->setImageFormat('jpeg');
$item->setImageCompression(Imagick::COMPRESSION_JPEG);
$item->setImageCompressionQuality(100);
if (count($images) == 1) {
$filename = $path . '.jpeg';
} else {
$filename = $path . '_' . $key . '.jpeg';
}
$result = $item->writeImage($filename);
if ($result == true) {
$fileArray[] = $filename;
} else {
write_log($result);
}
}
if (count($fileArray) != 1) {
$this->spliceImg($fileArray, $path);
} else {
return $fileArray[0];
}
}
/**
* 合并图片
* @param array $images 图片数组
* @param string $filename 文件名
* @return string 将多个图片拼接为成图的路径
* 注:多页的pdf转化为图片后拼接方法
*/
function spliceImg($images = [], $filename = '')
{
ini_set('memory_limit', '1G');
//自定义宽度
$width = 2480;
//获取总高度
$pic_tall = 0;
foreach ($images as $key => $value) {
$info = getimagesize($value);
$pic_tall += $width / $info[0] * $info[1];
}
// 创建长图
$temp = imagecreatetruecolor($width, $pic_tall);
//分配一个白色底色
$color = imagecolorAllocate($temp, 255, 255, 255);
imagefill($temp, 0, 0, $color);
$target_img = $temp;
$source = array();
foreach ($images as $k => $v) {
$source[$k]['source'] = Imagecreatefromjpeg($v);
$source[$k]['size'] = getimagesize($v);
}
$tmp = 1;
$tmpy = 0; //图片之间的间距
$count = count($images);
for ($i = 0; $i < $count; $i++) {
imagecopy($target_img, $source[$i]['source'], $tmp, $tmpy, 0, 0, $source[$i]['size'][0], $source[$i]['size'][1]);
$tmpy = $tmpy + $source[$i]['size'][1];
//释放资源内存
imagedestroy($source[$i]['source']);
}
$return_imgpath = $filename . '.jpeg';
$result = imagejpeg($target_img, $return_imgpath);
if (!empty($result)) {
foreach ($images as $key => $value) {
@unlink($value);
@unlink($filename.'.pdf');
}
}
return $return_imgpath;
}
/**
* 获取文件完整连接
* @param string $value
* @return string
*/
function getFileFullUrl($value = '')
{
if (stripos($value, 'http') === 0 || $value === '' || stripos($value, 'data:image') === 0) {
return $value;
} else {
$upload = \think\Config::get('upload');
if (!empty($upload['cdnurl'])) {
return $upload['cdnurl'] . $value;
} else {
$http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
return $http_type . $_SERVER['HTTP_HOST'] . $value;
}
}
}
参考链接:
https://www.cnblogs.com/relix/p/4982919.html
https://www.kancloud.cn/potatog/tcpdf/1358504