前端導(dǎo)出excel之使用exceljs + file-saver導(dǎo)出表格到excel

最近在使用exceljs導(dǎo)出表格數(shù)據(jù)時遇到問題,這里分享下,避免大家踩坑。

首先貼個exceljs中文文檔地址:https://github.com/exceljs/exceljs/blob/master/README_zh.md

。。。我一開始看的英文文檔,看得腦闊疼,過了好久才發(fā)現(xiàn)居然還有個中文文檔?好吧,我鼠標(biāo)滾太快了,直接看的正文,根本沒注意這行。。。


image.png

image.png

先貼個最簡單的導(dǎo)出表格例子

<!-- 純前端導(dǎo)出excel案例 -->
<template>
  <div class="wrap">
    <div>
      <el-button type="primary" @click="exportExcel">導(dǎo)出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: '上海市普陀區(qū)金沙江路 1518 弄'
        }, {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀區(qū)金沙江路 1517 弄'
        }, {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀區(qū)金沙江路 1519 弄'
        }, {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀區(qū)金沙江路 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);

        // 創(chuàng)建帶有紅色標(biāo)簽顏色的工作表
        const sheet = workbook.addWorksheet('My Sheet', {properties: {tabColor: {argb: 'FFC0000'}}});

        // 生成columns
        let columns = []
        this.tableHeader.map(item => {
          columns.push({
            name: item.label,
//            width: 30 // 這里設(shè)置寬度不起作用,詳情請看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

導(dǎo)出效果如下:
image.png

問題1:為什么這里還要使用file-saver,官方不是提供了 writeFile 方法嗎?

官網(wǎng)截圖:


image.png

然后我也這樣用了:

image.png

結(jié)果瀏覽器報錯了:
image.png

最后發(fā)現(xiàn)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:導(dǎo)出的表格如何更改列寬?

image.png

首先這里設(shè)置width是沒效果的
image.png

官網(wǎng)表格列屬性介紹:
image.png

解決辦法:使用getColumn給每列設(shè)置寬度
image.png

image.png

問題3:優(yōu)化,把導(dǎo)出的表格樣式修改下,將表頭居中,并設(shè)置邊框。

官網(wǎng)截圖:


image.png

代碼如下,替換之前添加的那三行設(shè)置寬度的代碼:

        // 表格列寬設(shè)置
        sheet.getColumn('C').width = 15
        sheet.getColumn('D').width = 15
        sheet.getColumn('E').width = 30

        // 表頭 居中并設(shè)置邊框
        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,如果表頭過多或者我還需要對表格其他單元格設(shè)置樣式,就得需要對上面的代碼進(jìn)行封裝了, 這個在下一篇貼封裝后的代碼。

問題4:表格主題樣式有哪些?

image.png

官網(wǎng)沒有樣式效果,小伙伴們可以自己試下。

更多exceljs的使用請查閱官網(wǎng):
https://www.npmjs.com/package/exceljs

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容