调用浏览器局部打印,空白、只有一页问题、火狐兼容

项目中需要局部打印页面的图表,图表类型多而杂,因此html结构中包含了canvas和iframe,iframe中又包含canvas。
刚开始根据网上的教程试了原生打印和插件打印(react-to-print),还有html2canvas转换页面都不能满足。要么iframe内空白,要么canvas空白。所以我需要结合以上的方案一起解决。
并且我需要实现局部打印,利用网上的做法复制innerHTML,复制过来iframe内部是空的,打印出来的内容自然是空白的,利用很多方法依旧不可行。直接appendChild会破坏页面的布局,也不行。

最终解决方案:
1.将局部打印内容iframe内部的canvas先转换成图片并添加到iframe外部,隐藏iframe,这样看起来内容没有变化,只是动态图表变成了图片。
2.第一步处理完,现在直接将一整个局部打印区域通过html2canvas转换成canvas,然后转换成图片。
3.创建一个iframe,内容是打印预览。创建一个div,将上面的图片插入div中。iframe和div都放到body中。
4.将div内容写入iframe中。iframe调用打印。
5.删除iframe转换的图片,将iframe重新显示。

如果大家的页面结构没有iframe、canvas,是不需要像我这么复杂的。想要局部打印的直接将dom的innerHTML写入iframe内部就可以了。

只有一页的问题
我出现这个问题是因为,我包裹内容的div有position:fixed;的属性,把他改成relative就好了。看网上还有人说,overflow要设置为visible,可以看看自己具体问题,都是样式的原因。

谷歌正常打印,火狐空白
局部打印iframe需要添加一个属性src,值为“javascript:”,不然的话值就是“about:blank”,会出现空白。我加上之后其他浏览器并无影响所以没有做判断,如果需要的话判断一下浏览器类型。

下面是我的代码,可以参考一下。

const el = document.getElementById(id); // 局部打印区域if (!el) return;// 创建iframe打印预览const iframe = document.createElement('IFRAME');let doc: any = null;// 兼容火狐浏览器 解决iframe的src是about:blank 内容是空白的问题iframe.setAttribute('src', 'javascript:');iframe.setAttribute('style','position:absolute;width:0px;height:0px;left:500px;top:500px;',);document.body.appendChild(iframe);// 找到打印区域的iframe 获取内部canvas 转换成图片 添加到iframe前 隐藏iframeconst iframes = el.querySelectorAll('iframe');iframes.forEach(item => {const itemChild = item.contentDocument?.body.querySelector('canvas');if (itemChild) {const image = new Image();image.src = itemChild.toDataURL('image/png');image.setAttribute('width', item.offsetWidth as any);image.setAttribute('height', item.offsetHeight as any);image.style.width = item.offsetWidth + 'px';image.style.height = item.offsetHeight + 'px';item.parentElement?.insertBefore(image, item);item.style.display = 'none';}});// 处理完所有iframe html2canvas转换一次el打印区域 得到的canvas转换成图片 赋值给打印iframeif (isIFrame(iframe) && iframe.contentWindow) {doc = iframe.contentWindow.document;html2canvas(el, {scale: 2,allowTaint: true,useCORS: true,width: el.offsetWidth,height: el.offsetHeight,windowWidth: el.scrollWidth,windowHeight: el.scrollHeight,}).then(canvas => {const context = canvas.getContext('2d') as any;context.mozImageSmoothingEnabled = false;context.webkitImageSmoothingEnabled = false;context.msImageSmoothingEnabled = false;context.imageSmoothingEnabled = false;const src64 = canvas.toDataURL();const contentWidth = canvas.width;const contentHeight = canvas.height;const imgWidth = el.clientWidth; // 根据打印区域宽度设定const imgHeight = (imgWidth / contentWidth) * contentHeight;const img = new Image();const div = document.createElement('div');div.appendChild(img);img.setAttribute('src', src64);img.setAttribute('width', imgWidth as any);img.setAttribute('height', imgHeight as any);img.setAttribute('id', 'imgs');document.body.appendChild(div);doc.open();doc.write(div.innerHTML);doc.close();// 图片加载完毕获取iframe的焦点调取打印img.onload = () => {// ,从iframe开始打印iframe.contentWindow?.focus();iframe.contentWindow?.print();// 删除所有img 显示iframeiframes.forEach((item, index) => {const imgNode = item.parentElement?.querySelector('img');imgNode && item.parentElement?.removeChild(imgNode);item.style.display = 'block';});document.body.removeChild(div);};});}if (navigator.userAgent.indexOf('MSIE') > 0) {document.body.removeChild(iframe);}

