使用html2canvas和jsPdf实现打印功能

摘要:
13if(isIframe){14dom=document.getElementById(printId).contentWindow.document.querySelector(“.flex container”)15}else{16dom=document.getElementById(printId);17}18letcopyDom=dom.cloneNode(true);

最近做项目中,️遇到过实现模版打印功能,网上也找到很多资料可以实现,有的方式可以实现分页,但是打印的A4纸上下不能留边距,后来找到一个通过剪裁的方式可以实现左右上下留边距,并且能实现分页;

方法如下:基本思路是对获得的canvas进行切割,按A4纸大小并留边距后的比例进行剪裁,切出一页一页的内容来,再分别加到pdf中。

DEMO:

  1 // 导出页面为PDF格式
  2 import html2canvas from "html2canvas"
  3 import JSPDF from "jspdf"
  4 export default {
  5   install(Vue, options) {
  6     /**
  7      * printId 打印区域id
  8      * isIframe 打印区域是否是iframe
  9      * childiframeIds 打印区域内包含的iframe的id
 10      */
 11     Vue.prototype.ExportSavePdf = async function (printId, isIframe, childiframeIds) {
 12       let dom;
 13       if (isIframe) {
 14           dom = document.getElementById(printId).contentWindow.document.querySelector(".flex-container")
 15       } else {
 16         dom = document.getElementById(printId);
 17       }
 18       let copyDom = dom.cloneNode(true);
 19       if (childiframeIds && childiframeIds.length > 0) {
 20         childiframeIds.forEach((fId) => {
 21           let iframeDom = document.getElementById(fId).contentWindow.document.querySelector(".flex-container");
 22           let copyIframeDom = iframeDom.cloneNode(true); // 复制iframe
 23           let copyIframeNode = copyDom.querySelector(`#${fId}`);
 24           let parentNode = copyIframeNode.parentNode;
 25           parentNode.removeChild(copyIframeNode); // 移除原有的iframe
 26           parentNode.appendChild(copyIframeDom);
 27           parentNode.style.height = iframeDom.scrollHeight + "px";
 28         })
 29       }
 30       copyDom.style.height = "auto";
 31       document.body.appendChild(copyDom);
 32       /* const [lWidth, rWidth] = [20, 20];
 33       const pageWidth = 595.28 - lWidth - rWidth // A4纸的宽高 减去左右边距
 34       const pageHeight = 841.89 */
 35       // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
 36       await html2canvas(copyDom, {
 37         logging: false,
 38          dom.scrollWidth,
 39         height: dom.scrollHeight,
 40         windowWidth: dom.scrollWidth,
 41         windowHeight: dom.scrollHeight
 42       }).then(function (canvas) {
 43         // 判断浏览器内核是否是IE
 44         if (!!window.ActiveXObject || "ActiveXObject" in window) {
 45           alert('截图打印暂不支持IE内核浏览器,请更换火狐或谷歌chrome内核浏览器,360等双核浏览器请切换至极速模式');
 46           return;
 47         }
 48 
 49         /* const contentWidth = canvas.width
 50         const contentHeight = canvas.height
 51         const pageData = canvas.toDataURL('image/jpeg/png', 1)
 52         const PDF = new JSPDF('', 'pt', 'a4') // , true
 53 
 54         // canvas图片的高
 55         const imgHeight = pageWidth / contentWidth * contentHeight // canvas的宽与PDF的宽比列一样的时候,canvas的高缩放后的值
 56         let leftHeight = imgHeight
 57         let position = 0
 58         // 如果图片的高小于A4纸的高,不分页
 59         if (leftHeight < pageHeight) {
 60           PDF.addImage(pageData, 'JPEG', lWidth, 0, pageWidth, imgHeight)
 61         } else {
 62           // 分页
 63           // let index = 0
 64           while (leftHeight > 0) {
 65             PDF.addImage(pageData, 'JPEG', lWidth, position, pageWidth, imgHeight)
 66             leftHeight = leftHeight - pageHeight
 67             position -= pageHeight
 68             if (leftHeight > 0) {
 69               PDF.addPage()
 70             }
 71           }
 72         }
 73         const link = window.URL.createObjectURL(PDF.output('blob'));
 74         window.open(link);
 75         document.body.removeChild(copyDom); */
 76         // const myWindow = window.open(link);
 77         // myWindow.print();
 78 
 79         var pdf = new JSPDF('p', 'mm', 'a4'); // A4纸,纵向
 80         var ctx = canvas.getContext('2d');
 81           var a4w = 190;
 82           var a4h = 277; // A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
 83           var imgHeight = Math.floor(a4h * canvas.width / a4w); // 按A4显示比例换算一页图像的像素高度
 84           var renderedHeight = 0;
 85 
 86         while (renderedHeight < canvas.height) {
 87           var page = document.createElement("canvas");
 88           page.width = canvas.width;
 89           page.height = Math.min(imgHeight, canvas.height - renderedHeight); // 可能内容不足一页
 90 
 91           // 用getImageData剪裁指定区域,并画到前面建立的canvas对象中
 92           page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight,
 93             canvas.height - renderedHeight)), 0, 0);
 94           pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height /
 95             page.width)); // 添加图像到页面,保留10mm边距
 96 
 97           renderedHeight += imgHeight;
 98           if (renderedHeight < canvas.height) { pdf.addPage(); } // 若是后面还有内容,添加一个空页
100           page.remove();
101         }
102         const link = window.URL.createObjectURL(pdf.output('blob'));
103         window.open(link);
104         document.body.removeChild(copyDom);
105       })
106     }
107   }
108 }

