赞
踩
目录
方法二:利用iframe,iframe.contentWindow.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内的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,放大缩小的比例,要根据实际情况调整。
除了使用浏览器自带的打印功能外,还可以使用第三方库或插件来实现更高级的打印操作,例如打印指定区域、打印多个页面等。
常用的打印插件有 Print.js、html2canvas、jPrintArea等。这里以 Print.js 为例,演示如何使用该插件实现前端打印功能。
首先,需要在 `head` 标签中引入 `Print.js` 插件:
- <head>
- <script src="/path/to/Print.js"></script>
- </head>
然后,在页面中需要打印的元素上添加 `class` 属性或 ID 属性:
- <div id="print-content">
- <!-- 这里是需要打印的内容 -->
- </div>
最后,在触发打印的按钮的点击事件中,使用 `Print.js` 插件的 `printHtml` 方法来触发打印操作:
- function onPrint() {
- // 获取需要打印的内容
- const content = document.getElementById('print-content').innerHTML;
-
- // 调用 printHtml 方法触发打印操作
- window.printHtml({
- printable: content,
- onAfterPrint: function() {
- // 打印完成后的操作
- }
- });
- }
在上述代码中,我们使用了 `window.printHtml` 方法来触发打印操作。该方法接受一个配置对象,其中包含需要打印的内容和打印完成后的回调函数。
需要注意的是,使用第三方插件能够提供更为定制化的打印功能,但是在使用前需要对插件的相关文档进行仔细的阅读和熟悉,确保能够正确地使用插件完成打印功能。
当用户想要打印页面时,我们可以向用户提供打印功能。而实现页面打印的主要步骤如下:
在进行打印之前,我们需要首先设计打印布局以确保打印内容能够在有限的纸张大小上清晰地展示。我们需要定义一个专门的打印样式表来控制样式和布局。这个样式表可以包含在主样式表中,也可以在header标签中单独引用。比较重要的是我们需要在这个样式表中使用`@media print` 来为网页在打印模式下设置独立的样式,以适应打印的需求。因为我们的网页布局和打印页面布局还是有很大的区别,如margin,padding等样式设置等。
可以通过一个简单的示例来说明:
- @media print {
- /* 隐藏不必须要打印的元素 */
- header, nav, .no-print {
- display: none;
- }
- /* 修改页面大小和边距 */
- @page {
- size: A4 landscape;
- margin: 20mm 10mm 20mm 10mm;
- }
-
- /*在打印模式下添加样式*/
- .table tr td, .table tr th {
- border: 1px solid #ddd;
- padding: 10px;
- }
- /*自定义打印样式*/
- h1 {
- font-size: 24pt;
- color: blue;
- }
- }
在这里我们使用 @media print 创建新的样式,确保要打印的布局不同于网页布局,并提供了一些自定义的打印样式,例如字体大小和颜色。
实现页面打印的另一个关键步骤是创建一个专门用于打印的版本。可以通过以下方式来实现:
以下是一个通过克隆来创建打印版本的示例:
- function createPrintVersion() {
- // 获取需要打印的内容。
- var content = document.getElementById('printContent').cloneNode(true);
-
- // 添加打印标记,以便于在新窗口中仅打印必要内容。
- var html = '<html><head><title>打印页面</title>' +
- '<style> @media print { /* 此处与上述样式表一样,可以复用 */ } </style></head><body>' +
- content.innerHTML + '</body></html>';
-
- // 返回新生成的打印版本。
- return html;
- }
在这个示例中,我们定义了一个名为createPrintVersion()
的函数,用于创建一个专门用于打印的版本。该函数获取需要打印的内容并将其复制到新标签中,然后添加打印标记和打印样式,以便在新窗口中仅打印必要的内容。最后,该函数返回一个新生成的打印版本。
在用户点击“打印”按钮时,我们需要触发打印功能。为此,我们要实现用 JavaScript 创建了一个打印功能呼叫的链接,在单击该链接时执行打印功能。
- function printContent() {
- // 创建打印窗口。
- var printWindow = window.open('', 'PrintWindow', 'height=600,width=800');
-
- // 获取需要打印的内容。
- var content = document.getElementById('printContent').cloneNode(true);
-
- // 添加打印标记,以便于在新窗口中仅打印必要内容。
- var html = '<html><head><title>打印页面</title>' +
- '<style> @media print { /* 此处与上述样式表一样,可以复用 */ } </style></head><body>' +
- content.innerHTML + '</body></html>';
-
- // 在新窗口中输出打印内容。
- printWindow.document.write(html);
-
- // 等待文档加载完成后再打印。
- printWindow.document.addEventListener('DOMContentLoaded', function() {
- setTimeout(function() {
- printWindow.print();
- printWindow.close();
- }, 500);
- });
- }
在此示例中,我们定义了一个名为printContent()
的函数,用于创建一个新的打印窗口并获取打印版本。然后,我们在新窗口中输出打印内容,并添加一个事件侦听器来等待文档加载完成后再进行打印和关闭窗口。
此外,我们也可以通过使用现成打印控件和第三方库如 jspdf 等更加便捷地实现打印功能。
第二步和第三步之间的区别是前者仅是生成打印版本,而后者则创建一个新的窗口并自动进行打印。第二步可以将生成的打印版本传递给用户,以供他们手动打印。而第三步则在打印版本生成后自动弹出窗口进行打印,无需用户交互。
在打印之前,我们可以为用户提供某些选项,例如检查页面元素是否准备好,或者是否已进行必要的复杂计算,或者在开始打印前看一下预览。因此,我们需要在打印之前添加一些前处理程序,并与用户确认这些设置。
不同浏览器和打印机配置间打印设置会有一定差异,为确保打印刻度和页面排版在不同浏览器下达到最佳效果,我们建议先自己制作一些测试文件进行测试。要注意的是,在不同的操作系统上,打印输出的内容可能会有所不同,这些问题需要适当考虑。我们可以使用 JavaScript 或其他依赖库在不同情况下进行测试和设置以确保适配性。
以上步骤是如何实现页面打印的主要步骤,如此复杂的需求往往需要前端工程师提前考虑好后。
- @media print {
- .no-print {
- display: none;
- }
- }
然后在iframe标签中添加一个class为"no-print"的div元素,这样可以在打印页面中隐藏该元素及其子元素,从而避免显示路由地址。
打印的方式很多,大家选择适合自己项目的即可。就像王者荣耀,哈哈哈(肯定会有人突然疑惑,为什么会突然提到游戏,因为前两天我肯开心自己粉丝在增加,但是感觉自己博客不怎么生动,同事就给了我一个建议,可以说说王者荣耀,嘻嘻嘻,第一次说,以后不一定啥时候说),所以最后总结只有第一句话有用,后边大家随便看看就行,代码机器们,加油,在努力个四五十年,马上就可以退休了!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。