记一次wkhtmltopdf填坑经历

一年前产品提了一个让我们试着实现看看的需求,前端要支持用户将系统中java动态页面一键导出为pdf文件。当时项目组决定使用wkhtmltopdf这个第三方软件来实现。当时是由一位后端开发的同学来实现的,逻辑是前端点击按钮,后端生成动态文件,调用wkhtmltopdf生成pdf文件,存储在服务器中,并将文件地址返回给前端进行调用下载,并且要加上页眉页脚(页眉中包含客户商标)。逻辑图如下:

发送请求
生成动态文件
调用wkhtmltopdf生成pdf
返回pdf地址
下载pdf文件

总算是试着实现了,后来理所当然的三番五次接到各种生成pdf的需求了,wkhtmltopdf在系统中也开始渐渐“活跃”了起来,同时也bug不断。再后来, 由于人员变动,我承接了使用wkhtmltopdf的全部bug。

wkhtmltopdf相信用过的人大多数用过的人对其实又爱又恨。优缺点不多说了,用过的自然会明白。简单总结就是:功能强大,漏洞百出。

分割线---------------------------------

最近接到一个新需求,在动态页面中的过程变量(就是各种交互组件,涉及到产品保密不做多描述)需要支持用户设置宽高,其中图片有一种配置是上传后,如果配置了默认,则显根据图片原始大小显示。最近在对前端项目进行改造升级,毫不犹豫的使用了React作为输出渲染,功能实现的很愉快。

最终,从测试那里接到噩耗,生成pdf内容不全,甚至说没有内容。鉴于wkhtmltopdf的使用者较少,或者用来生成文件的目标页面几乎都比较简单,网上也没有太多的相关问题解答,于是本老中医根据病情列出了如下可能进行排查:

  1. javascript脚本执行太慢导致部分dom元素无法加载
  2. wkhtmltopdf版本太低
  3. 图片以及其他元素动态缩放引起的reflow导致页面加载迟缓
  4. wkhtmltopdf不支持动态页面或者react

第一个猜想很快被排除了,除了调整–javascript-delay参数以外,各种参数调整都无效
第二个猜想也很快排除,wkhtmltopdf已经停止维护好久了(年中的时候本打算替换为phantomjs来实现生成pdf的,结果刚要决定就接到其核心成员退出项目停止维护的噩耗)
第三个测试比较费力气,单个搭建动态页面进行测试,排除每一种动态缩放的可能,但是最终还是一样
第四个测试简单粗暴,先删除了react以及相关组件的引用,居然成功了。注意这里只测试了react。

于是当前晚上大张旗鼓,对前三天的功能进行重构,使用传统的javascript对图片过程变量进行了重构,好在轻车熟路,一晚上加上第二天一上午搞定了,编译+测试。。。。。。失败

最后冥思苦想,突然想到把动态页面里面的资源拷贝出来,存储成html文件在本地调用生成pdf,成功了!。在请教了部门老大(公司大牛)后,决定使用静态化过程进行处理,方案如下:

发起请求
生成动态页面
返回动态页面
获取动态资源
中间层服务存储为html
将静态化url传递给后端
生成pdf并下载

完美解决问题。不过为了赶项目,方案解决的优点仓促。有个弊端就是上行数据量太大,要修改中间层服务器的上传限制。完美的方案是应该把页面静态化和打印访问全部做在中间层中。当然这部分后来慢慢优化吧。

总结:
wkhtmltopdf对动态页面的支持效果一般,动态页面输出pdf的需求中最好不要有太复杂的javascript逻辑,尤其是一些比较大的视图框架(至少react是的)。加载的js文件最好不要太大。如果可以最好先静态化再输出。对于输出页面的样式,尤其是圆角等css3特性,能少则少,否则缺失个线条啥的都是家常便饭

