目录
一、需求描述
二、使用 jspdf + html2canvas 导出遇到的问题
三、window.print() 导出具体实现 【api: toHtml】
一、需求描述
将 AoMao Editor 富文本插件中的内容导出为PDF。
二、使用 jspdf + html2canvas 导出遇到的问题
试了很多插件,但 angular 能用的插件很少,网上比较多的方案是使用 html2canvas 截取内容后,再使用 jspdf 导出 PDF。
这个方案的 优点 是:① 可以选定范围;② 原样式输出,因为是以截图的方式导出,所以 amoao 文本引擎中渲染的样式也能导出(即页面展示什么,导出的PDF内容也是什么样);
缺点 是:① 无法分页,因为 aomao 的内容是 h5 格式的,长度不定,且以截图方式截取,所以会存在一行文字被切开在两页上的情况(如图)
② 图片导出有问题,我用的 Chrome 浏览器,导出包含图片的文档内容时,图片会丢失,报错是跨域。但我图片服务器已经设置了跨域,查了半天还是报错,所以感觉是插件的问题。后面找到了一个改源码的帖子(html2canvas截图时 不能使用跨域图片的解决方案_node_modules中没有html2cannvas-CSDN博客),跟着改了源码,试了一下可以用,但就出现了下面的清晰度问题。【后面也试了一下其他浏览器,火狐浏览器不用改源码也可以导出图片,所以我也不清楚到底是哪里有问题】
③ 导出清晰度有问题,html2canvas 有一个参数 scale 设置缩放,默认是1,使用改了源码的 html2canvas 能导出所有图片,但导出的 PDF 会不清晰;当设置 scale = 2 时,导出的 PDF 变清晰了,但又出现了新的问题,文档中所有的图片不能都导出来(例如文档有 15张图,只能导出 10张,后面的就丢失了)
④ 导出的PDF无法复制,还是因为是截图的方式导出,所以导出的 PDF 内容无法复制。
三、window.print() 导出具体实现 【api: toHtml】
找了半天,最终找到了一个使用 浏览器 原生方法导出 PDF 的方案: window.print()。
这个方案的 优点 是:① 能分页,原本就是浏览器的打印方法,能分页应该很正常吧(如图)
② 图片导出没问题,因为是使用浏览器的加载方法,所以加载图片不存在跨域的问题,自然导出图片也没有问题。
唯一的缺点是:无法指定范围,这个方法默认是导出当前页面的所有内容的,所以无法只导出页面中 aomao 文本插件的内容。
但这个缺点是可以解决的!那就是把 aomao 文本插件的内容导出来,然后新建一个页面,把导出来的内容填充到新页面,再使用 window.print() 方法将新页面导出 PDF
实现如下:
public exportPdf() {
const textContent = this.engine.model.toHTML();
const pageStandard = ' <!DOCTYPE HTML><HTML><head><meta charset="UTF-8"><title>' +
this.documentTitle + '</title></head>' +
'<body><h1 style="padding: 0px 45px; margin-top: -10px;">' + this.documentTitle +'</h1>' +
'<div style="padding: 0px 55px;">' + textContent + '</div>' +
'</body></HTML>';
let newWindow = window.open("", "_blank");
newWindow.document.write(pageStandard);
newWindow.document.close();
newWindow.print();
}
代码解释:
① 使用 aomao 的 api toHTML 可以将文本插件的内容和样式导出来;
② 拼接一个基础的 html 页面,设置<title>,导出PDF的时候文件名默认就是设置的 title 名称;
③ window.open("", "_blank") 打开一个新页面,对原页面没有任何影响(网上有方案是在原页面上操作的,实测操作完会对原页面功能产生影响)