设为首页 收藏本站
查看: 785|回复: 0

[经验分享] Docker 快速验证 HTML 导出 PDF 高效方案

[复制链接]

尚未签到

发表于 2019-2-20 07:40:19 | 显示全部楼层 |阅读模式
需求分析
  项目中用到了Echarts,想要把图文混排,当然包括 echarts 生成的 Canvas 图也导出PDF。
  设计和实现时,分析了 POI、iText、freemaker、world 的 xml 模版、Jquery-printArea.js、JQuery Plugin-TableExport、flying saucer 等等技术组合,不尽人意。甚至因为 echarts 不支持后端调用导出图片(没有简单易行的办法),一度考虑要在导出时用 JfreeCharts 重新画一遍图表。一是不能完整体现原有设计样式,二是工期不支持这么庞大的工作量(硬撸代码解析 html 生成 word 或 pdf。好吧,也同时觉得挺low的);
  最终选择了 wkhtmltopdf,实现了预期目标。整理成笔记,分享给大家。同时,发现docker hub 有 wkhtmltopdf 基于 apline 搭建的 web service 镜像,生产环境可以上Docker 的同学有福了,这应该是个更加高效的方案。后续考虑整合到支撑平台中,一并开源出来。

笔记本实验
  本地测试为 Mac Book,生产环境请自行评估调整。

下载和安装
  B4下,brew 仓库里居然没有,所以 brew install wkhtmltopdf安装报错。
  直接贴官方链接了:有依赖亲自行安装依赖;

验证

ChinaDreams:workspace kangcunhua$ wkhtmltopdf --version
wkhtmltopdf 0.12.4 (with patched qt)
测试
  联网抓取

ChinaDreams:~ kangcunhua$ wkhtmltopdf --header-center  '报表' --outline  --header-line --margin-top 2cm --header-line http://www.qq.com/  qq.pdf
  本地页面测试
index.html 见静态页面
  –zoom 4 是 Mac book 上实验出来的参数,这样页面是正常A4宽幅;在windows10、Suse 11 下不用加这个参数。
  toc 参数生成目录,包括左侧导航;—toc-header-text 自定义目录名;

ChinaDreams:~ kangcunhua$ wkhtmltopdf  --zoom 4 toc --toc-header-text "第四季度季报" index.html export.pdf
模拟商业环境
  我们拿到项目中实践验证下方案。商业项目,往往是残酷的要求,会遇到各种各样demo 时碰不上的挑战。
  思路还是先用 docker 神器,模拟商业环境,验证方案,然后再修订验证后的方案到正式项目环境验证。
  客户方提供的环境是 SuSE。我们先来看看是哪个版本

cat /etc/SuSE-release # 可以看到补丁版本
SUSE LINUX Enterprise Server 11 (x86_64)
VERSION = 11
PATCHLEVEL = 4
请 Docker 神器
  查找 SuSE 镜像,恰好有一个 11 版本的,下载镜像先

$ docker search SUSE # yuzhenpin/suse-11-sp3-x86_64-java
$ docker pull yuzhenpin/suse-11-sp3-x86_64-java
启动镜像

docker run --name suse-ep -it yuzhenpin/suse-11-sp3-x86_64-java /bin/bash
9e023776a1d5:/ # java -version
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
9e023776a1d5:/ # id
uid=0(root) gid=0(root) groups=0(root)
9e023776a1d5:/ # groupadd prms && useradd -d /prms -g prms -m prms
9e023776a1d5:/ # passwd prms
9e023776a1d5:/ # su prms
安装和配置
  因为下载的二进制版本的,直接把 wkhtmltopdf 拷贝进容器即可。index.html 是写的测试页面,后文附有源码:此文件用到的 jquery 相关 js 直接引用了 CDN,故实验在联网环境下进行的。

ChinaDreams:copy2docker kangcunhua$ docker cp wkhtmltox-0.12.4_linux-generic-amd64.tar.xz su-ext:/prms/workspace
ChinaDreams:copy2docker kangcunhua$ docker cp index.html su-ext:/prms/workspace
检查运行依赖
  使用 ldd 命令,not found 的就是对应的依赖包不存在:

7d183ecb0026:/prms/workspace/wkhtmltox/bin # ldd wkhtmltopdf
linux-vdso.so.1 =>  (0x00007ffe40bd2000)
libXrender.so.1 => not found
libfontconfig.so.1 => not found
libfreetype.so.6 => not found
libXext.so.6 => not found
libX11.so.6 => not found
libz.so.1 => /lib64/libz.so.1 (0x00007f9ca59ad000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f9ca57a9000)
librt.so.1 => /lib64/librt.so.1 (0x00007f9ca55a0000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f9ca5383000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f9ca507b000)
libm.so.6 => /lib64/libm.so.6 (0x00007f9ca4e02000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f9ca4bec000)
libc.so.6 => /lib64/libc.so.6 (0x00007f9ca4870000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9ca5bc5000)
安装依赖
  使用 zypper se 命令查找,根据查找结果,来安装需要的版本;

