0


纯前端--原生js将html页面变成pdf文件(html2canvas+jsPDF)

一、html2canvas – 将dom变成图片:

下载或者安装html2canvas:官网

1、将文档放在本地,用原生js进行引用和使用。

① 新建一个名为

html2canvas.min.js

的文件,并且将线上的内容进行复制。
② 引入 js 文件:

// js直接引入 -- 未尝试<script type="text/javascript" src="XXX/html2canvas.js"></script>// layui使用// 首先在html2canvas.js文件中添加exports
layui.define([],function(exports){// 复制的内容...exports('html2canvas',html2canvas);})// 其次进行自定义插件的引入
layui.define(['appsmenu'],function(exports){exports("conf",{// 第三方扩展extend:{// 引入html转图片的插件html2canvas:"lay/extends/html2canvas.min",}}})
2、使用
npm

进行安装使用:

待续。。。

二、jsPDF – 将图片变成pdf:

下载或者安装jsPDF :

  • github
  • 中文网站
  • CDN - Jspdf.es.js:ES 2015 模块格式。- Jspdf.umd.js:UMD模块格式,用于 AMD 或脚本标签加载。- Jspdf.polyfills.js:Internet Explorer等旧浏览器所需的兼容文件。
1、将文档放在本地,用原生js进行引用和使用。

① 新建一个名为

jsPDF.min.js

的文件,并且将线上(我找到的都不能用)或者资源 的内容进行复制。
② 引入 js 文件:

// js直接引入 -- 未尝试<script type="text/javascript" src="XXX/jsPDF.js"></script>// CDN引入 -- 未尝试<script type="text/javascript" src="https://cdn.staticfile.org/jspdf/2.5.1/jspdf.umd.min.js"></script>// layui使用// 首先在jsPDF.min.js文件中添加exports
layui.define([],function(exports){exports('jsPDF',jsPDF);})// 其次进行自定义插件的引入
layui.define(['appsmenu'],function(exports){exports("conf",{// 第三方扩展extend:{// 引入图片转pdf的插件jsPDF:"lay/extends/jsPDF.min",}}})
2、使用
npm

进行安装使用:

待续。。。

三、普通使用(html2canvas+jsPDF):

1、
layui

或者

原生js

使用:

// html:<div id="box"><button id="btn">下载为pdf</button>
    内容....</div>// js:// layui引入:
layui.define(['html2canvas','jsPDF'],function(exports){var html2canvas = layui.html2canvas;// 引入html转图片var jsPDF = layui.jsPDF;// 引入图片转pdf// 初始化varinit=function(){// 点击下载按钮
        document.getElementById("btn").onclick=function(){html2canvas(document.getElementById("box"),{allowTaint:false,// 是否允许跨域图像。会污染画布,导致无法使用canvas.toDataURL 方法backgroundColor:'#fff',// 画布背景色(如果未在DOM中指定)。设置null为透明useCORS:true,// 是否尝试使用CORS从服务器加载图像dpi:192,// 导出pdf清晰度scale: window.devicePixelRatio *3,// 用于渲染的比例。默认为浏览器设备像素比率。}).then(canvas=>{// html生成图片的数据var imageData = canvas.toDataURL('image/jpeg',1.0);// 原本的html页面的宽高const canvasWidth = canvas.width;const canvasHeight = canvas.height;// 当分辨率是72像素/英寸时,A4纸像素长宽分别是842×595var a4Width =595;// A4 宽度var a4Height =(595/ canvasWidth)* canvasHeight;// A4总高度// 生成pdf的一页显示html的高度let pageHeight = canvasWidth /595*842;// 未生成pdf的html页面高度,最初是整体的高度let restHeight = canvasHeight;// 页面上下偏移的大小var position =0;/**
                     * 参数1:方向:l:横向  p:纵向
                     * 参数2:单位:"pt"、"mm"、"cm"、"m"、"in"、"px"
                     * 参数3:格式:默认为a4
                    */var pdf =newjsPDF('p','pt','a4');// 当内容未超过pdf一页显示的范围,无需分页if(restHeight < pageHeight){/**
                         * 将图像添加到PDF中
                         * 参数1:图片的url
                         * 参数2:图片的格式
                         * 参数3:图片上下偏移的大小
                         * 参数4:原始宽度
                         * 参数5:原始高度
                        */ 
                        pdf.addImage(imageData,'JPEG',0, position, a4Width, a4Height );}else{while(restHeight >0){
                            pdf.addImage(imageData,'JPEG',0, position, a4Width, a4Height)
                            restHeight -= pageHeight;
                            position -=842;if(restHeight >0){// 在PDF文档中添加新页面
                                pdf.addPage();}}}// 保存为pdf格式的文件
                    pdf.save('生成的pdf文件.pdf')})}}var Class ={init:function(options){init();returnthis;}}exports('XXX', Class);)}
2、
vue/react

框架进行使用:

待续。。。

四、模块分割(html2canvas+jsPDF – 文字会截断,除了让后端做,没找到别的解决办法,感觉后端的插件比前端的更好用…):

参考链接:https://blog.csdn.net/qq_32244819/article/details/109678481

具体代码:
// 点击下载按钮
    document.getElementById("btn").onclick=function(){outPutPdfFn()}// 导出方法varoutPutPdfFn=function(){constA4_WIDTH=592.28;// A4纸的宽constA4_HEIGHT=841.89;// A4纸的高
        console.log('正在导出pdf,请稍候...');let target = document.getElementById('box');// 需要打印的页面的domlet pageHeight = target.scrollWidth /A4_WIDTH*A4_HEIGHT;// 根据比例换算一页的高度// 获取分割的dom,即class类名为splitItem的domlet splitItemAll = document.getElementsByClassName('splitItem');// 进行分割操作,当分块的内容超出a4纸的高度,则在这个块之前插入一个空白的块,将原有的块下移进行分割for(let i =0; i < splitItemAll.length; i++){// 计算当前模块需要分成几部分let modulesNum = Math.ceil((splitItemAll[i].offsetTop + splitItemAll[i].offsetHeight)/ pageHeight);if(isSplit(splitItemAll, i, modulesNum * pageHeight)){let divParent = splitItemAll[i].parentNode;// 获取当前需要分割块的父节点let newNode = document.createElement('div');
                newNode.className ='emptyDiv';
                newNode.style.background ='#ffffff';// 计算需要插入块的高度let _H = modulesNum * pageHeight -(splitItemAll[i].offsetTop + splitItemAll[i].offsetHeight);
                newNode.style.height = _H +'px';
                newNode.style.width ='100%';let nextDom = splitItemAll[i].nextSibling;// 获取当前需要分割块的下一个兄弟节点// 判断兄弟节点是否存在
                console.log(nextDom);if(nextDom){// 存在则将新节点插入到下一个兄弟节点的前面
                    divParent.insertBefore(newNode, nextDom);}else{// 不存在则直接添加
                    divParent.appendChild(newNode);}}}getPdf('导出pdf','box')}/**
     * 计算当前内容是否跨越了a4大小,以此分割
     * @params nodes 拿到的所有需要分割的dom
     * @params index 当前需要分割内容的索引
     * @params pageHeight A4纸的高度
    */varisSplit=function(nodes, index, pageHeight){// 当前需要分割的内容:内容高度+内容距离页面定位父元素(/body)的高度 < 页面的高度// 当前需要分割的内容的下一个兄弟节点:内容高度+内容距离页面定位父元素(/body)的高度 > 页面的高度if(nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight && nodes[index +1]&& nodes[index +1].offsetTop + nodes[index +1].offsetHeight > pageHeight){returntrue;}returnfalse;}// 导出pdfvargetPdf=function(title, dom){html2canvas(document.getElementById(dom),{allowTaint:false,// 是否允许跨域图像。会污染画布,导致无法使用canvas.toDataURL 方法backgroundColor:'#fff',// 画布背景色(如果未在DOM中指定)。设置null为透明useCORS:true,// 是否尝试使用CORS从服务器加载图像dpi:192,// 导出pdf清晰度scale: window.devicePixelRatio *3// 用于渲染的比例。默认为浏览器设备像素比率。增加清晰度}).then(canvas=>{// html生成图片的数据var imageData = canvas.toDataURL('image/jpeg',1.0);// 原本的html页面的宽高const canvasWidth = canvas.width;const canvasHeight = canvas.height;// 当分辨率是72像素/英寸时,A4纸像素长宽分别是842×595var a4Width =592.28;// A4 宽度var a4Height =(592.28/ canvasWidth)* canvasHeight;// A4总高度// 生成pdf的一页显示html的高度let pageHeight = canvasWidth /592.28*841.89;// 未生成pdf的html页面高度,最初是整体的高度let restHeight = canvasHeight;// 页面上下偏移的大小var position =0;/**
             * 参数1:方向:l:横向  p:纵向
             * 参数2:单位:"pt"、"mm"、"cm"、"m"、"in"、"px"
             * 参数3:格式:默认为a4
            */var pdf =newjsPDF('p','pt','a4');// 当内容未超过pdf一页显示的范围,无需分页if(restHeight < pageHeight){/**
                 * 将图像添加到PDF中
                 * 参数1:图片的url
                 * 参数2:图片的格式
                 * 参数3:图片上下偏移的大小
                 * 参数4:原始宽度
                 * 参数5:原始高度
                */ 
                pdf.addImage(imageData,'JPEG',0,0, position, a4Height );}else{while(restHeight >0){
                    pdf.addImage(imageData,'JPEG',0, position, a4Width, a4Height)
                    restHeight -= pageHeight;
                    position -=841.89;if(restHeight >0){// 在PDF文档中添加新页面
                        pdf.addPage();}}}// 保存为pdf格式的文件
            pdf.save(`${title}.pdf`)})}

五、echarts图表模糊的解决办法:

// 方法一:初始化echarts的时候,添加清晰度配置 devicePixelRatio
echarts.init(chartDom,null,{devicePixelRatio: window.devicePixelRatio *3});// 方法二:使用svg渲染,这个效果更好,就是需要调整grid,不然图表不完整// echarts.init(chartDom, null, { renderer: "svg" })
标签: javascript html pdf

本文转载自: https://blog.csdn.net/Y1914960928/article/details/131824887
版权归原作者 ᥬ 小月亮 所有, 如有侵权,请联系我们删除。

“纯前端--原生js将html页面变成pdf文件(html2canvas+jsPDF)”的评论:

还没有评论