昨天搞了个前端html转pdf的功能。略有所收,踩了一些坑,所以做些记录,为后来的兄弟做些提示。经过一番调研发现html导出pdf一般有这几种方式,各有各有优缺,下面简单介绍。
一、通过jsPdf实现
此种方案可以看昨天写的博客:jsPDF将html页面生成pdf文件的前端解决方案及html2canvas如何真正解决跨域图片的问题
主要就是利用html2canvas和jsPDF生成pdf文件,对于不分页的文件比较好,如果对于需要分页的文件,则不大适合。当然对于确实需要分页pdf文件,下面这个方法通过打印预览实现,也是不错的选择。
二、通过打印预览实现
通过打印预览来实现导出pdf并不是什么稀奇事,一般浏览器(Chrome)在页面手动Ctrl + P
都能将当前页进行打印预览。在打印预览的时候我们更改打印方式,选择将页面保存为PDF
即可实现页面保存为PDF的功能。
比如我们在谷歌进行Ctrl + P
就可以看到这个功能。而且对pdf分页还处理的挺好的。
程序中实现这个则要靠下面这个方法来实现:
window.print(); // 在控制台执行print()也能看到上面打印预览的效果
当然能导出PDF只是主要需求,我们还有一些其他的需求
- 只想将页面的一
部分导出为PDF
- 我们想导出的PDF是
A4纸大小
- 我们想导出的PDF是
竖着的
- 我们还想调整导出PDF的
样式等等
这些需求通过在对css中媒体查询
的定义就可以实现。具体可以看下这篇博客:通过CSS控制window.print打印样式浅析
@media print {
@page {
size: A4 portrait; // A4大小 纵向
}
.other-ele {
// 打印时将不需要的元素隐藏
display: none;
}
.pdf-title {
// 只在打印时候显示的元素
display: block;
}
.panel-sm {
// 打印时候改变某些元素的样式
margin: 0;
border: 1px solid #bce8f1;
}
}
需要提醒的是:如果要改变原有样式,最好是在元素上新加一个
class或者id来写,而不是在原有class上写。
比如有这样一个元素
<h1 class="title">我是PDF标题</h1>
// 打印时候要把这个字体大小设置成18px的话,我们不能这么写
@media print{
.title { // not work
font-size: 18px;
}
}
这样写是不起作用的。想要生效得在元素上新加一个class类写
<h1 class="title title-print">我是PDF标题</h1>
@media print{
.title-print {
font-size: 18px;
}
}
经过实践,这样写才可以生效。
有人可能觉得这样写略有麻烦,别担心,总有人会让麻烦的事情变得简单,基于window.print()
有人封装了一些插件:
PrintArea可以简单的实现部分区域打印,他的原理是通过把要打印的部分放入一个新的iframe然后触发这个iframe的print。这个插件不太稳定,会出现空白,请酌情使用。
jQuery.print比上面的稍微好点,支持了一些css方面的东西,具体看这个jQuery.print中文配置参数
这种方法前端实现,灵活简单,而且在页面还原上是很好
的,生成pdf的过程不需要自己操心
,页面样式还可控
,可以说是非常不错的。但是因为浏览器对print
方法的支持不一
,所以目前也就只能在Chrome上用用。另外,这个方法还需要用户点一下保存按钮,用户体验上也不太好
。
三、后端导出pdf
iText
、wkhtmltopdf
、prince
这三个都是后端生成pdf的工具。这三个都没有node api。
想看具体的比较可以参考这篇文章html页面导出为pdf(jsPDF、iText、wkhtmltopdf)。