当前位置: 首页 > Web前端 > HTML

html转pdf前端实现总结

时间:2023-04-02 21:05:27 HTML

最近会实现前端html转pdf功能。折腾了两天,有了一点收入,也踩了一些坑,所以做了一些记录,给后来的兄弟们做一些提醒,也算是回馈社会了。经过一番调查(sou)research(suo),发现html转pdf的方法一般有几种,各有优缺点,下面简单介绍一下。本文讲的是前端通过打印预览实现(重点)和后端通过插件jsPdf(凑数)iText、wkhtmltopdf、太子文本通过打印预览实现。通过打印预览导出pdf并不少见。浏览器(Chrome)可以在页面按Ctrl+P手动打印预览当前页面。在打印预览中,我们更改打印方式,选择页面另存为PDF,实现页面另存为PDF的功能。比如我这个时候按Ctrl+P就可以看到这个功能。这个在程序中的实现依赖于下面的方法:window.print();//在控制台执行print()也可以看到上面打印预览的效果。当然,导出PDF只是主要需求,我们还有一些其他的需求就是只将页面的一部分导出为PDF。我们要导出的PDF是A4纸大小。我们要导出的PDF是垂直的。我们还想调整导出的PDF的样式...这些需求在css中的mediaquery中通过定义即可实现@mediaprint{@page{size:A4portrait;//A4sizeportrait}.other-ele{//打印时隐藏不必要的元素display:none;}.pdf-title{//仅打印时显示的元素display:block;}.panel-sm{//打印时改变某些元素的样式margin:0;边框:1px实心#bce8f1;}}更多设置请参考:CSSPrintingBest实践中需要提醒的是:如果要改变原有的样式,最好给元素添加一个新的class或id,而不是在原有的上面写班级。比如有这样一个元素我是PDF的标题,如果我们想在打印的时候设置字体大小为18px,就不能这样写@mediaprint{.title{//无效font-size:18px;}}这样写是不行的。要生效,向元素添加一个新类并写入我是PDF标题@mediaprint{.title-print{font-size:18px;}}通过练习,这样写才能见效。库或插件有些人可能会觉得这样写有点麻烦,别担心,总有人会把麻烦的事情变得简单,如果这个人不是你,那一定是他。有人在window.print()的基础上封装了一些插件:PrintArea可以很方便的实现局部区域打印。它的原理是将需要打印的部分放到一个新的iframe中,然后触发这个iframe的打印。本插件不是很稳定,会有漏洞,请酌情使用。jQuery.print比上面的稍微好一点,支持一些css的东西。具体可以看这篇jQuery.print中文配置参数评估。这种方法前端实现灵活简单,在页面还原、生成pdf过程中都非常好用,过程不用自己操心,而且页面风格可控,可以说是非常好。但是由于浏览器对打印方式的支持不同(具体支持情况请点击这里),所以目前只能在Chrome上使用。另外,这种方式还需要用户点击保存按钮,用户体验不是很好。通过jsPdf介绍jsPdf是一个可以将html转pdf的插件,用的人很多。But,很多老外做的东西没有考虑过英文以外的语言(这个可以理解,我想做的一定是中文做的,日文英文阿拉伯文我不考虑),而这个东西是也不例外,它不支持中文,怎么办,很多兄弟都想到了一个办法:曲线救国|html2canvas+jsPdf既然你不支持中文,劳资懒得跟你废话了,劳资我把页面转成图片,你放心,图片会导出成PDF还在进行中!这种方法很普通也很简单,图片拉伸和模糊的问题比较多。最重要的是,这样导出的PDF是没有灵魂的,因为里面的内容都是图片,无法复制。因为没有灵魂,所以没有用这个方法。如果喜欢这种方法,可以参考这篇Javascript转html转pdf,下载,支持多页面(html2canvas和jsPDF)。它非常详细。硬撑|jsPDF-CustomFonts-support既然你不支持其他语言,那我就写个插件,等你支持了。做这个的是一个韩国的哥们,他写了一个插件jsPDF-CustomFonts-support,可以支持其他语言。原理大概是把你提供的字体文件转成base64格式,然后做成js文件,把这个js文件作为字体库。好吧,我喜欢这种强有力的方法。而且这种方式导出的pdf内容是可以复制的,算是一个惊喜吧。所以,我采用了这个方法。当时我就走这哥们的路。jsPDF生成pdf文件和中文编码。最好的做法是挂几个陷阱遇到的错误。jsPdf官网的api文档打不开。虽然文档页面打不开,但是在他的github仓库里有一个docs目录,目录里面有文档。那我们下载这个仓库,在本地打开docs/index.html查看文档,效果是一样的。jsPDF-AutoTabledemo的表格看起来不错,但是他没有提供代码,那我怎么看他是怎么实现的呢?demo的实现就在这个examples.js中,没有混淆,没有压缩,大家可以照葫芦画瓢的模仿一个demo表。如何生成自己的字体文件jsPDF-CustomFonts-support默认提供了字体文件,但是有很多汉字无法正常显示,需要自己生成字体文件。如何生成它?你需要这个:gitclonehttps://github.com/sphilee/jsPDF-CustomFonts-supportcdjsPDF-CustomFonts-supportnpminstallmvfontFilePath/fontName.ttf./jsPDF-CustomFonts-support/fonts/#putyouPrepare`.ttf`格式字体,放到`jsPDF-CustomFonts-support/fonts/`目录下节点makeFonts.js然后jsPDF-CustomFonts-support/dist/default_vfs.js就是你要的字体文件。UncaughtTypeError:jsPDFAPI.addFileToVFSisnotafunction这个错误报在jsPDF-CustomFonts-support中,因为jsPDF在1.4.0以下版本不支持addFileToVFS方法,所以最好的办法是用最新的jspdf版本替换掉以下版本的jspdf报告错误。Cannotreadproperty'widths'ofundefinedjsPDF-AutoTable报这个错误,是由于通过同时引入jspdf.customfonts.min.js和jspdf.customfonts.debug.js这两个文件,只引用其中一个即可。找不到jsPDF-AutoTablethead中的中文显示乱码的原因,但是找到了一个方法:隐藏thead,通过在tbody中设置tr第一行的样式来模拟thead。实现如下:doc.autoTable(columns,data,{showHeader:'never'});//直接评估html2canvas+jsPdf不显示头部的方法简单,但质量较差。jsPDF-CustomFonts-support方式虽然在质量上有优势,但是字体文件动辄几兆,甚至十几兆,这对于前端来说是一笔不小的开销,对性能影响很大。另外,导出PDF的两种方式都是点击导出后下载文件,不需要用户再次确认下载,是比较好的用户体验。后台导出pdfiText、wkhtmltopdf、prince都是后台生成pdf的工具。这三个都没有节点api。所以不多说了。如果想看具体对比,可以参考这篇文章将html页面导出为pdf(jsPDF、iText、wkhtmltopdf)。参考https://segmentfault.com/a/11...https://segmentfault.com/a/11...https://segmentfault.com/a/11...https://blog。csdn.net/JodenHe...https://blog.csdn.net/huyuyan...