iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript图片打印方案实例详解
  • 445
分享到

JavaScript图片打印方案实例详解

js 打印图片js打印预览js打印输出 2023-03-19 17:03:09 445人浏览 薄情痞子
摘要

最近有个页面打印图片的小需求。就是系统界面展示有一些证件照片,我们希望可以点击图片旁边的打印小按钮,就可以将这张图片直接打印到A4纸张上,例如下图效果: 其实浏览器 window

最近有个页面打印图片的小需求。就是系统界面展示有一些证件照片,我们希望可以点击图片旁边的打印小按钮,就可以将这张图片直接打印到A4纸张上,例如下图效果:

其实浏览器 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 = 0
	const 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毫米是为了保证不出现页眉页脚。

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

  • 当图片是横图时,即宽度大于高度的图片时,需要将A4纸张横向打印,然后图片在A4里面上下左右都居中。同时要将这张图片尽可能地铺满A4纸张,也不能改变图片的宽高比(即不变形)。

  • 当图片是纵图时,即宽度小于高度的图片时,需要将A4纸张纵向打印,然后图片在A4里面上下左右都居中。同时要将这张图片尽可能地铺满A4纸张,也不能改变图片的宽高比(即不变形)。

  • 图片不要紧挨着纸张边缘,留出一定边距。

横图效果:

纵图效果:

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

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

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

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

