前端导出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 @   小龙女先生  阅读(744)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示