因为项目中打印的可能是iframe区域,也可以是当前窗口的body内,所以前面代码中有一些对dom的操作,

核心代码在后半部分;

效果如下:

使用html2canvas和jsPdf实现打印功能第1张

免责声明:文章转载自《使用html2canvas和jsPdf实现打印功能》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇visual studio 2019 插件安装(插件扩展名vsix).NetCore学习笔记:五、MiniProfiler监控运行效率下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Python之字符编码与文件操作

目录 字符编码 Python2和Python3中字符串类型的差别 文件操作 文件操作的方式 文件内光标的移动 文件修改 字符编码 什么是字符编码? ''' 字符编码就是制定的一个将人类的语言的字符与二进制数据一一对应地翻译过来的标准。 ''' 字符编码的发展史与分类: 计算机最早的字符编码为ASCII,只规定了英文字母、数字和一些特殊字符与数字一一...

mif文件生成方法

mif文件就是存储器初始化文件,即memory initialization file,用来配置RAM或ROM中的数据。常见生成方法: Quartus自带的mif编辑器生成 mif软件生成 高级编程语言生成 前两种方法都有一定的缺陷,主要介绍第三种方法,按照mif文件格式,使用高级编程语言(Matlab、C)编写生成。 注意: mif文件都是ASCⅡ码...

实战优化丨如何借助 CODING 实现云开发中的云函数的自动化部署

云开发中的云函数是云开发 Cloudbase 的一个重要的功能,开发者可以借助其中的云函数来实现一些复杂的业务逻辑,来实现诸如图片处理、数据处理等复杂的逻辑。同时,云函数的免运维、快速部署等特性也可以大大简化开发者的工作量,让开发者把更多的精力投放在业务逻辑的开发上。 在进行云开发中云函数的开发时,我们可能会经常重复“编写函数代码->部署”这个过程,...

oracle系统包——dbms_random用法

oracle中随机数的包的源文件目录:{oracle_home} dbmsadmindbmsrand.sql 1.返回0~1间的随机数(包括0和1)sql> select dbms_random.value from dual; 2.返回10~20间的随机数(包括10和20)sql> select dbms_random.value(10,20...

DFA算法 处理屏蔽词库

春节之后,回来就连着上班,没休息过来那.简单整下吧。 这里是lua实现的。直接上代码。 --敏感词库转化关键词 dfa算法处理屏蔽词库 require "sensitive_words" ---词库 local SensitiveWordsUtil = class('SensitiveWordsUtil') function Sensit...

Android实现简单的检测手机自由落体关闭屏幕

实现功能如下:在背景运行app,检测到自由落体状态时,熄灭屏幕,可重复测试。 1. 检测自由落体动作  需要使用到加速度感应器 TYPE_ACCELEROMETER SensorManager mSensorManager; private float mLastX; private float mLastY; private float mLastZ;...