文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScript图片打印功能怎么实现

2023-07-05 13:50

关注

这篇文章主要讲解了“JavaScript图片打印功能怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript图片打印功能怎么实现”吧!

其实浏览器 window 对象提供了 print 方法,就可以对整个页面进行打印。只需要点击按钮执行以下方法即可。

window.print()

调用此方法,会打印出整个 html 里的内容,即 document 对象下所有的页面节点。而我们需要的是只打印页面的某个元素部分,即只打印图片。

很遗憾,浏览器在 具体的dom 节点上并没有部署 print 方法,不过我们可以转变个思路,我们可以将需要打印的元素提取出来,同时构造一个新的window对象,将提取出来的元素插入到这个window对象下,再调用打印即可。

<button @click="print">打印</button><div id="box"><img src="/test.jpg"/></div>

例如我们只需要打印id="box"下的 img

print(){    const el = document.querySelector("#box")    var newWindow=window.open("打印窗口","_blank");    var docStr = el.innerHTML;    newWindow.document.write(docStr);    newWindow.document.close();    newWindow.print();    newWindow.close();},

通过 window.open 方式返回一个新的 window 对象,再调用 document.write 写入我们获取到指定节点,再打印即可。

这种方式有点不好的就是需要重新开一个 window ,并且设置一些打印的样式会比较麻烦。所以不推荐。

我查阅了一些知名的打印插件,都是采用的 iframe 来构造页面来实现局部打印的。iframe 有个属性 srcdoc可以渲染指定的html内容

<iframe srcdoc="<p>Hello world!</p>"></iframe>

以往我们都是通过src来加载一个指定的页面地址,这里通过 srcdoc 来渲染指定的html内容。下面实现一个最简单的点击按钮打印图片功能:

// 打印function btnClick(){const iframe = document.createElement('iframe')// 视觉上隐藏 iframe    iframe.style.height = 0    iframe.style.visibility = 'hidden'    iframe.style.width = 0const str = `<html>            <style media='print'>                 @page{size:A4 landscape};margin:0mm;padding:0}            </style>            <body>                 <div id="box"></div>            </body></html>`    iframe.setAttribute('srcdoc', str);    document.body.appendChild(iframe);// 一定要加载完成后执行iframe.addEventListener("load",()=>{        const image = document.querySelector('img').cloneNode();        image.style.display = 'block'        const box = iframe.contentDocument.querySelector('#box');        box.appendChild(image);// 一定要图片加载完再打印        image.addEventListener('load', function () {// 打印            iframe.contentWindow.print();        });    })iframe.contentWindow.addEventListener('afterprint', function () {iframe.parentNode.removeChild(iframe);});}

对于打印的样式设置,可以通过在style标签上添加media=print来设置

<style media='print'>@page{size:A4 landscape};margin:0mm;padding:0}</style>

上述就指定了打印机默认格式为A4纸张 横向打印 ,margin设置成0毫米是为了保证不出现页眉页脚。

基础功能的打印实现了,可是为了让打印体验更好,产品经理又提出了需求点:

实现思路: 由于要保证纸张边缘留有一定的空白区域,这个时也可以使用 margin 来实现。

<style media='print'>@page{size:A4 landscape;margin:10mm;}</style>

但是不将 margin 设置成 0 的话,又会默认出现页眉页脚。这显然是矛盾的。这个时候我想到了一个好的思路,就是将图片放置到一个 div 容器里,这个 div 宽高设置成 A4 一样的大小。同时将div里面的图片通过 flex 布局来实现上下左右都居中。然后打印区域设置成这个容器就可以了。

JavaScript图片打印功能怎么实现

由于 div 和 A4 纸张一样大,所以 @page 里可以设置成 margin:0mm 来规避页眉页脚的出现。然后里面的图片需要居中

