前端生成pdf?jspdf+html2canvas实现pdf预览和导出

最近做后台系统遇到挺多复杂的需求,比如导出pdf,word,excel
一般这种需求后端如果存文件,然后传个流过来,前端就可以下载导出了。
但是如果后端不存文件,只返回字符串(富文本字符串),这时候咋办?
= =不知道,但是我遇到了,也只能头铁干了。


吃货镇楼

路还是有的,讲一下实现方式:

html2canvas+jspdf

具体需求是在弹窗内预览,然后点击下载可以生成对应pdf,预览pdf如果后端没有给文件地址,只返回富文本字符串(类似"

123

"),比较难做,但是办法还是有的,个人感觉难点在于html2canvas生成完整截图的时机和pdf的分页。
贴一下效果:


预览弹窗
生成的pdf文件

思路:由于pdf不可直接编辑,个人思路是先将html截屏转化成图片,再把图片嵌入生成pdf。

  1. html2canvas:直接npm i html2canvas -S ,用法是截图dom然后转化为canvas,具体api可以去github上看。
  2. jspdf(项目编译报错所以选了个特定的版本):https://cdn.bootcss.com/jspdf/1.5.3/jspdf.debug.js

直接贴代码(项目用的是elementUI,核心代码在preview2pdf这个方法):






母猪焊接

遇到坑,注意的点

  1. 控制pdf页面大小取决于html2canvas截图dom的样式,例子中是 .preview-data 这个类,可以观察其中的css样式,其中z-index为负一的原因是html2canvas截图只能截可视dom元素,如果display:none或者是克隆出来的虚拟dom,都截不了,所以只能采取让元素看不见的方法来取巧。

  2. 由于后台返回的是富文本字符串,所以渲染的内容代码用innerHTML赋值了,赋值后dom还未渲染,此时不能立即使用html2canvas截取,需要等dom更新完成再截取,这就是调用vue.$nextTick的原因。

  3. 关于pdf分页问题:position 这个变量控制第二页的偏移位置,即利用偏移制造假分页,实际上pdf渲染出来的东西都在同一页上,只是按高度切割后,把剩余的内容合理偏移,使得看来像分页了而已。
    分页参考: https://blog.csdn.net/weixin_43720095/article/details/87358705

4.预览和下载pdf:jspdf很强大,有一个output('datauristring')的方法,可以生成一个dataurl外链,把它带给iframe标签或者embed标签src就可以在线预览(后台直接返回pdf地址也是这种方法预览),下载则更为简单,调用save方法即可。

你可能感兴趣的:(前端生成pdf?jspdf+html2canvas实现pdf预览和导出)