记一次wkhtmltopdf填坑经历相关推荐

  1. 一次macOS的升级填坑(macOS Catalina - macOS Monterey)

    目录 小序 一.升级前操作 二.升级中 三.问题填坑 1.像我一样长时间卡在一个进度条怎么办 2.在更新途中重启过电脑(完整流程填坑) 3.安装之后不能开机,如何紧急拷贝资料 4.安装不成功,如何重新 ...

  2. 《Getting Started with D3》填坑之旅(六):第三章(下)

    Chapter 3. Scales, Axes and Lines(比例尺.坐标轴与线) (接上篇:<Getting Started with D3>填坑之旅(五):第三章(上)) 示例2 ...

  3. 【填坑】ESP32 bootloader初探(上)

    前言 大名鼎鼎的乐鑫ESP8266 WIFI模组你应该不陌生,不用我多说了.在这之后乐鑫还更迭了更多高性能的芯片型号,比如这次我要记录的ESP32-C3,搭载近期很火的RISC-V指令集处理器,支持2 ...

  4. 记一次完整的新浪云部署nodejs项目上线完整流程及填坑处理!

    工欲善其事,必先利其器.在开始本次部署新浪云nodejs项目之前,请先做好以下准备工作: 1.注册一个新浪微博账号! 2.使用注册好的新浪微博账号,登录新浪云网站:http://www.sinaclo ...

  5. Java web 开发填坑记 2 -如何正确的创建一个Java Web 项目

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/72566261 本文出自[赵彦军的博客] Java web 开发填坑记 1-如何正确 ...

  6. Android项目开发填坑记-Fragment的onAttach

    背景 现在Android开发多使用一个Activity管理多个Fragment进行开发,不免需要两者相互传递数据,一般是给Fragment添加回调接口,让Activity继承并实现. 回调接口一般都写 ...

  7. 【SAP PO】X-DOC:SAP PO 接口配置 REST 服务对接填坑记

    X-DOC:SAP PO 接口配置 REST 服务对接填坑记 1.背景 2.PO SLD配置 3.PO https证书导入 1.背景 (1)需求背景: SAP中BOM频繁变更,技术人员在对BOM进行变 ...

  8. 记一次成功把Vue2后台项目改造成Vite2的踩坑经历

    文章目录 前言 一.项目背景 1.1.为什么要选择Vite 二.迁移前的准备 2.1.补全.vue后缀 2.2.移动public/index.html的位置 2.2.1.通过vite-plugin-h ...

  9. 记一次 vivo x21 Android 8.1.1 调试Apk填坑

    项目做版本适配 项目在功能方面接近尾声的时候,轮到了适配工作,首先要解决 Android版本适配问题,也就是在不同安卓版本的机型上要跑起来无障碍.经过 20 多部手机测试,发现只有 vivo x21手 ...

  10. 共享内存 - shmget填坑记

    shmget设置的size值,不能大于最大值SHMMAX和小于最小值SHMMIN 且若是key值对应的段已经存在,那么后来使用shmget的size值要小于等于原来的值函 而后询问了一下那位程序猿,他 ...

最新文章

  1. webstorm2018修改运行web page端口号,并且让web在本地局域网内用IP访问
  2. vue 带全选和多选的表格怎么写_vue中使用计算属性巧妙的实现多选框的“全选”...
  3. 【GoldenGate】使用OGG,两个Oracle库之间单向同步数据
  4. LDD3源码分析之访问控制
  5. 代码没问题,请求无响应,超时
  6. golang基本数据类型和string的相互转换
  7. boost::mp11::mp_identity_t相关用法的测试程序
  8. OSI七层模型、数据封装与解封装过程、TCP三次握手、四次挥手
  9. springboot项目发布JAR包
  10. python数据分析环境搭建_教你零搭建Python数据分析环境
  11. python怎么把写在一个文件的类导入另一个文件_跟我一起自学python语言 第9章 类(9.4 导入类)...
  12. 【算法】排序_计数排序
  13. 算法:顺时针遍历矩阵 螺旋矩阵转换为顺时针列表spiral matrix
  14. 第十一周助教心得体会
  15. 天使、A轮、B轮……公司不同阶段估值方法大全
  16. 登录到接收邮件服务器(pop3):验证失败,Office2010的outlook pop3邮箱设置问题
  17. 图像算法(一):最近邻插值,双线性插值,三次插值
  18. Android 监听软键盘弹出/隐藏,控制软键盘弹出/隐藏
  19. ZOJ 1788 Quad Trees (四分树经典)
  20. IT人员升职必会的软技能

热门文章

  1. android 获取手机内存及SD卡内存可用空间
  2. 广义线性模型之指数分布族期望和方差的推导
  3. Linux技术——lsof命令详解
  4. 刨根系列 之 Unity3D UGUI 背后的工作原理
  5. 关于unity打包apk在手机上安装失败(-108)
  6. Massive MIMO简介
  7. 上海电力大学计算机专业全国排名,上海电力大学有哪些专业 上海电力大学专业排名...
  8. 如何提高下载速度(校园网怎么提高下载速度)
  9. 使用Git上传本地项目到GitHub
  10. 2021-05-22