2023 您所在的位置:网站首页 vue-iframe-print插件打印兼容性ie浏览器 2023

2023

2023-05-07 09:30| 来源: 网络整理| 查看: 265

WechatIMG11.jpeg

一、 需求期望

根据需求生成指定html结构,通过web端调用打印功能将其或者指定区域打印出来

二、 打印方式

1. 预览打印

  点击打印按钮以后,出现浏览器自带的打印预览设置面板,点击确认,进行页面打印

2. 直接打印(静默打印)

  无预览页面展示,直接调用打印机,打印相应内容

  注:预览打印方式在交互方式上不支持批量打印

三、 预览打印方式—实现方案

1. 基于Dom结构预览打印

  a) 整个页面全部打印

    i. 原理:调用window.print()

    ii. 优点:

      1. 无兼容性问题,展示效果完美,页面整体打印

    iii. 缺点:

      1. 无法指定区域打印,会打印当前全页面内容

  b) 预览打印指定区域

    i. 当前窗口直接打印指定区域

      1. 原理:

代码示例:

//(1)首先获得元素的html内容(这里建议如果有样式最好是用内联样式的方式) var newstr = document.getElementById(myDiv).innerHTML; //得到需要打印的元素HTML //(2)保存当前页面的整个html,因为window.print()打印操作是打印当前页的所有内容,所以先将当前页面保存起来,之后便于恢复。 var oldstr = document.body.innerHTML; //保存当前页面的HTML //(3)把当前页面替换为打印内容HTML document.body.innerHTML = newstr; //(4)执行打印操作 window.print(); //(5)还原当前页面 document.body.innerHTML = oldstr; },

      2. 缺点:

        a) 实现方式的特殊性,会导致当前页面状态重置,用户体验不好

    ii. 打开新窗口,在其中预览指定内容然后打印

    iii. 当前窗口内嵌iframe,或者弹框iframe,在iframe中预览指定内容,然后打印

      1. 原理:

代码示例:

//id-str 内容中的id printPart( id_str ) { var cssStr = this.getCssBlock(); console.log(cssStr); var cssStyle = document.createElement("style"); cssStyle.type = "text/css"; cssStyle.innerHTML = cssStr; var el = document.getElementById(id_str); var iframe = document.createElement("IFRAME"); var doc = null; iframe.setAttribute( "style", "position:absolute;width:0px;height:0px;left:-500px;top:-500px;" ); document.body.appendChild(iframe); doc = iframe.contentWindow.document; doc.getElementsByTagName("head")[0].appendChild(cssStyle); doc.body.innerHTML = "" + el.innerHTML + ""; // doc.write("" + el.innerHTML + ""); doc.close(); iframe.contentWindow.focus(); iframe.contentWindow.print(); if (navigator.userAgent.indexOf("MSIE") > 0) { console.log("------"); document.body.removeChild(iframe); } document.body.removeChild(iframe); }, // 获取vue文件中的style标签中的样式 getCssBlock() { const cssBlock = document.styleSheets; console.log(cssBlock); const styleData = [...cssBlock].reverse().find(({ cssRules }) => { return [...cssRules].find((rule) => { return ["#test-p"].includes(rule.selectorText); }); }); return styleData.ownerNode.innerText; },

      2. 优点

        a) 打开新窗口和当前窗口内嵌iframe方式,可以指定打印区域

        b) 不会影响当前页面的页面状态

      3. 缺点

        a) 打开新窗口和当前窗口内嵌iframe方式,都是产生了新窗口,新窗口不会复用当前窗口的css样式,需要为新窗口和iframe注入打印内容的css样式

        b) 获取指定打印区域css样式,有很多不确定因素

    iv. 使用print.js插件

      1. Print.js:

        a) 大小:128 kB

        b) Github-star:3.6k

      c) 仓库地址:https://github.com/crabbly/Print.js

      文档地址:https://printjs.crabbly.com/#documentation

      2. 原理:

        原生js,将打印模块的dom和style样式(style/link)写入iframe,然后调用document.execCommand(”print”)进行打印

代码示例:

