前端导出excel之使用exceljs + file-saver导出表格到excel

最近在使用exceljs导出表格数据时遇到问题,这里分享下,避免大家踩坑。

首先贴个exceljs中文文档地址:https://github.com/exceljs/exceljs/blob/master/README_zh.md

。。。我一开始看的英文文档,看得脑阔疼,过了好久才发现居然还有个中文文档?好吧,我鼠标滚太快了,直接看的正文,根本没注意这行。。。


image.png

image.png

先贴个最简单的导出表格例子

<!-- 纯前端导出excel案例 -->
<template>
  <div class="wrap">
    <div>
      <el-button type="primary" @click="exportExcel">导出excel</el-button>
    </div>
    <div style="width:500px;margin: 20px auto;">
      <el-table
        border
        :data="tableData"
        style="width: 100%">

        <template v-for="(item,index) in tableHeader">
          <el-table-column
            :key="index"
            v-bind="item">
          </el-table-column>
        </template>

      </el-table>
    </div>

  </div>
</template>
<script>
  import ExcelJS from 'exceljs'
  import FileSaver from 'file-saver'
  export default {
    name: 'exceljs-demo',
    data(){
      return {
        tableHeader: [
          {
            prop: 'date',
            label: '日期'
          },
          {
            prop: 'name',
            label: '姓名'
          },
          {
            prop: 'address',
            label: '地址'
          }
        ],
        tableData: [{
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        }, {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        }, {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄'
        }, {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }]
      }
    },
    methods: {
      // 是否为空
      $isNull(val){
        return val === null || val === void 0 || val === '' || (val).toString() === 'NaN'
      },
      async exportExcel(){
        const workbook = new ExcelJS.Workbook();
        workbook.creator = 'Me';
        workbook.lastModifiedBy = 'Her';
        workbook.created = new Date(1985, 8, 30);
        workbook.modified = new Date();
        workbook.lastPrinted = new Date(2016, 9, 27);

        // 创建带有红色标签颜色的工作表
        const sheet = workbook.addWorksheet('My Sheet', {properties: {tabColor: {argb: 'FFC0000'}}});

        // 生成columns
        let columns = []
        this.tableHeader.map(item => {
          columns.push({
            name: item.label,
//            width: 30 // 这里设置宽度不起作用,详情请看table 下 列属性,里面没有width 属性
          })
        })

        // 生成rows
        let rows = []
        this.tableData.map(item => {
          let arr = []
          this.tableHeader.map(sub => {
            arr.push(!this.$isNull(item[sub.prop]) ? item[sub.prop] : '')
          })
          rows.push(arr)
        })

        sheet.addTable({
          name: 'MyTestTable',
          ref: 'C3', // 表格左上角的位置
          headerRow: true,
          totalsRow: false,
          style: {
            theme: 'TableStyleLight1',
//            showRowStripes: true,
          },
          columns: columns,
          rows: rows,
        })

        // workbook.xlsx.writeFile('test.xlsx')
        workbook.xlsx.writeBuffer().then(buffer => {
          FileSaver.saveAs(new Blob([buffer], {type: 'application/octet-stream'}), `test.xlsx`);
        })
      }
    }
  }
</script>
<style scoped>
</style>

版本如下:


image.png

页面效果如下:

image.png

导出效果如下:
image.png

问题1:为什么这里还要使用file-saver,官方不是提供了 writeFile 方法吗?

官网截图:


image.png

然后我也这样用了:

image.png

结果浏览器报错了:
image.png

最后发现workbook.xlsx.writeFile(filename)是在node端用的:
image.png

app.js代码如下,可以自己试下:

let excel = require("exceljs");
let workbook = new excel.Workbook();
workbook.creator = 'Me';
workbook.lastModifiedBy = 'Her';
workbook.created = new Date(1985, 8, 30);
workbook.modified = new Date();
workbook.lastPrinted = new Date(2016, 9, 27);

let sheet1 = workbook.addWorksheet('Sheet1');
let reColumns=[
  {header:'FirstName',key:'firstname'},
  {header:'LastName',key:'lastname'},
  {header:'Other Name',key:'othername'}
];
sheet1.columns = reColumns;
workbook.xlsx.writeFile("./test.xlsx").then(function() {
  console.log("xlsx file is written.");
});

问题2:导出的表格如何更改列宽?

image.png

首先这里设置width是没效果的
image.png

官网表格列属性介绍:
image.png

解决办法:使用getColumn给每列设置宽度
image.png

image.png

问题3:优化,把导出的表格样式修改下,将表头居中,并设置边框。

官网截图:


image.png

代码如下,替换之前添加的那三行设置宽度的代码:

        // 表格列宽设置
        sheet.getColumn('C').width = 15
        sheet.getColumn('D').width = 15
        sheet.getColumn('E').width = 30

        // 表头 居中并设置边框
        let h1 = sheet.getCell('C3')
        let h2 = sheet.getCell('D3')
        let h3 = sheet.getCell('E3')

        let arr = [h1, h2, h3]
        arr.map(item => {
          // 居中 
          item.alignment = {vertical: 'middle', horizontal: 'center'}
          // 边框
          item.border = {
            top: {style: 'thin'},
            left: {style: 'thin'},
            bottom: {style: 'thin'},
            right: {style: 'thin'}
          }
        })

效果图如下:


image.png

上面的方式有点low,如果表头过多或者我还需要对表格其他单元格设置样式,就得需要对上面的代码进行封装了, 这个在下一篇贴封装后的代码。

问题4:表格主题样式有哪些?

image.png

官网没有样式效果,小伙伴们可以自己试下。

更多exceljs的使用请查阅官网:
https://www.npmjs.com/package/exceljs

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容