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

Here's the polished English translation of the article: --- **Article Class: _2rhmJa**

Recently encountered issues while using exceljs to export table data. Here's a share to avoid common pitfalls.

First, here's the Chinese documentation for exceljs:https://github.com/exceljs/exceljs/blob/master/README_zh.md

Initially, I viewed the English documentation and felt completely lost. After a long time, I realized there's also a Chinese version! I was so focused on scrolling that I didn't notice this line.


image.png

image.png

Simple Table Export Example

<!-- Pure Frontend Excel Export Case -->
<template>
  <div class="wrap">
    <div>
      <el-button type="primary" @click="exportExcel">Export 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: 'Date'
          },
          {
            prop: 'name',
            label: 'Name'
          },
          {
            prop: 'address',
            label: 'Address'
          }
        ],
        tableData: [{
          date: '2016-05-02',
          name: 'Wang Xiaohu',
          address: 'Shanghai Pu Tong District Jia Sha Jiang Road 1518 No.'
        }, {
          date: '2016-05-04',
          name: 'Wang Xiaohu',
          address: 'Shanghai Pu Tong District Jia Sha Jiang Road 1517 No.'
        }, {
          date: '2016-05-01',
          name: 'Wang Xiaohu',
          address: 'Shanghai Pu Tong District Jia Sha Jiang Road 1519 No.'
        }, {
          date: '2016-05-03',
          name: 'Wang Xiaohu',
          address: 'Shanghai Pu Tong District Jia Sha Jiang Road 1516 No.'
        }]
      }
    },
    methods: {
      // Check if value is null
      $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);

        // Create worksheet with red label color
        const sheet = workbook.addWorksheet('My Sheet', {properties: {tabColor: {argb: 'FFC0000'}}});

        // Generate columns
        let columns = []
        this.tableHeader.map(item => {
          columns.push({
            name: item.label,
//            width: 30 // This setting is ineffective, details see table below
          })
        })

        // Generate 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', // Cell position
          headerRow: true,
          totalsRow: false,
          style: {
            theme: 'TableStyleLight1',
//            showRowStripes: true,
          },
          columns: columns,
          rows: rows,
        })

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

Version:


image.png

Effect as shown:

image.png

Export effect:
image.png

Problem 1: Why use file-saver instead of workbook.xlsx.writeFile?

Official screenshot:


image.png

Then I used it too:


image.png

Result in browser error:
image.png

Finally discovered workbook.xlsx.writeFile(filename) is used in Node.js:
image.png

app.js code:

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.");
});

Problem 2: How to adjust column widths?

Code:

        // Column width setting
        sheet.getColumn('C').width = 15
        sheet.getColumn('D').width = 15
        sheet.getColumn('E').width = 30

        // Header center with border
        let h1 = sheet.getCell('C3')
        let h2 = sheet.getCell('D3')
        let h3 = sheet.getCell('E3')

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

Effect:


image.png

This method is low. If the header is too many or I need to adjust other cells' styles, I need to encapsulate the code. This will be shared in the next post with the encapsulated code.

Problem 3: What are the theme styles available?

image.png

Official documentation doesn't show effects. Try it yourself.

More exceljs usage please refer to:

https://www.npmjs.com/package/exceljs