前端实现在浏览器中打印网页

不才
• 阅读 560

前端数据报表打印方案

背景

项目:vue + element ui

需求:web端连接打印机打印报表功能

关键词:浏览器端 连接打印机 打印报表

调研

首先,前端调用打印只有两种方式,使用window.print()和调用网络打印机。

window.print

这个是浏览器开放的api一般快捷键ctrl+p或右键都也能调用。

可以通过媒体查询的方案进行局部打印,也就是隐藏其他的元素只展示需要打印的区域。

调用网络打印机

这个方式其实就是调用接口传递参数,一般可以配合html2canvas

方案

由于网络打印机方案还需要后端or打印机支持,不适用这里。

方案一:通过CSS媒体查询进行区域打印

  1. 添加一个全局的媒体查询的样式
@media print {
  .no-print {
    display: none!important;
  }
}
  1. 将样式绑定不需要打印的元素上
<div class="no-print"></div>
  1. 改动需要打印区域的大小,宽度一般为980px,宽度过多会导致溢出。
printElement.style.width = "980px"

优缺点

优势:改动难度小。

缺点:涉及位置多,而且这种行为太了,不优雅。

方案二:将元素append到iframe进行渲染打印

通过获取到需要打印的元素,然后通过innerHtml获取元素,然后将html字符串写入到iframe,然后把需要的样式全部写入。

const printId = 'print-element-id';
const printElement = document.querySelector(printId)
const printElementHtml = printElement.innerHtml

const iframe = document.createElement('iframe')
iframe.setAttribute('style', '你的样式,可以从css文件下载')
document.appendChild(iframe)
iframe.contentWindow.document.body.innerHtml = printElementHtml;
// 调用打印
iframe.contentWindow.print()

优缺点

改动不大,可以针对性处理。

但样式容易出问题,需要调整,有些依赖js自适应宽度的可能出现打印不完整的问题。

方案三:通过在iframe中直接构建TABLE进行渲染

个人推荐方案

由于目标是打印报表,所以可以聚焦报表,没必要纠结是不是和网页一致,只要能按table打印就达到了目的。

当然如果产品需要保持一致,那看看能不能好好沟通,不能就选择上面的方案。

核心就是结合方案二,使用自定义table简化样式,达到打印完整的目的。

const data = [
    {
      "name": "马磊",
      "email": "o.biayajolg@xkic.pe",
      "id": "EfFACeD4-51d8-43B5-E9Bf-FFEB361dc5a4",
      "age": 18,
      "phone": "19864717125",
      "address": "场历当式使民党标对确并线却。",
      "user": "75FD6371-4c3D-ED90-DD15-F0EA6fD7b942",
      "create_at": "2005-08-25 PM 18:35:14",
      "update_at": "1983-12-28 AM 00:47:25"
    },
    {
      "name": "程刚",
      "email": "m.rvvvzvojp@ofrozu.hn",
      "id": "912C1FF4-6CeA-8489-b2D8-2d5FFA816F6b",
      "age": 97,
      "phone": "19838636737",
      "address": "办约拉则三称斯也包报素万制老。",
      "user": "94754927-94cf-a7e5-aBe7-3A23112BC8f5",
      "create_at": "1988-08-04 PM 17:26:51",
      "update_at": "2008-05-26 AM 08:33:42"
    },
 ];
// 代码非完整代码,【伪代码】,代码大致行为:通过数据创建table
const table = document.createElement('table')
data.forEach(item=>{
  const tr = document.createElement('tr')
  table.appendChild(tr);
  Object.keys(item).forEach(item => {
    const td = document.createElement('td')
      tr.appendChild(td)
  });
});

const iframe = document.createElement('iframe')
iframe.setAttribute('style', '你的样式,可以从css文件下载')
document.appendChild(iframe)
// 这里改成table的html代码,当然可以考虑改为自己 appendChild element
iframe.contentWindow.document.body.innerHtml = table.innerHtml;
// 调用打印
iframe.contentWindow.print()

前端实现在浏览器中打印网页

第三方插件

不过实际项目中没必要这样难为自己去实现,有一个很完整的框架可以完成以上的能力print-js

调用也很简单:

printJS({
  documentTitle: '测试',
  header: '表格标题',
  type: 'json',
  properties: [
    { field: 'id', displayName: '编号' },
    { field: 'name', displayName: '名称' },
    { field: 'age', displayName: '年龄' },
    { field: 'phone', displayName: '手机号' },
    { field: 'address', displayName: '地址' },
    { field: 'email', displayName: '邮箱' },
    { field: 'address', displayName: '地址' },
    { field: 'user', displayName: '用户编号' },
    { field: 'create_at', displayName: '创建时间' },
    { field: 'update_at', displayName: '更新时间' },
  ],
  printable: [
    {
      "name": "马磊",
      "email": "o.biayajolg@xkic.pe",
      "id": "EfFACeD4-51d8-43B5-E9Bf-FFEB361dc5a4",
      "age": 18,
      "phone": "19864717125",
      "address": "场历当式使民党标对确并线却。",
      "user": "75FD6371-4c3D-ED90-DD15-F0EA6fD7b942",
      "create_at": "2005-08-25 PM 18:35:14",
      "update_at": "1983-12-28 AM 00:47:25"
    },
    {
      "name": "程刚",
      "email": "m.rvvvzvojp@ofrozu.hn",
      "id": "912C1FF4-6CeA-8489-b2D8-2d5FFA816F6b",
      "age": 97,
      "phone": "19838636737",
      "address": "办约拉则三称斯也包报素万制老。",
      "user": "94754927-94cf-a7e5-aBe7-3A23112BC8f5",
      "create_at": "1988-08-04 PM 17:26:51",
      "update_at": "2008-05-26 AM 08:33:42"
    },
  ],
})