// 获取图片宽高比
const rate = owidth/oheight
// 横图的话容器宽度就是A4的高度,即29.7cm,纵图的话宽度就是21cm,由于刚好设置成21cm会溢出,多出一张纸,原因未明,所以我设置成20.9
const 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.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 - 1
imgH = imgW/rate
iframe.addEventListener("load",()=>{
	const image = document.createElement("img")
	image.style.width = item.width
	image.style.height = item.height
	image.style.display = 'block'
	image.src = item.newUrl || item.url || item.original_content_url
	image.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 } = item
	const rate = owidth/oheight
	const imgHeight = height.replace("px","")
	const iframe = document.createElement('iframe')
	iframe.style.height = 0
	iframe.style.visibility = 'hidden'
	iframe.style.width = 0
	const 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 - 1
	imgH = imgW/rate

	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);
	document.body.appendChild(iframe);
	iframe.addEventListener("load",()=>{
		const image = document.createElement("img")
		image.style.width = item.width
		image.style.height = item.height
		image.style.display = 'block'
		image.src = item.newUrl || item.url || item.original_content_url
		image.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 图片打印内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript图片打印方案实例详解

本文链接: https://www.lsjlt.com/news/200400.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript图片打印方案实例详解
    最近有个页面打印图片的小需求。就是系统界面展示有一些证件照片,我们希望可以点击图片旁边的打印小按钮,就可以将这张图片直接打印到A4纸张上,例如下图效果: 其实浏览器 window ...
    99+
    2023-03-19
    js 打印图片 js打印预览 js打印输出
  • Python实现打印金字塔图案的方法详解
    目录简单的金字塔图案方法:使用while循环方法:使用for循环打印三角数字模式无需重新分配的数字字符模式连续字符模式可以使用简单的 for 循环在 python 中打印模式。第一个...
    99+
    2024-04-02
  • JavaScript图片打印功能怎么实现
    这篇文章主要讲解了“JavaScript图片打印功能怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript图片打印功能怎么实现”吧!其实浏览器 window 对象提供了 ...
    99+
    2023-07-05
  • Python去除图片水印实现方法详解
    目录OpenCV介绍去水印图片去水印原理最近写文章遇到图片有水印,如何去除水印呢? 网上找了各种办法,也跑到小红书、抖音等平台找有没有不收费就去水印的网站,但是基本上都是需要VIP会...
    99+
    2023-01-06
    Python去除图片水印 Python去除水印
  • Python实现图片压缩的案例详解
    目录1、引言2、PIL模块2.1 quality 方式2.2 thumbnail方式3、OpenCV模块3.1 安装3.2 执行代码4、总结1、引言 小屌丝:鱼哥,求助,求助 小鱼:...
    99+
    2024-04-02
  • Python实现为图片添加水印的示例详解
    目录1、引言2、filestools介绍2.1 安装2.2 filestools 功能介绍2.3 watermarker模块介绍2.4 代码实例补充1、引言 小屌丝:鱼哥,这个周末过...
    99+
    2024-04-02
  • C语言打印各种图案实例代码
    1、线段图案 #include<stdio.h> int main() { int a = 0; while(~scanf("%d",&a))...
    99+
    2024-04-02
  • Python实现处理图片水印的方法详解
    原图:  去水印后: 程序非常简单,首先读取图片后,转为HSV通道图像。 image = cv2.imread("watermark.png") HSV = cv2...
    99+
    2024-04-02
  • .Net实现图片裁剪图片缩放及图片加水印详解
    目录引言(1)原图裁剪后的效果如下(2)原图缩略后的效果如下(3)原图加文字水印后的效果如下(4)原图加图片水印后的效果如下引言 图片的裁剪、缩放、与加水印,是任何系统经常要用到的功...
    99+
    2024-04-02
  • Java实现添加文字水印&图片水印的方法详解
    目录为什么要给图片添加水印绘制文字水印动态计算字符串的宽度自适应文字水印位置绘制图片水印提升图片处理速度为什么要给图片添加水印 为图片添加水印的主要作用是保护图片版权,防止图片被未经...
    99+
    2023-02-06
    Java添加文字水印 Java添加图片水印 Java添加水印
  • wps打印图片不发黑的方法
    今天小编给大家分享一下wps打印图片不发黑的方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。打印图片发黑可能是图片本身颜色...
    99+
    2023-07-02
  • C语言实现打印星号图案
    目录C语言 打印星号图案C语言 循环打印星号图形*用两层循环C语言 打印星号图案 打印一个上半部分为等腰三角形,下半部分为倒等腰三角形星号图案:思想为创建一层大的循环表示行数,然后里...
    99+
    2022-11-16
    C语言打印图案 打印星号图案 C打印星号图案
  • JavaScript offsetParent案例详解
    1. offsetParent定义:那么offsetParent就是距离该子元素最近的进行过定位的父元素(position:absolute  relative fixed...
    99+
    2024-04-02
  • 电脑黑白打印机打印图片底色黑如何解决
    本篇内容介绍了“电脑黑白打印机打印图片底色黑如何解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!解决方法方法一:首先在“Photoshop...
    99+
    2023-06-30
  • win10无法打印jpg图片如何解决
    本文小编为大家详细介绍“win10无法打印jpg图片如何解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“win10无法打印jpg图片如何解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。win10无法打印jp...
    99+
    2023-07-01
  • Android 显示GIF图片实例详解
    Android 显示GIF图片实例详解gif图动画在Android中还是比较常用的,比如像新浪微博中,有很多gif图片,而且展示非常好,所以我也想弄一个。经过我多方的搜索资料和整理,终于弄出来了,其实github上有很多开源的gif的展示代...
    99+
    2023-05-31
    android gif图片 roi
  • Vuelazyload图片懒加载实例详解
    文档:https://github.com/hilongjw/vue-lazyload 1.安装 cnpm i vue-lazyload -S 或 npm i vue-lazyl...
    99+
    2024-04-02
  • Android图片压缩的实例详解
    Android图片压缩的实例详解在做微信分享的时候,由于分享的缩略图要求不得大于32K,否则不能调起微信,所以总结了一下Android图片的压缩问题,大部分资料都是来自网上各位的分享,自己只是完善或修改了一下,本着继续分享的精神,也方便自己...
    99+
    2023-05-30
    android 图片压缩 roi
  • TypeScript顺时针打印矩阵实现实例详解
    目录前言梳理思路实现代码示例代码前言 有一个矩阵,如何按照从外向里以顺时针的顺序依次打印出每一个元素?本文将跟大家分享下这个算法,欢迎各位感兴趣的开发者阅读本文。 梳理思路 当我们遇...
    99+
    2024-04-02
  • python为图片和PDF去水印详解
    目录安装模块获取图片的 RGB图片去水印PDF 去水印图片转为 pdf总结网上下载的 pdf 学习资料有一些会带有水印,非常影响阅读。比如下面的图片就是在 pdf 文件上截取出来的。...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作