前端实现 HTML 转 PDF 并导出

您所在的位置:网站首页 网页页面转pdf 前端实现 HTML 转 PDF 并导出

前端实现 HTML 转 PDF 并导出

2024-07-14 20:08| 来源: 网络整理| 查看: 265

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

主要介绍了前端实现 HTML 转 PDF 并导出的一些方法,包括浏览器自带的、vue-print-nb、html2canvas 和 jspdf,wkhtmltopdf 以及 iText

系统中使用了图形化报表,那么导出报表也是必不可少了,一般的导出形式就是pdf文件,对此,进行了一番研究,以下就是踩坑经验。

以如下报表页为例: ic_print.png

Window.print

官网地址:developer.mozilla.org/zh-CN/docs/…

详细使用可参考文档:window.print() 前端实现网页打印详解

这个是借助浏览器自带的打印来实现的,默认打印页面中 body里的所有内容,即全局打印,如果要局部打印,需要替换 body 的内容,会改变原网页内容,体验不是很好。

window.print

ic_print_1.png

vue-print-nb

官网安装及使用文档:www.npmjs.com/package/vue…

该插件本质上也是使用浏览器自带的打印 window.print()来实现的,默认会创建一个 iframe,将要打印的内容嵌入进去。相较第一个方法而言,更加灵活一点,但是样式的支持还是比较差的,ant design vue 组件的样式展示不全,需要自己去重写样式,这样就麻烦了呀。

// 1. 安装 npm install vue-print-nb --save // 2. 全局注册(main.js) import Print from "vue-print-nb"; Vue.use(Print); // 3. 使用 vue-print-nb ; var printObj = { id: "pdfDom", popTitle: "good print", extraCss: "https://www.google.com,https://www.google.com", extraHead: '', };

ic_print_2.png

html2canvas + jspdf

html2canvas:github.com/niklasvh/ht…

jspdf:github.com/parallax/js…

通过 html2canvas 将 HTML 页面转换成canvas图片,再通过 jspdf 将图片转成 pdf格式文件。

缺点:

清晰度不够 分页时,内容会被截断,不能智能展示完整 页面内容太长时(宽高限制为 14400),无法打印出内容,一直是空白页。这个真的就很不友好了呀,报表的内容肯定多呀...

ic_print_4.png

注意点:

引入外链图片时,需要配置图片跨域,给 img 标签设置 crossOrigin='anonymous'。 提高生成图片质量,可以适当放大 canvas 画布,通过设置 scale 缩放画布大小,或者设置 dpi 提高清晰度。 安装 npm install html2canvas jspdf --save 定义工具函数 // utils/htmlToPdf.js:导出页面为PDF格式 import html2Canvas from "html2canvas"; import JsPDF from "jspdf"; export default { install(Vue, options) { // id-导出pdf的div容器;title-导出文件标题 Vue.prototype.htmlToPdf = (id, title) => { const element = document.getElementById(`${id}`); const opts = { scale: 12, // 缩放比例,提高生成图片清晰度 useCORS: true, // 允许加载跨域的图片 allowTaint: false, // 允许图片跨域,和 useCORS 二者不可共同使用 tainttest: true, // 检测每张图片已经加载完成 logging: true, // 日志开关,发布的时候记得改成 false }; html2Canvas(element, opts) .then((canvas) => { let contentWidth = canvas.width; let contentHeight = canvas.height; // 一页pdf显示html页面生成的canvas高度; let pageHeight = (contentWidth / 592.28) * 841.89; // 未生成pdf的html页面高度 let leftHeight = contentHeight; // 页面偏移 let position = 0; // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高 let imgWidth = 595.28; let imgHeight = (592.28 / contentWidth) * contentHeight; let pageData = canvas.toDataURL("image/jpeg", 1.0); // a4纸纵向,一般默认使用;new JsPDF('landscape'); 横向页面 let PDF = new JsPDF("", "pt", "a4"); // 当内容未超过pdf一页显示的范围,无需分页 if (leftHeight < pageHeight) { // addImage(pageData, 'JPEG', 左,上,宽度,高度)设置 PDF.addImage(pageData, "JPEG", 0, 0, imgWidth, imgHeight); } else { // 超过一页时,分页打印(每页高度841.89) while (leftHeight > 0) { PDF.addImage(pageData, "JPEG", 0, position, imgWidth, imgHeight); leftHeight -= pageHeight; position -= 841.89; if (leftHeight > 0) { PDF.addPage(); } } } PDF.save(title + ".pdf"); }) .catch((error) => { console.log("打印失败", error); }); }; }, }; 全局注册 // main.js文件 import htmlToPdf from "./utils/htmlToPdf"; Vue.use(htmlToPdf); 使用 export default { methods: { handleExportPdf() { // 滚动到顶部,确��打印内容完整 document.body.scrollTop = 0; // IE的 document.documentElement.scrollTop = 0; // 其他 this.htmlToPdf("pdfDom", "统计报告"); }, }, };

ic_print_3.png

下一篇介绍wkhtmltopdf和iText踩坑



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3