前端实现打印功能

目录

方法一:window.print()   

方法二:利用iframe,iframe.contentWindow.print()

方法三:使用第三方库或插件

提供一个完整的范例:

1. 设计打印布局

2. 创建打印版本

3. 使用JavaScript控制打印

4. 提供打印前处理程序

5. 确保打印的兼容性

总结:


前端实现打印功能的方法有很多,大家在网上随便一搜就是一大堆,在这里,我主要选择一个我觉得比较好一点的实现方式来进行解释描述:


方法一:window.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,iframe.contentWindow.print()

这个与方法一的区别就是,取消打印后可以完整保留当前访问页面的内容,不需要影响原页面,需要注意的是,在你生成新的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.jshtml2canvasjPrintArea等。这里以 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` 方法来触发打印操作。该方法接受一个配置对象,其中包含需要打印的内容和打印完成后的回调函数。

需要注意的是,使用第三方插件能够提供更为定制化的打印功能,但是在使用前需要对插件的相关文档进行仔细的阅读和熟悉,确保能够正确地使用插件完成打印功能。

提供一个完整的范例:

当用户想要打印页面时,我们可以向用户提供打印功能。而实现页面打印的主要步骤如下:

1. 设计打印布局

在进行打印之前,我们需要首先设计打印布局以确保打印内容能够在有限的纸张大小上清晰地展示。我们需要定义一个专门的打印样式表来控制样式和布局。这个样式表可以包含在主样式表中,也可以在header标签中单独引用。比较重要的是我们需要在这个样式表中使用`@media print` 来为网页在打印模式下设置独立的样式,以适应打印的需求。因为我们的网页布局和打印页面布局还是有很大的区别,如marginpadding等样式设置等。

可以通过一个简单的示例来说明:

@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 创建新的样式,确保要打印的布局不同于网页布局,并提供了一些自定义的打印样式,例如字体大小和颜色。

2. 创建打印版本

实现页面打印的另一个关键步骤是创建一个专门用于打印的版本。可以通过以下方式来实现:

  •  让用户选择打印区域。在这种情况下,我们可以提供一个打印按钮将用户选择的部分发送到打印机。我们可以使用 JavaScript 或 jQuery 将所需的元素捕获并在新窗口中打印。
  • 克隆一个指定的区域。通过使用 `clone()` 方法,我们可以克隆指定的区域来创建一个专门用于打印的版本,然后在新窗口中打印。

以下是一个通过克隆来创建打印版本的示例:

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()的函数,用于创建一个专门用于打印的版本。该函数获取需要打印的内容并将其复制到新标签中,然后添加打印标记和打印样式,以便在新窗口中仅打印必要的内容。最后,该函数返回一个新生成的打印版本。

3. 使用JavaScript控制打印

在用户点击“打印”按钮时,我们需要触发打印功能。为此,我们要实现用 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 等更加便捷地实现打印功能。

第二步和第三步之间的区别是前者仅是生成打印版本,而后者则创建一个新的窗口并自动进行打印。第二步可以将生成的打印版本传递给用户,以供他们手动打印。而第三步则在打印版本生成后自动弹出窗口进行打印,无需用户交互。

4. 提供打印前处理程序

在打印之前,我们可以为用户提供某些选项,例如检查页面元素是否准备好,或者是否已进行必要的复杂计算,或者在开始打印前看一下预览。因此,我们需要在打印之前添加一些前处理程序,并与用户确认这些设置。

5. 确保打印的兼容性

不同浏览器和打印机配置间打印设置会有一定差异,为确保打印刻度和页面排版在不同浏览器下达到最佳效果,我们建议先自己制作一些测试文件进行测试。要注意的是,在不同的操作系统上,打印输出的内容可能会有所不同,这些问题需要适当考虑。我们可以使用 JavaScript 或其他依赖库在不同情况下进行测试和设置以确保适配性。

以上步骤是如何实现页面打印的主要步骤,如此复杂的需求往往需要前端工程师提前考虑好后。

出现的问题:

1、在使用iframe打印时,发现在打印页自动显示了路由地址,可以尝试以下几种方法去除:

  • iframe标签中添加属性:scrolling="no",这样可以禁用iframe中的滚动条,从而避免显示路由地址。
  • 在打印页面的CSS样式中,添加以下样式代码:
@media print {
  .no-print {
    display: none;
  }
}


然后在iframe标签中添加一个class为"no-print"的div元素,这样可以在打印页面中隐藏该元素及其子元素,从而避免显示路由地址。

  • iframe标签中添加属性:sandbox="allow-same-origin",这样可以限制iframe中的脚本只能与父页面同源的脚本通信,从而避免显示路由地址。

总结:

打印的方式很多,大家选择适合自己项目的即可。就像王者荣耀,哈哈哈(肯定会有人突然疑惑,为什么会突然提到游戏,因为前两天我肯开心自己粉丝在增加,但是感觉自己博客不怎么生动,同事就给了我一个建议,可以说说王者荣耀,嘻嘻嘻,第一次说,以后不一定啥时候说),所以最后总结只有第一句话有用,后边大家随便看看就行,代码机器们,加油,在努力个四五十年,马上就可以退休了!!!

  • 14
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
有人说她是Web打印控件,因为她能打印、在浏览器中以插件的形式出现,用简单一行语句就把整个网页打印出来; 有人说她是打印编程接口,因为她介于浏览器和打印设备之间,是个通道和桥梁,几乎能想到的打印控制事项都能做到; 有人说她是JavaScript的扩展,因为她所有功能就那么几个语句,和JS语法一样,一看就明白个究竟; 有人说她是报表打印工具,因为那个add_print_table语句把报表统计的那点事弄了个明明白白; 有人说她是条码打印工具,因为用了她再也不用后台生成条码图片了,前端一行指令就动态输出清晰准确的条码,一维二维都行; 有人说她是图表打印工具,因为用她能输出几乎能想象的任何图表,虽然没那么豪华,但什么饼图、折线图、柱图甚至复合图等等都不在话下; 有人说她是个小玩意,因为她体积太小了,才2M多,她所包含的其中任何一个对照工具都是她的好几倍(例如条码打印控件、图表控件等); 有人说她是套打教案,因为以Lodop+JS实现套打这种模式,在网上已被吵吵为教科书般的解决方案; 有人说她是Web打印控件的“终结者”,因为接触“她”后再不想别的“她”; 有人说她就是一个Web编程小工具,因为有了她,在BS下的打印终于像cs下那种随意而高效了; 但我们说,她是全国1000多家软件公司的智慧结晶,诞生7年了,几乎每个功能细节都蕴藏着无数开发者的期待和汗水; 她就是Lodop,没有别的名称,她是web开发的必选伴侣...
实现Vue前端打印的方法有多种。其中一种方法是通过引入打印插件来实现。你可以在后台功能中查询合适的插件并进行下载,然后在前端中使用该插件来进行打印操作。 另外,需要注意的是在处理打印逻辑之前,要确保样式已经正确引入,否则打印的页面可能会没有样式。你可以单独引入一个print.scss文件或者使用@media print {}来调整一些样式。这样可以确保打印页面的样式与预期一致。 如果打印的内容中包含线上图片资源,并且你不想进行服务器配置,可以考虑在浏览器关闭获取缓存文件的方式来解决。这样可以保证每一次获取的都是线上文件,避免打印时出现图片跨域的错误。需要注意的是,前端无法获取你点击打印或者取消的事件,只能获取你是否关闭打印框的事件。 综上所述,你可以通过下载适合的打印插件来实现Vue前端打印功能,并在处理打印逻辑前确保样式已正确引入。如果打印内容中包含线上图片资源,可以通过浏览器关闭获取缓存文件的方式来避免跨域错误。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [vue 前端实现打印功能](https://blog.csdn.net/m0_64344940/article/details/128405517)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [vue前端实现打印功能](https://blog.csdn.net/love521334421/article/details/125163942)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值