文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

前端实现打印功能的两种方法详解

2023-01-06 12:01

关注

前言

前端实现打印功能的方法有很多,大家在网上随便一搜就是一大堆,在这里,我主要选择一个我觉得比较好一点的实现方式来进行解释描述:

方法一:window.print()   

这个命令默认打印整个页面的内容,所以,如果想要实现局部打印功能的话,就要重新给body赋值,并且后续执行完之后再还原回去,这样的话会造成一些非预期的结果,很麻烦,并且在当前也操作,window.document.body的内容重新渲染,打印完会有刷新,影响用户的体验,所以不推荐但还是简单介绍一下:

//(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;

方法二:利用iframe,iframe.contentWindow.print()

这个与方法一的区别就是,取消打印后可以完整保留当前访问页面的内容,不需要影响原页面,需要注意的是,在你生成新的iframe内的html时,样式可能会有影响加载不完全(全局样式特别),需要单独引入一些你自己的样式,我比较推荐这个,所以来重点说明一下:

// 1、获取需要打印的部分
const  printArea =  this.getElementById(document.body,"rx-form-container");
 
// 2、引入打印的专有CSS样式
var strStyleCSS="<link href='/rxform.css' type='text/css' rel='stylesheet'>";
var antdesignCSS="<link href='/antdesign.css' type='text/css' rel='stylesheet'>";
let printCSS=" <link href='/print.css' type='text/css'  rel='stylesheet'> ";
 
// 3、拼接字符串
var strFormHtml=strStyleCSS  +antdesignCSS + printCSS+"<body>"+domEl.innerHTML+"</body>";
 
// 4、创建 iframe 标签
var iframe = document.createElement('IFRAME');
var doc = null;
iframe.setAttribute('style','position:absolute;width:0;height:0;left:-500px;top:-500px;');
 
// 5、浏览器插入 iframe
document.body.appendChild(iframe);
doc = iframe.contentWindow.document;
// 引入打印的专有CSS样式
// doc.write("<LINK rel='stylesheet' type='text/css' href='/print.css'>");
doc.write(printHTML);
doc.close();
iframe.contentWindow.focus();
 
// 注意:等待加载完调用打印,否则样式外联css显示有问题
iframe.contentWindow.addEventListener('load', function() {
    // 6、开始打印
    iframe.contentWindow.print();
    // 7、删除iframe
    document.body.removeChild(iframe);
})

这样写虽然不会影响原页面,但是需要我们把打印的内容及样式用JS来生成,如果打印的内容很多,或者样式很复杂的话,那就是一个大工程,难免不方便,所以如何解决问题呢?我在查度娘的时候,发现了一种方式:将要打印的内容生成一个图片然后放在iframe中,利用html2canvas 生成截图,但是我并未校验(因为本人项目主要是打印表单流程,没有很复杂,嘻嘻),所以,这里我就简单复制一下大佬的,最后也放置了链接,如果有需要也可以去大佬博客看看:

    // 打印账单
    printBill () {
      this.printDisabled = true  // 点击打印按钮禁止重复点击
      setTimeout(_ => {      // 按钮显示为禁止了再去执行截图功能
        html2canvas(this.$refs.reconciliationWrapper, {
          backgroundColor: null,
          scale: 1.3
        }).then((canvas) => {
          let dataURL = canvas.toDataURL('image/png')
          this.$refs.iframe.contentWindow.document.body.innerHTML = ''  // 清空上一次打印的内容
          this.$refs.iframe.contentWindow.document.write('<html><head><style media="print">@page { margin: 0mm 10mm; }body{margin-top: 50px; text-align: center;}</style></head><body><img src=' + dataURL + '></body></html>')
          setTimeout(_ => {
            this.$refs.iframe.contentWindow.print()
          }, 0)
          this.printDisabled = false
        })
      }, 100)
    }

然后将截图放在iframe中的img打印,截图一般会有些模糊,调整html2canvas的参数scale,放大缩小的比例,要根据实际情况调整。

补充:导出步骤

1:引入html2Canvas 和 JsPDF

import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';

2:实现导出

export() {
    var printDom = document.getElementById('print');//获取打印的节点
    let opts: any = {
      useCORS: true, // 表示允许跨越的图片;allowTaint: true和useCORS: true选择一个
      // windowHeight: modal.scrollHeight + 24 + 100,//获取y方向页面包含滚动条的高度,24和100为padding,margin
      // width: dom.offsetWidth + 48,//48为padding值
      // height: dom.clientHeight + 400,//可见高度+padding+margin
      // y: window.pageYOffset + 100,//滚动条高度修复
      // scrollX: 17,
      scale: 1
    };
    //html2Canvas的作用是根据dom生成屏幕截图
    html2Canvas(printDom, opts).then(canvas => {
      let contentWidth = canvas.width;
      let contentHeight = canvas.height;
      let pageHeight = contentWidth / 592.28 * 841.89;
      let leftHeight = contentHeight;
      let position = 0;
      let imgWidth = 595.28;
      let imgHeight = 592.28 / contentWidth * contentHeight;
      let pageData = canvas.toDataURL('image/jpeg', 1.0);
      // landscape表示横向,portrait表示纵向
      let PDF = new JsPDF('portrait', 'pt', 'a4');//纵向
      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.save(`导出内容.pdf`);
    })
  }

总结:

打印的方式很多,大家选择适合自己项目的即可。就像王者荣耀,哈哈哈(肯定会有人突然疑惑,为什么会突然提到游戏,因为前两天我肯开心自己粉丝在增加,但是感觉自己博客不怎么生动,同事就给了我一个建议,可以说说王者荣耀,嘻嘻嘻,第一次说,以后不一定啥时候说),所以最后总结只有第一句话有用,后边大家随便看看就行,代码机器们,加油,在努力个四五十年,马上就可以退休了!!!

到此这篇关于前端实现打印功能的文章就介绍到这了,更多相关前端实现打印功能内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