前端导出Excel和打印介绍

开发后台管理系统时,都需要实现打印、导出Excel这两项功能,在前后台分离的开发模式,你是否想找一个前端解决方案。这样后端开发人员就不用为每个报表功能附加一个导出Excel的接口了,那我们进入主题吧。

核心问题-导出Excel是个麻烦

打印不用多说,前端很容易搞定,因为浏览器自带;主要是导出Excel,因为浏览器没有默认支持,而以前大多数据项目都是后台提供接口生成excel文件后下载。

解决问题-引入两个开源库

  • printa-js

支持丰富内容的打印组件,原名print-js,printa-js是本人fork后加以改动增加了对页底部内容自定义的功能。git地址:https://github.com/cqhaibin/Print.js

  • xlsx

前端导出excel解决方案 git地址:https://github.com/SheetJS/sheetjs

  • npm安装包
npm install --save printa-js xlsx
  • 导入包
import * as printJS from 'printa-js'
import * as XLSX from 'xlsx'

打印与导出JSON的通用代码

打印

/**
 * 普通的打印方法
 * data: 数据
 * columns:列集合
 * title: 标题
 * subTitle: 副标题
 * 数据格式
 * properties: [{filed:'id', displayName: 'title'}]
 * printable: [{ id:1 },{id: 2}]
 * @param opt { printable: datas, properties: columns }
 */
export function printTable ({ data, columns, header, footer }) {
  const props = []
  columns.forEach(c => {
    if (c.ignorePrint) {
      return
    }
    props.push({
      field: c.field,
      displayName: c.label
    })
  })
  const distData = []
  data.forEach(item => {
    const tmp = {}
    columns.forEach(c => {
      if (item[c.field] !== undefined) {
        let val = item[c.field]
        if (c.format) {
          val = c.format(val, item)
        }
        Object.defineProperty(tmp, c.field, {
          value: val || ''
        })
      }
    })
    distData.push(tmp)
  })
  const opt = {
    properties: props,
    printable: distData,
    header: '<div class="header" >' + (header || '') + '</div>',
    style: ' .title { text-align: center; }, .second-title{ font-size:12px; font-weidth: norm; }, .line{ text-decoration: underline; } ',
    type: 'json',
    footer: footer || ''
  }
  printJS(opt)
}

导出Excel

/**
 * 导出excel
 * 数据格式:
 * [
        ['姓名', '年龄', '日期'],
        ['sam', 20, new Date()],
        ['long', 20, new Date()]
   ]
 */
export function excelTable ({ data, columns, title, fName, footer }) {
  const props = []
  columns.forEach(c => {
    if (c.ignorePrint) {
      return
    }
    props.push(c.label)
  })
  const distData = []
  distData.push(props)
  data.forEach(item => {
    const tmp = []
    columns.forEach(c => {
      if (item[c.field] !== undefined) {
        let val = item[c.field]
        if (c.format) {
          val = c.format(val, item)
        }
        tmp.push(val || '')
      } else {

      }
    })
    distData.push(tmp)
  })

  distData.unshift([title])

  const sheet = XLSX.utils.aoa_to_sheet(distData)
  const len = props.length
  sheet['!merges'] = [
    {
      s: {
        c: 0,
        r: 0
      },
      e: {
        c: len,
        r: 0
      }
    }
  ]
  const wb = {
    SheetNames: ['sheet1'],
    Sheets: {}
  }
  wb.Sheets.sheet1 = sheet
  // not support ie
  const fileName = fName || (title + '-' + (new Date()).getTime()) + '.xls'
  XLSX.writeFile(wb, fileName)
}
posted @ 2020-11-29 12:02  小龙女先生  阅读(716)  评论(0编辑  收藏  举报