vue 打印html <iframe>标签(内容打印)超详细

前言

今天领导给了个需求,需要配合其他项目组给一个公共组件的npm进行,公共组件打印,打印操作由这个npm包来操作。(经过开会商讨,最后决定配置一个path路径,来展示页面,然后我负责在公共这里打印相应页面内容。)在这之初都是好着的,首先进行配置,这里只需要一个input框来给后端传值就可以了,这一步没什么好讲的,

正传

好了 正头戏开始了,通过请求在mounted中发送请求,获取到配置好的 path路径,开始我想着用路由进行编写后来发现过于麻烦,选择了iframe标签来进行编写,(这里再说一下留下来的需求,需要弹窗然后展示其他组要展示的内容)这里选择了iframe ,然而iframe的src值如果不是本项目页面的话 是会报跨域的,so(幸好我们是同一个域名同一个端口号) 这里我对src 路径的最前面的地址进行处理,编写一个 获取域名以及端口号等的一个过滤方法,方法如下:

 // 获取http域名
  urlhttp() {
  console.log(window.location.href, "window.location.href");
   // 截取域名前面的部分
  const url = window.location.href.split("://")[1];
  const urlhttp = window.location.href.split("://")[0];
  const urlArr = url.split("/");
  const urlStr = urlArr[0];
  const urlStrArr = urlStr.split(".");
  const urlStrArrLen = urlStrArr.length;
  const urlStrArrLenLast = urlStrArrLen - 1;
  const urlStrArrLenLastStr = urlStrArr[urlStrArrLenLast];
  const urlStrArrLenLastStrLen = urlStrArrLenLastStr.length;
  const urlStrArrLenLastStrLenLast = urlStrArrLenLastStrLen - 1;
  const urlStrArrLenLastStrLenLastStr = urlStrArrLenLastStr[urlStrArrLenLastStrLenLast];
  const urlStrArrLenLastStrLenLastStrNum = Number(urlStrArrLenLastStrLenLastStr);
  if (urlStrArrLenLastStrLenLastStrNum) {
    this.urlStr = urlStrArr[urlStrArrLenLastStrLenLastStrNum];
  } else {
    this.urlStr = urlStrArr[urlStrArrLenLastStrLenLastStr];
  }
  console.log(urlhttp + urlStr, "urlStr");

  // 截取域名带http+域名
  this.urlhttpStr = urlhttp + "://" + urlStr;
  console.log(this.urlhttpStr, "urlhttpStr");
},

通过次方法,对页面域名进行格式化,其中window.location.href 获取的是当前地址框的所有地址,然后通过.split(" : / / " )[1];等进行数据的获取,最终得到:http://localhost:8080 这种地址,
从而拼接起来我配置的 iframe的src地址拼接后,弹窗展示了相应的页面,

然后在弹窗上给一个打印按钮(重头戏来了) 我先对iframe标签进行ref的设置,从而获取该节点,然后我将

const contentWindow = iframe.contentWindow.document;

节点进行赋值,拿到后直接打印该节点,
调用 contentWindow.print(); 方法,发现打印信息不全的情况,然后我通过翻阅资料方得知 会有样式排版等一些问题导致至此,所以次方法pass,过,后又发现可以通过创建新的页面进行展示打印,然后我调用

  const printWindow = window.open("", "_blank");
   printWindow.document.write(`
<html>
<body>
</body>
</html>
`);

去创建新页面,在新页面中执行打印方法

printWindow.document.close();
printWindow.print();

然后发现打印后,我iframe中的打印的东西消失了,然后我便复制一个子节点然后再用子节点打印

const childElementcopy = childElement.cloneNode(true); // 复制元素

发现奏效了,但是没有css样式,我开始便利子节点的样式

	Array.from(sourceComputedStyle).forEach(style => {
const value = sourceComputedStyle.getPropertyValue(style);
printElement.style.setProperty(style, value);
});

但是次方法未奏效,尝试了好多办法后,我查看元素时候发现 style标签我可以直接copy旗下所有元素啊 然后便复制了一份,一起加入打印的新页面,至此完成次需求,下面是全部代码

  async submitPrint() {
  const iframe = this.$refs.myIframe;
  console.log(this.$refs.myIframe, "this.$refs.myIframe");
  const contentWindow = iframe.contentWindow.document;
  const head =  contentWindow.querySelector("head")
  // 访问iframe的子元素
  const childElement = contentWindow.getElementById(this.printLocation) || contentWindow.getElementsByClassName(this.printLocation)[0]
  //this.printLocation是我后配置的要打印模块的id
  console.log(childElement);
  const childElementcopy = childElement.cloneNode(true); // 复制html元素
  const headcopy = head.cloneNode(true); // 复制css 样式元素元素

  const printWindow = window.open("", "_blank");
  // 在前确保先监听
  printWindow.document.write(`
  <html>
  <body>
  </body>
  </html>
	`);
      const printBody = printWindow.document.querySelector("body");
      const printhead = printWindow.document.querySelector("html");
      printhead.appendChild(headcopy);
      printBody.appendChild(childElementcopy);

  printWindow.onafterprint = function() {
    // 在打印对话框关闭后执行的逻辑
    console.log("打印对话框已关闭");

    // 判断用户是否点击了取消按钮
    var printResult = window.matchMedia("print");
    if (printResult.matches) {
      console.log("用户点击了取消按钮");
      // 执行取消打印的相关逻辑
      printWindow.close(); // 关闭新页面
    } else {
      console.log("用户点击了打印按钮");
      // 执行打印操作的相关逻辑
      printWindow.close(); // 关闭新页面
    }
  };

  setTimeout(() => {
    printWindow.document.close();
    printWindow.print();
  }, 500);
  // const printBody = printWindow.document.querySelector('body');
  // const printhead = printWindow.document.querySelector('html');
  // printhead.appendChild(headcopy);
  // printBody.appendChild(childElementcopy);

  // printWindow.document.close();
  // printWindow.print();

  // 监听新窗口的onload事件,在加载完成后执行打印操作



},

对你有帮助的话请点赞收藏,你的鼓励我会收到的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值