7d183ecb0026:/prms/workspace/wkhtmltox/bin # zypper se libXrender                                                                       
7d183ecb0026:/prms/workspace/wkhtmltox/bin # zypper install xorg-x11-libXrender
7d183ecb0026:/prms/workspace/wkhtmltox/bin # zypper se libfreetype     
7d183ecb0026:/prms/workspace/wkhtmltox/bin # zypper install libfreetype6
7d183ecb0026:/prms/workspace/wkhtmltox/bin # zypper se libXext
7d183ecb0026:/prms/workspace/wkhtmltox/bin # zypper install xorg-x11-libXext
7d183ecb0026:/prms/workspace/wkhtmltox/bin # zypper se fontconfig
7d183ecb0026:/prms/workspace/wkhtmltox/bin # zypper install fontconfig
7d183ecb0026:/prms/workspace/wkhtmltox/bin # zypper se libX11
7d183ecb0026:/prms/workspace/wkhtmltox/bin # zypper install xorg-x11-libX11
  需要在 html 代码中指定 font-face,所以需要一种支持中英文的字体。这里不指定的话,中英文都是黑色方框。因为不知容器使用的是何种字体,没找到 Suse 如何查看当前已有字体。从网下下载了文泉驿正黑,cp 了字体进来,发现是乱码,mv 重命名为tt.tff;cp 到字体目录。

7d183ecb0026:/usr/share/fonts # mkdir windows
7d183ecb0026:/prms/workspace # mv tt.ttf /usr/share/fonts/windows/
7d183ecb0026:/prms/workspace # ./wkhtmltox/bin/wkhtmltopdf index.html exp.pdf
QIconvCodec::convertToUnicode: using Latin-1 for conversion, iconv_open failed
QIconvCodec::convertFromUnicode: using Latin-1 for conversion, iconv_open failed
Loading pages (1/6)
Counting pages (2/6)                                               
Resolving links (4/6)                                                      
Loading headers and footers (5/6)                                          
Printing pages (6/6)
Done
和容器之间复制文件

ChinaDreams:copy2docker kangcunhua$ docker cp wkhtmltox-0.12.4_linux-generic-amd64.tar.xz su-ext:/prms/workspace
ChinaDreams:copy2docker kangcunhua$ docker cp index.html su-ext:/prms/workspace
ChinaDreams:copy2docker kangcunhua$ docker cp 文泉驿等宽正黑.ttf su-ext:/prms/workspace
ChinaDreams:copy2docker kangcunhua$ docker cp su-ext:/prms/workspace/exp.pdf .
商业环境实战
  待补充。
  2017.11.10update: 商业环境最大的挑战是内网。还有个挑战是客户使用的是SuSE Enterprise,这种情况下,如果缺少依赖,补丁包安装很麻烦。
  通过走手续,在内网申请了wkhtmltopdf二进制包,工程师传到测试环境,直接运行了测试命令,居然一条就过!依赖不缺,甚至中文字体也不缺。这只能说是运气。不过,凡事预则立,多准备一些,事情周密一些总是没错的。
  接下来,就是撰写个工具类调用shell命令了,可能还要考虑权限认证的问题。不过,从前台登录后的UI发起导出,应该不会存在需要认证的问题。
  皆大欢喜!

错误、参考和源码
  报错:SslHandshakeFailedError
笔记本实验时,报了个错。貌似也不影响最终需要的导出 PDF 结果。后来猜测应该是页面上有 button 或与打印无关的 js 导致的,删了就好了。国外的网友写了一个工具 carleton/moodle-scraper,也碰上了这个问题:这个错误貌似不是我第一个碰上,官方也没有修复。

moodle-scraper的KNOWN CURRENT ISSUES

WebToPDF
KNOWN CURRENT ISSUES:
1) "Issue found on page:wkhtmltopdf reported an error:
Mon Mar 28 20:51:52 unreg-30-152.dyn.carleton.edu wkhtmltopdf[3817] : CGContextSetShouldAntialias: invalid context 0x0"
As of Spring 2016 this problem has not been solved and seems to be a problem with whtmltopdf using a deprecated library of Mac OSX. Try it with Windows and see if it breaks?
Additionally, reported issue on GitHub: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2196
  报错信息:

Loading pages (1/6)
^C===========================>                               ] 48%
ChinaDreams:WebRoot kangcunhua$ wkhtmltopdf --disable-smart-shrinking index.html export.pdf
Loading pages (1/6)
QFont::setPixelSize: Pixel size

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-674590-1-1.html 上篇帖子: Docker(三十四)kubectl通过token 链接kube 下篇帖子: Docker 基础
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表