小尾巴

我的博客:https://www.notbucai.com/

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
Ubuntu下怎么安装联想LJ2205激光打印机的驱动
联想的激光打印机LJ2205在京东只卖599,确实比较便宜。但是联想的软件研发能力一向是比大厂要弱很多的。很遗憾的是LJ2205没有官方的Linux驱动。怎么办?经过一番调研,我发现LJ2205其实就是日本的BortherHL2140打印机。安装步骤就是,用USB连接开机状态的打印机到PC,打开控制面板中的打印机选项,添加打印机,选
Easter79 Easter79
3年前
strace命令使用
命令介绍strace是Linux环境下的一款程序调试工具,用来输出一个应用程序所使用的系统调用。strace底层使用内核的ptrace特性来实现其功能。什么是系统调用?系统调用是通向操作系统本身的接口,是面向底层硬件的。通过系统调用,可以使得用户态运行的进程与硬件设备(如CPU、磁盘、打印机等)进行交互,是操作系统留给
Wesley13 Wesley13
3年前
java 根据图片文字动态生成图片
今天在做热敏打印机打印二维码,并有文字描述,想到的简单的方法就是根据热敏打印机的纸张宽度和高度,生成对应的图片,如下:packagecom.orisdom.utils;importlombok.extern.slf4j.Slf4j;importjavax.imageio.ImageIO;importjava.awt.;importja
Wesley13 Wesley13
3年前
Spread for Windows Forms高级主题(7)
表单打印的多个部分都可以进行自定义,大多数的自定义选项存在于PrintInfo对象中。大多数打印选项是在PrintInfo对象上进行设置,并在表单级别上应用。当你执行打印操作时,你将一个特定的表单发送给使用这些设置的打印机。如果你想为不同的表单使用不同的打印设置,那么你可能需要重置PrintInfo对象,然后在表单打印的间隔内做必要的修改。深入理解打
Wesley13 Wesley13
3年前
asp.net调用Lodop实现页面打印或局部打印,可进行打印设置或预览
<%@PageLanguage"C"AutoEventWireup"true"CodeFile"WebPrint.aspx.cs"Inherits"WebPrint"%<!DOCTYPEhtmlPUBLIC"//W3C//DTDXHTML1.0Transitional//EN""http:/
Wesley13 Wesley13
3年前
C#调用打印机
usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Drawing;usingSystem.IO;usingSystem.Windows.Forms;namespaceTY\_ClassLibrary{  
Stella981 Stella981
3年前
Bartender五大优势
领跑业界,优势明显Seagull Scientific 在提供真正的Windows 标签打印方面堪称全球领先者。实际上,BarTender 是第一个同时支持激光及热敏打印机的Windows应用程序。如今,在为标签打印机提供真正的Windows 驱动程序这一领域,我们已成为世界上最大的软件开发商,产品可支持20 多种语言。因此,选择合适的Win
Wesley13 Wesley13
3年前
.NET中的GC垃圾回收
本章将和大家分享.NET中的GC垃圾回收。托管堆垃圾回收CLR提供GC。1、什么样的对象需要垃圾回收?  托管资源引用类型  托管资源和非托管资源:    托管的就是CLR控制的,例如:new的对象、string字符串、变量等;    非托管不是CLR能控制的,例如:数据库连接、文件流、句柄、打印机连接等;    u
京东云开发者 京东云开发者
3个月前
桌面运维工具之打印机驱动安装
1.前言桌面运维同学经常会处理打印机驱动安装这类工单,手动安装打印机驱动通常包含以下步骤:1.根据打印机型号网上查找对应打印机驱动2.使用cmd命令进入管理员界面3.将打印机驱动添加到window系统中人工安装需要经过三个步骤,操作繁琐,效率较低。基于此,
taskbuilder taskbuilder
2星期前
TaskBuilder_v1.3.45版更新说明
TaskBuilderv1.3.45版更新说明打印报表整个打印报表功能进行了重构,解决了原来存在的打印模糊、分页不准确等问题,并采用跟tfp页面设计器一样的设计界面,使用更加简便,功能更加强大。具体包括以下功能特性:1、整个打印页面分为页眉、表头、表体、表