js-xlsx excel导出学习

430 阅读4分钟

安装

npm install xlsx --save
npm install file-saver --save
npm install blob.js --save

引用

import XLSX from 'xlsx';
import FileSaver from 'file-saver';
import 'blob.js'

后面2个包用来实现在本地机器上的文件下载,知道它们的安装和用法就行,不去深究。

const s2ab = s => {
  let buf = new ArrayBuffer(s.length);
  let view = new Uint8Array(buf);
  for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
  return buf;
};

FileSaver.saveAs(new Blob([s2ab(workbook)], {
  type: 'application/octet-stream'
}), fileName + '.xlsx')

使用库之前先理解一下它的概念

workbook [excel文档]

首先是workbook,可以把它看作是一个excel文档。
我们要用xlsx导出excel,就是要按规范创建workbook
一个简单的workbook对象是这样的

const workbook = {
  SheetNames: [],           //工作表名数组
  Sheets: {}                //工作表对象 键名对应SheetNames的key
}

sheet [工作表]

workbook对象下面延伸出来的是sheet对象,很容易理解,它对应这个excel文档下面的工作表
一个workbook可以有多个sheet,就像下面这个对象这样,等于是有三个工作表的excel文档
sheet的常用配置项,我在代码中注释出来

const workbook = {
  SheetNames: [          //工作表名数组
    'Sheet1', 'Sheet2', 'Sheet2',
  ],
  Sheets: {               //工作表对象
    Sheet1: {  //工作表1
      '!ref': 'A1:C2',         //工作表的范围 如 必须 否则不显示
      '!margins': [             //工作表单元格合并配置项 可选
        {
          s: { //s start 开始
            c: 1,//cols 开始列
            r: 0 //rows 开始行
          },
          e: {//e end  结束
            c: 4,//cols 结束列
            r: 0 //rows 结束行
          }
        }
      ],
      '!cols': [                //工作表列宽配置项 可选
        {
          /* visibility */
          hidden? : boolean, // if true, the column is hidden
          /* column width is specified in one of the following ways: */
          wpx? : number, // width in screen pixels
          width? : number,  // width in Excel's "Max Digit Width", width*256 is integral
          wch? : number,  // width in characters
          /* other fields for preserving features from files */
          MDW? : number,  // Excel's "Max Digit Width" unit, always integral
        }
      ],
      '!rows': [                //工作表列高配置项 可选
        {
          /* visibility */
          hidden? : boolean, // if true, the row is hidden
          /* row height is specified in one of the following ways: */
          hpx? : number,  // height in screen pixels
          hpt? : number,  // height in points
          level? : number,  // 0-indexed outline / group level
        }
      ],
    },
    Sheet2: {}, //工作表2
    Sheet3: {}  //工作表3
  }
}

cell [单元格]

sheet 对象下面延伸出来的是cell 对象,对应的是工作表下的单元格,cell 对象键名是A1,B1这样与excel一致的键名

const workbook = {
  FileName: 'export.xlsx',
  SheetNames: ['Sheet1'],
  Sheets: {
    Sheet1:{
      '!ref': 'A1:B2',
      A1:{},
      A2:{},
      B1:{}, 
      B2:{}
    }
  }
}

js-xlsx提供了一个方法XLSX.utils.encode_cell来转换键名

XLSX.utils.encode_cell({
  c: 0, //cols 列 
  r: 0  //rows 行
};

知道相应的行列值就能方便的转换成键名了,需要注意的是行列是从0开始不是从1开始

XLSX.utils.encode_cell({c: 0, r: 0});//A1
XLSX.utils.encode_cell({c: 0, r: 1});//A2
XLSX.utils.encode_cell({c: 1, r: 0});//B1
XLSX.utils.encode_cell({c: 1, r: 1});//B2
XLSX.utils.encode_cell({c: 100, r: 100});//CW101
cell单元格对象的配置项
键名作用
v初始值 (请参见数据类型t部分)
w格式化文本 (如果适用)
t单元格数据类型: b Boolean, n Number, e error, s String, d Date
f单元格编码为A1样式的字符串(如果适用)
F如果公式为数组公式,则包含数组的范围(如适用)
r富文本编码(如适用)
hHTML 富文本呈现(如适用)
c单元格注释
z与单元格关联的数字格式字符串(如果请求)
l单元格超链接对象(.Target holds link, .Tooltip is tooltip)
s单元格的样式/主题(如果适用)

大概搞懂了workbook配置,先来创建一个简单的workbook看看是否能正常导出,这里要用到xlsx的write函数

XLSX.write(workbook, options)生成excel数据

第一个参数传入写好的workbook,第二个参数是配置项

write options 配置项
键名默认值描述
type输出数据编码(见下表Output Type)
cellDatesfalse存储日期为d类型(默认为n)
bookSSTfalse生成共享字符串表
bookType"xlsx"文档格式类型
sheet""单页格式的工作表名称
compressionfalse对基于ZIP的格式使用ZIP压缩
Props重写工作簿时重写工作簿属性
themeXLSXOverride theme XML when writing XLSX/XLSB/XLSM
Output Type
typeoutput
"base64"string: Base64 encoding of the file
"binary"string: binary string (byte n is data.charCodeAt(n))
"string"string: JS string (characters interpreted as UTF8)
"buffer"nodejs Buffer
"file"string: path of file that will be created (nodejs only)

感觉上面学习的内容已经足够导出一个简单的excel了,我先来试下

const workbook = {
  SheetNames: ['Sheet1'],
  Sheets: {
    Sheet1: {
      '!ref': 'A1:C2',
      A1: {v: '标题1', t: 's'},
      B1: {v: '标题2', t: 's'},
      A2: {v: '第2行第1列', t: 's'},
      B2: {v: '第2行第2列', t: 's'},
    }
  }
};

const workbookOut = XLSX.write(workbook, {
  bookType: 'xlsx',
  bookSST: false,
  type: 'binary'
});

FileSaver.saveAs(new Blob([s2ab(workbookOut)], {
  type: 'application/octet-stream'
}), 'export.xlsx')