vue 表格数据打印功能

一、单页打印

只对当前页面可见数据进行打印,实现方法不唯一,此处介绍相对简单的vue-print-nb。他的缺点是只能打印可见区域,不能分页打印 。

  1. 安装
  npm install vue-print-nb --save
  1. 引入
// 安装好以后在main.js文件中引入
import Print from 'vue-print-nb'
Vue.use(Print);  //注册
  1. 使用
    (1). 直接使用id,不对最终打印的表格进行样式修改
// 通过ID直接打印
  <div id="print_demo" >
    <p>打印内容</p>
  </div>
<button v-print="'#print_demo'">打印</button>

(2). 使用printObj,可以对打印的表格进行样式调整

// 在组件的打印按钮标签上使用指令 v-print="printObj", print是配置对象
  <button v-print="printObj">打印</button>

//  在组件的打印区域标签上加 id="print_demo"
<div id="print_demo"  style="background:red;">
  <p>打印内容</p>
</div>

(2-1). 在组件的data中定义print配置对象

export default {
    data() {
        return {
            printObj: {
              id: "print_demo",
              popTitle: '打印的标题', //  打印配置页上方标题
              extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',  // 最上方的头部文字,附加在head标签上的额外标签,使用逗号分隔
               preview: '',  // 是否启动预览模式,默认是false(开启预览模式,可以先预览后打印)
               previewTitle: '',  // 打印预览的标题(开启预览模式后出现),
               previewPrintBtnLabel: '',  // 打印预览的标题的下方按钮文本,点击可进入打印(开启预览模式后出现)
               zIndex: '', // 预览的窗口的z-index,默认是 20002(此值要高一些,这涉及到预览模式是否显示在最上面)   
               previewBeforeOpenCallback() {}, //预览窗口打开之前的callback(开启预览模式调用)
               previewOpenCallback() {}, // 预览窗口打开之后的callback(开启预览模式调用)
               beforeOpenCallback() {}, // 开启打印前的回调事件
               openCallback() {}, // 调用打印之后的回调事件
              closeCallback() {}, //关闭打印的回调事件(无法确定点击的是确认还是取消)
              extraCss: 'https://www.google.com,https://www.google.com', 
            }
        };
    }
}

(2-2). 打印过滤(隐藏打印区域不需要打印的内容)
只需要在组件的打印区域里,给需要隐藏的内容的标签上添加

class="noprint"

(2-3). 配置打印的样式
在全局样式中,新增标签,里面是打印时才生效的样式

<style media="print">
    @page {
    size: auto;
    margin: 3mm;
    }

    html {
    background-color: #ffffff;
    height: auto;
    margin: 0px;
    }
</style>

(2-4). 处理常见的打印bug
解决打印出现空白页的问题
解决el-table表格内容过多,打印不全问题
解决作用域污染问题导致el-table序号错位

<style media="print" lang="scss">
    @page {
    size: auto;
    margin: 3mm;
    }
    @media print {
    html {
        background-color: #ffffff;
        height: auto;
        margin: 0px;
    }

    body {
        border: solid 1px #ffffff;
        margin: 10mm 15mm 10mm 15mm;
    }
    table {
        table-layout: auto !important;
    }

    .el-table__header-wrapper .el-table__header {
        width: 100% !important;
        border: solid 1px #f2f2f2;
    }
    .el-table__body-wrapper .el-table__body {
        width: 100% !important;
    }
    #pagetable table {
        table-layout: fixed !important;
    }
    }
</style>

(2-5). 局部打印,局限在当前组件里
在组件标签

<style media="print" lang="scss">
@page {
  size: auto;
  margin: 3mm;
}
@media print {
  html {
    background-color: #ffffff;
    height: auto;
    margin: 0px;
  }

  body {
    border: solid 1px #ffffff;
    margin: 10mm 15mm 10mm 15mm;
  }
  #printArea table {
    table-layout: auto !important;
  }

  #printArea .el-table__header-wrapper .el-table__header {
    width: 100% !important;
    border: solid 1px #f2f2f2;
  }
  #printArea .el-table__body-wrapper .el-table__body {
    width: 100% !important;
  }
  #printArea #pagetable table {
    table-layout: fixed !important;
  }
}
</style>

(2-6). 注意
启动打印后可以通过调整设置的缩放来调整显示比例
可以通过设置背景图形来控制页面是否使用彩色背景

二、打印数据库内全部数据

Print.js 文档

将数据库内的全部数据以表格的形式进行打印,需要调用后台接口直接从数据库内进行数据的查找,而不是直接在页面内获取数据。

  1. 安装
npm install print-js --save
  1. 引入
// 在当前vue文件内引用
import printJS from 'print-js'
  1. 使用
<el-button  @click="printJson">打印全部表格</el-button>
async printJson() {
      //通过getdata调用后台接口获取数据封装到res
      const res = await getdata();
      this.list = res.data || [];
      printJS({
        printable: this.list ,
        properties: [ // 表头数据
          {
            field: 'num', //  表头字段
            displayName: '序号', // 页面显示的文字
          },
          { field: 'date', displayName: '日期 '},
         { field: 'name', displayName: '费用名称' },
         { field: 'subjectMatter', displayName: '事由' },
         { field: 'money', displayName: '金额(元)' },
         { field: 'notes', displayName: '备注' },
        ],
        type: 'json',
         // tbody的样式
        gridStyle: 'text-align: center;border: 1px solid #E5E6EB;' ,
         // 标题
		header: `<h3 class="custom-h3">标题</h3>`,
        // 标题样式
		style: '.custom-h3{text-align: center; margin-bottom: 10px;}',
      })
    },