// 获取图片宽高比const rate = owidth/oheight// 横图的话容器宽度就是A4的高度,即29.7cm,纵图的话宽度就是21cm,由于刚好设置成21cm会溢出,多出一张纸,原因未明,所以我设置成20.9const boxWidthCM = `${rate >1 ? 29.7 : 20.9}cm`// 容器高度const boxHeightCM = `${rate >1 ? 20.9 : 29.7}cm`const str = `<html><style media='print'>@page{size:A4 ${rate>1 ? 'landscape':'portrait'};margin:0mm;padding:0}</style><style>*{padding:0;margin:0}body{height:100%}#box{width:${boxWidthCM};height:${boxHeightCM};display:flex;align-items:center;justify-content:center;}</style><body><div id="box"></div></body></html>`iframe.setAttribute('srcdoc', str);

居中问题解决了,接下来就是解决图片尽可能铺满纸张问题。这个时候我们需要结合容器大小以及图片宽高比来手动计算图片宽高,算法如下:

let imgW = null;let imgH = null;if(rate > 1){ // 横图if(rate>1.414){imgW = 29.7imgH = 29.7/rate} else {imgH = 20.9imgW = 20.9*rate}} else {if(rate>(1/1.414)){imgW = 20.9imgH = 20.9/rate} else {imgH = 29.7imgW = 29.7*rate}}// 预留1cm边距imgW = imgW - 1imgH = imgW/rateiframe.addEventListener("load",()=>{const image = document.createElement("img")image.style.width = item.widthimage.style.height = item.heightimage.style.display = 'block'image.src = item.newUrl || item.url || item.original_content_urlimage.style.width = `${imgW}cm`image.style.height = `${imgH}cm`const box = iframe.contentDocument.querySelector('#box');box.appendChild(image);image.addEventListener('load', function () {iframe.contentWindow.print();});})

完整代码:

print(item){const { owidth,oheight,height } = itemconst rate = owidth/oheightconst imgHeight = height.replace("px","")const iframe = document.createElement('iframe')iframe.style.height = 0iframe.style.visibility = 'hidden'iframe.style.width = 0const boxWidthCM = `${rate >1 ? 29.7 : 20.9}cm`const boxHeightCM = `${rate >1 ? 20.9 : 29.7}cm`let imgW = null;let imgH = null;if(rate > 1){ // 横图            if(rate>1.414){                imgW = 29.7                imgH = 29.7/rate            } else {                imgH = 20.9                imgW = 20.9*rate            }} else {            if(rate>(1/1.414)){                imgW = 20.9                imgH = 20.9/rate            } else {                imgH = 29.7                imgW = 29.7*rate            }}// 预留1cm边距imgW = imgW - 1imgH = imgW/rateconst str = `<html>            <style media='print'>                  @page{size:A4 ${rate>1 ? 'landscape':'portrait'};margin:0mm;padding:0}            </style>            <style>                    *{padding:0;margin:0}                    body{height:100%}                    #box{                        width:${boxWidthCM};                        height:${boxHeightCM};                        display:flex;                        align-items:center;                        justify-content:center;                    }            </style>            <body>                  <div id="box"></div>            </body></html>`iframe.setAttribute('srcdoc', str);document.body.appendChild(iframe);iframe.addEventListener("load",()=>{const image = document.createElement("img")image.style.width = item.widthimage.style.height = item.heightimage.style.display = 'block'image.src = item.newUrl || item.url || item.original_content_urlimage.style.width = `${imgW}cm`image.style.height = `${imgH}cm`const box = iframe.contentDocument.querySelector('#box');box.appendChild(image);image.addEventListener('load', function () {iframe.contentWindow.print();});})iframe.contentWindow.addEventListener('afterprint', function () {iframe.parentNode.removeChild(iframe);});}

感谢各位的阅读,以上就是“JavaScript图片打印功能怎么实现”的内容了,经过本文的学习后,相信大家对JavaScript图片打印功能怎么实现这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

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

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

软考中级精品资料免费领

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

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

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

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

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

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

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