前端导出excel之使用exceljs + file-saver导出表格到excel
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.


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:

Effect as shown:

Export effect:

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 discoveredworkbook.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.pngThis 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