// print-js 分页样式表现比较好 printMedical(idStr) { // 调用打印插件,配置项参考官网:https://printjs.crabbly.com/ print({ // printable为需要打印的DOM的id printable: idStr, // type为需要打印的类型 type: "html", // css为样式文件或者直接css样式,支持导入整个css文件,或者css文件数组 // css: medicalStyle, // 可选项,这样配置意味着应用所有导入的css文件 targetStyles: ["*"], }); },

      3. 优点:

        a) 逻辑简单,展示效果完美

        b) 支持打印的类型多:PDF、HTML、IMAGE、JSON

        c) 支持行内样式与外联样式,再也不用在DOM元素上写满样式了

        d) 兼容性好,除了IE不支持PDF和IMAGE打印外,其余主流浏览器全部支持

      4. 缺点:

        a) 需要引入第三方插件,受控性不友好

        b) 可能会出现的样式异常

        c) 无法直接打印/静默打印,因为是调用chrome打印,还是会弹出打印预页面

2. 将Dom结构转换为pdf预览打印

    a) 原理:

      html2canvas+jsPDF 通过html2canvas将遍历页面打印元素,并渲染生成canvas,然后将canvas图片格式添加到jsPDF实例,生成pdf,插入到iframe,然后打印

代码示例:

downPdf(idStr) { html2Canvas(document.querySelector(idStr), { // onrendered: background: "#0B1A48", }).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; // pdf页面偏移 var position = 0; // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高 var imgWidth = 595.28; var imgHeight = (592.28 / contentWidth) * contentHeight; var pageData = canvas.toDataURL("image/jpeg", 1.0); // eslint-disable-next-line var pdf = new jsPDF("", "pt", "a4"); // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89) // 当内容未超过pdf一页显示的范围,无需分页 if (leftHeight < pageHeight) { pdf.addImage(pageData, "JPEG", 0, 0, imgWidth, imgHeight); } else { while (leftHeight > 0) { pdf.addImage(pageData, "JPEG", 0, position, imgWidth, imgHeight); leftHeight -= pageHeight; position -= 841.89; // 避免添加空白页 if (leftHeight > 0) { pdf.addPage(); } } } // 导出pdf文件命名 // pdf.save("report_pdf_" + new Date().getTime() + ".pdf"); const iframe = document.createElement("iframe"); iframe.setAttribute( "style", // "position:absolute;width:0px;height:0px;left:-500px;top:-500px;" "display:none" ); iframe.src = pdf.output("bloburl"); document.body.appendChild(iframe); iframe.contentWindow.focus(); iframe.contentWindow.print(); // iframe.contentWindow.document.close(); // document.body.removeChild(iframe); // const myWindow = window.open(pdf.output("bloburl")); // myWindow.print(); }); },

    b) 优点:

      i. 可以设置分页和不分页

      ii. 可以对多页内容添加页眉页脚

    c) 缺点:

      i. 需要引入两个第三方插件html2canvas+jsPDF

      ii. 前端生成pdf不太友好,会有一定的性能问题

      iii. 由于浏览器的样式差异化,转换后可能会出现样式不统一问题

      iv. 分页逻辑不好控制,会出现展示效果不理想

3.将Dom结构转换为image,然后预览打印

  a) 原理:

    将打印内容html利用html2canvas生成canvas 通过canvas.toDataURL('image/jpeg', 1.0)生成图片,插入到iframe中预览打印

代码示例:

// 生成图片插入到iframe中,然后预览打印 printBill() { this.printDisabled = true; // 点击打印按钮禁止重复点击 setTimeout(() => { // 按钮显示为禁止了再去执行截图功能 html2Canvas(this.$refs.reconciliationWrapper, { backgroundColor: null, // scale: 1, }).then((canvas) => { let dataURL = canvas.toDataURL("image/png"); this.$refs.iframe.contentWindow.document.body.innerHTML = ""; // 清空上一次打印的内容 this.$refs.iframe.contentWindow.document.write( '@page { margin: 0mm 10mm; }body{margin-top: 50px; text-align: center;}


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有