调用浏览器局部打印,空白、只有一页问题、火狐兼容相关推荐

  1. javascript 调用浏览器的打印方法。并设置打印为横向打印

    最近做一个简单的打印功能,要使用JavaScript调用浏览器的打印功能.并设置打印为横向打印: 为了适应A4纸的宽和高这里设置: body{margin:0 auto; width: 1010px; ...

  2. 调用浏览器的打印方法打印页面内容

    2018-08-30 直接调用浏览器的打印方法 1.打印按钮 <a href="#" target="_self" οnclick="print ...

  3. js打印指定html页面(调用浏览器的打印功能)

    上代码: <p>这里的所有内容不打印</p> //<!--startprint-->标签上面的内容不打印<!--startprint--><p&g ...

  4. vue打印模版-自定义模版-局部打印/使用插件vue-print-nb打印,打印样式设置

    一.自定义模版打印功能: <template><div v-if="printVisible"><div id="printBox" ...

  5. 浏览器调用打印功能打印页面内容(可全局打印,可局部打印)

    function printhtml() {var ht = $('#xxx').html(); //局部打印,全局打印的话直接调用windows.document.print()即可var h = ...

  6. jq jqprint 设置页脚_jQuery 插件 jqprint 实现浏览器页面打印和设置页眉页脚

    使用 jqprint 插件实现浏览器页面打印,需要用到两个js文件,jquery.js 和 jqprint.js,本文使用 jquery-1.4.4.min.js,jquery.jqprint-0.3 ...

  7. 如何调用浏览器打印功能来打印页面

    最近项目需要做一个打印功能,是点击一个按钮成功后调用jQuery的打印功能,网上找了找,有一个jQuery打印插件jqprint. 首先需要创建一个打印区域 <div style="w ...

  8. JimuReport积木报表打印多出一页空白页问题(解决方案)

    原文地址: JimuReport积木报表打印多出一页空白页问题 - BIGTREE (whwtree.com) 问题描述 积木报表预览或打印时,会多出一页空白页问题. 解决方案 总结如下: (1)方法 ...

  9. jimu积木报表打印时多一页空白页-问题解决

    记录一下工作中使用jimu积木遇到的问题,被折磨了一下午. 积木报表完成后测试打印功能,结果打印时无缘无故多出来一页空白页,对空白页的地方进行删除格式,清空数据,清楚合并历史等各种清理单元格的操作都无 ...

最新文章

  1. 【Android 逆向】Android 逆向工具 ( Apktool | IDA | Python )
  2. c# timer使用
  3. 从.Net框架Bug的提交到修复代码成功合并到.NET CoreFX主线
  4. python 流式计算框架_流式计算的三种框架:Storm、Spark和Flink
  5. Meinheld 和 Gevent_XYM
  6. vue中怎么点击修改文字_杭州展馆设计中说明牌和说明文字怎么样才能使用最大化?...
  7. python 爬虫爬取内容时, \xa0 、 \u3000 的含义与处理方法
  8. 照片处理高手《光影魔术手 nEO iMAGING 》使用全攻略,看完的都变高手!
  9. MySQL 临时表的原理以及优化手段
  10. 经典面试题-什么是java序列化,如何实现java序列化?
  11. 计算机切换器鼠标反应慢,kvm切换器故障操作解决方法详解
  12. ubuntu打开摄像头测试
  13. 数值图形处理软件活图简介
  14. 电脑硬盘右击计算机就卡死,win10总是莫名其妙卡死怎么解决
  15. obs和red5以及网页视频播放器实行直播
  16. CSS三种样式表:行内样式表、内部样式表、外部样式表
  17. Linux mysql数据库每天定时自动备份数据
  18. golang colly踩坑笔记
  19. matlab 求矩阵秩,用MATLAB编程求矩阵的秩
  20. Java:计算机编程语言Java的简介、安装(编程环境/工具)、学习路线(如何学习Java以及几十项代码编程案例分析)之详细攻略

热门文章

  1. IE和FireFox关于CSS的兼容性
  2. x64长模式与段的纠葛
  3. 解决Jenkins安装时插件无法下载的问题
  4. 日本python教程视频_清华学姐推荐的python视频400集,拿走不谢
  5. Python中 ‘int‘ object is not subscriptable 问题的可能解决方法
  6. 用户代理检测与浏览器Ua详细分析
  7. pyqt5 输入确认_PyQt5学习笔记(五):弹出对话框请求确认
  8. latch:cache buffers chains等待事件导致的latch争用的原理原因与检查
  9. 威纶通触摸屏技巧总结
  10. 最大化参数 火车头_火车头采集器教程:使用正则匹配模式采集数据