vue3+ElementUI html 导出Pdf
迪丽瓦拉
2024-05-30 15:53:21
0

文章目录

    • 1. 安装依赖
    • 2. 创建htmlToPdf.js
    • 3. 如何使用htmlToPdf.js

1. 安装依赖

主要用到以下两个依赖:

html2canvas:通过获取HTML的某个元素,然后生成Canvas,能让用户保存为图片。

jspdf:基于HTML5的客户端解决方案,用于生成各种用途的 PDF 文档。

npm i html2canvas jspdf --save

package.json

"dependencies": {"html2canvas": "^1.4.1","jspdf": "^2.5.1","vue": "^3.2.37"}

2. 创建htmlToPdf.js

/* eslint-disable */
//不使用JQuery版的
import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';/*** @param  ele          要生成 pdf 的DOM元素(容器)* @param  padfName     PDF文件生成后的文件名字* */function js_getDPI() {var arrDPI = new Array();if (window.screen.deviceXDPI != undefined) {arrDPI[0] = window.screen.deviceXDPI;arrDPI[1] = window.screen.deviceYDPI;}else {var tmpNode = document.createElement("DIV");tmpNode.style.cssText = "width:1in;height:1in;position:absolute;left:0px;top:0px;z-index:99;visibility:hidden";document.body.appendChild(tmpNode);arrDPI[0] = parseInt(tmpNode.offsetWidth);arrDPI[1] = parseInt(tmpNode.offsetHeight);tmpNode.parentNode.removeChild(tmpNode);}return arrDPI;
}export function getPdfUrl(ele, pdfName,callback){let eleW = ele.offsetWidth;// 获得该容器的宽let eleH = ele.offsetHeight;// 获得该容器的高let eleOffsetTop = ele.offsetTop;  // 获得该容器到文档顶部的距离let eleOffsetLeft = ele.offsetLeft; // 获得该容器到文档最左的距离var canvas = document.createElement("canvas");var abs = 0;let win_in = document.documentElement.clientWidth || document.body.clientWidth; // 获得当前可视窗口的宽度(不包含滚动条)let win_out = window.innerWidth; // 获得当前窗口的宽度(包含滚动条)if(win_out>win_in){// abs = (win_o - win_i)/2;    // 获得滚动条长度的一半abs = (win_out - win_in)/2;    // 获得滚动条宽度的一半}canvas.width = eleW * 2;    // 将画布宽&&高放大两倍canvas.height = eleH * 2;var context = canvas.getContext("2d");context.scale(2, 2);context.translate(-eleOffsetLeft -abs, -eleOffsetTop);// 这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此// translate的时候,要把这个差值去掉// html2canvas(element).then( (canvas)=>{ //报错// html2canvas(element[0]).then( (canvas)=>{html2canvas( ele, {// dpi: 300,width:eleW+135,height:eleH,// allowTaint: true,  //允许 canvas 污染, allowTaint参数要去掉,否则是无法通过toDataURL导出canvas数据的useCORS:true  //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。} ).then( (canvas)=>{var contentWidth = canvas.width;var contentHeight = canvas.height;//一页pdf显示html页面生成的canvas高度;var pageHeight = contentWidth / 592.28 * 841.89;//未生成pdf的html页面高度var leftHeight = contentHeight;//页面偏移var position = 30;//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高var imgWidth = 595.28;var imgHeight = 595.28/contentWidth * contentHeight;var pageData = canvas.toDataURL('image/jpeg', 1.0);var pdf = new JsPDF('', 'pt', 'a4');//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)//当内容未超过pdf一页显示的范围,无需分页if (leftHeight < pageHeight) {//在pdf.addImage(pageData, 'JPEG', 左,上,宽度,高度)设置在pdf中显示;pdf.addImage(pageData, 'JPEG', 30, 30, imgWidth, imgHeight);// pdf.addImage(pageData, 'JPEG', 20, 40, imgWidth, imgHeight);} else {    // 分页while(leftHeight > 0) {pdf.addImage(pageData, 'JPEG', 30, position, imgWidth, imgHeight);leftHeight -= pageHeight;position -= 841.89;//避免添加空白页if(leftHeight > 0) {pdf.addPage();}}}//可动态生成// pdf.save(pdfName);var buffer = pdf.output("datauristring");callback(buffer)})
}export function downloadPDF2(ele, pdfName,callback){let eleW = ele.offsetWidth;// 获得该容器的宽let eleH = ele.offsetHeight;// 获得该容器的高let eleOffsetTop = ele.offsetTop;  // 获得该容器到文档顶部的距离let eleOffsetLeft = ele.offsetLeft; // 获得该容器到文档最左的距离var canvas = document.createElement("canvas");var abs = 0;let win_in = document.documentElement.clientWidth || document.body.clientWidth; // 获得当前可视窗口的宽度(不包含滚动条)let win_out = window.innerWidth; // 获得当前窗口的宽度(包含滚动条)if(win_out>win_in){// abs = (win_o - win_i)/2;    // 获得滚动条长度的一半abs = (win_out - win_in)/2;    // 获得滚动条宽度的一半// console.log(a, '新abs');}canvas.width = eleW * 2;    // 将画布宽&&高放大两倍canvas.height = eleH * 2;var context = canvas.getContext("2d");// context.scale(2, 2);context.translate(-eleOffsetLeft -abs, -eleOffsetTop);// 这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此// translate的时候,要把这个差值去掉// html2canvas(element).then( (canvas)=>{ //报错// html2canvas(element[0]).then( (canvas)=>{html2canvas( ele, {// dpi: 300,width:eleW+135,height:eleH,// allowTaint: true,  //允许 canvas 污染, allowTaint参数要去掉,否则是无法通过toDataURL导出canvas数据的useCORS:true  //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。} ).then( (canvas)=>{var contentWidth = canvas.width;var contentHeight = canvas.height;//一页pdf显示html页面生成的canvas高度;var pageHeight = contentWidth / 592.28 * 841.89;//未生成pdf的html页面高度var leftHeight = contentHeight;//页面偏移var position = 30;//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高var imgWidth = 595.28;var imgHeight = 595.28/contentWidth * contentHeight;var pageData = canvas.toDataURL('image/jpeg', 1.0);var pdf = new JsPDF('', 'pt', 'a4');//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)//当内容未超过pdf一页显示的范围,无需分页if (leftHeight < pageHeight) {//在pdf.addImage(pageData, 'JPEG', 左,上,宽度,高度)设置在pdf中显示;pdf.addImage(pageData, 'JPEG', 30, 30, imgWidth, imgHeight);// pdf.addImage(pageData, 'JPEG', 20, 40, imgWidth, imgHeight);} else {    // 分页while(leftHeight > 0) {pdf.addImage(pageData, 'JPEG', 30, position, imgWidth, imgHeight);leftHeight -= pageHeight;position -= 841.89;//避免添加空白页if(leftHeight > 0) {pdf.addPage();}}}//可动态生成pdf.save(pdfName + '.pdf');callback()})
}

3. 如何使用htmlToPdf.js

App.vue为例,这样就得到了pdf-con范围内的PDF的base64Url, 可以转成file对象去做上传,提交给后端参数
在这里插入图片描述
调用此方法后浏览器就会直接下载PDF
在这里插入图片描述

相关内容