前言
之前写过一篇 《Lumen生成PDF》 的文章,当时在生成 PDF 的时候,遇到了一些问题,并加以解决了。
前段时间,项目组中的小伙伴发现了一个好项目 wkhtmltopdf/wkhtmltopdf。
可以直接将 HTML 转换成 PDF,这跟我们之前的诉求一致。
Docker版
KnpLabs/snappy 是基于 wkhtmltopdf/wkhtmltopdf 扩展而来的 PHP 项目。
我们通过加工,将其做成一个服务。
环境信息
PHP7.4+swoolecomposersupervisorwkhtmltopdf 0.12.15
项目地址
文件内容
composer.json:
{ "name": "imjcw/wkhtml2x", "description": "html2pdf", "require": { "php": "^7.4", "knplabs/knp-snappy": "^1.2" } }
|
wkhtml2x.php:
<?php
include_once './vendor/autoload.php';
define('WKHTMLTOPDF', '/usr/bin/wkhtmltopdf');
$http = new \Swoole\Http\Server('0.0.0.0', 80);
$http->on('request', function (\Swoole\Http\Request $request, \Swoole\Http\Response $response) { $uri = $request->server['path_info']; if ($uri == '/pdf') { try { $content = $request->post['file'] ?? ''; if ($request->files['file'] ?? '') { $content = @file_get_contents($request->files['file']); } $url = $request->post['url'] ?? ''; if (!$content && !$url) { throw new \Exception('没有需要转换的内容'); }
$snappy = new \Knp\Snappy\Pdf(WKHTMLTOPDF, $request->post['options'] ?? []); $response->header('Content-Type', 'application/pdf'); if ($url) { $response->end($snappy->getOutput($url)); } else { $response->end($snappy->getOutputFromHtml($content)); } } catch (\Throwable $t) { $response->status(500); $response->end(str_replace('__ERROR__', $t->getMessage(), '<!DOCTYPE html><html><head><title>Internal Server Error</title></head><body><h1>Internal Server Error</h1><p>__ERROR__</p></body></html>')); } } else { $response->status(404); $response->end('<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>404 Not Found</h1></body></html>'); } });
$http->start();
|
使用方法
docker pull imjcw/wkhtml2x:latest
docker run -p 80:80 --name=wkhtml2x imjcw/wkhtml2x:latest
|
请求地址:127.0.0.1/pdf
请求方式:POST
请求参数:
| 参数 | 必填 | 说明 |
|---|
| file | 和 url 二选一 | 文件内容 |
| url | 和 file 二选一 | 网址 |
| options | 否 | PDF参数 |
其中,options 的一些定义,需要参考对应文档
wkhtmltopdf 官方参数文档:传送门
wkhtmltopdf Knp/Snappy 参数文档:传送门
返回的是文件流
待提升
目前支持了 pdf,并未支持 image 的生成。
容器因 swoole 变大了不少,而我们只是用了其中的一个小功能,这里也可以优化。
最后
处理问题的方式多种多样,在上次写 Lumen生成PDF 的时候,并没有想太多,在后续出现类似需求的时候,才发现做事情不能只顾眼前。
本文章观点仅代表个人立场,部分观点可能已过时,仅供参考。
本博客所有文章除特别声明外,均采用
CC BY-SA 4.0 协议,转载请注明出处!