夜猫子的知识栈 夜猫子的知识栈
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

夜猫子

前端练习生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 技术文档

    • Git使用手册
    • Markdown使用教程
    • npm常用命令
    • yarn基本命令
    • npm packageJson属性详解
    • yaml语言教程
    • Stylus预处理语言
    • Less预处理语言
    • Sass预处理语言
    • PWA运用
    • 富文本编辑器Ueditor
    • 发布npm
    • 构建一个TS的npm包
    • tsup打包工具
    • leaflet地图框架
    • pdfjs-dist使用
    • xlsx插件使用
      • 读取excle文件并解析详细文件信息
      • FileReader读取文件内容
        • FileReader的读取方法
      • XLSX解析文件内容
        • XLSX
        • read_opts
        • 解析type: base64
        • 解析 type: buffer
        • 解析 type: binary
      • excel数据预览
        • workbook 对象
        • sheet object 表格对象
        • cell object 单元格对象
        • XLSX.utils
      • 下载文件
        • workbook 对象
        • XLSX.utils
    • changesets
    • release-it
    • mathjs
  • GitHub技巧

  • 博客搭建

  • Ajax

  • Vite

  • Vitest

  • Nuxt

  • UI库文章

  • Docker

  • 技术
  • 技术文档
好脾气姑娘
2024-06-13
目录

xlsx插件使用

excel 表格解析插件

# xlsx插件使用

安装并引入XLSX (opens new window)

npm i xlsx
1

# 读取excle文件并解析详细文件信息

# FileReader读取文件内容

export const readExcel = (file) => {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onload = (e) => {
      const fileData = reader.result;
      // reader.result === e.target.result
      const result = [];
      parseExcelData(fileData, result);
      resolve(result);
    };
    reader.readAsArrayBuffer(file);
  });
};
1
2
3
4
5
6
7
8
9
10
11
12
13

# FileReader (opens new window)的读取方法

  • 【属性】readyState 表示FileReader状态的数字 {EMPTY: 0, LOADING: 1, DONE: 2}。
  • 【属性】result 文件的内容。该属性仅在读取操作完成后才有效。
  • 【事件】onload 在读取操作完成时触发。
  • 【方法】readAsArrayBuffer() 读取指定的 Blob 或 File 对象。一旦完成,会出发onload/onloadend事件,readyState状态会变味DONE,同时 result 属性中将包含一个 ArrayBuffer 对象以表示所读取文件的数据。
  • 【方法】readAsBinaryString() 和 readAsArrayBuffer 功能相同,区别是 result 属性将包含所读取文件原始二进制格式。(非标准: 该特性是非标准的,请尽量不要在生产环境中使用它!)
  • 【方法】readAsDataURL() 和 readAsArrayBuffer 功能相同,区别是 result 属性将包含所读取文件的 data:URL格式的字符串(base64编码)。
  • 【方法】readAsText() 异步读取指定的 Blob 或 File 对象,根据特殊的编码格式转化为内容(字符串形式)。

# XLSX解析文件内容

import * as XLSX from "xlsx";

export const parseExcelData = (fileData, result) => {
  const workbook = XLSX.read(fileData, { type: "binary" });
  workbook.SheetNames.forEach((sheetName) => {
    const tableAu = XLSX.utils.sheet_to_html(workbook.Sheets[sheetName]);
    result.push({
      sheetName,
      sheet: XLSX.utils.sheet_to_formulae(workbook.Sheets[sheetName]),
      json: XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]),
      tableAu,
    });
  });
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# XLSX (opens new window)

解析方法

  • XLSX.read(data, read_opts) 解析数据 data
  • XLSX.readFile(filename, read_opts) 解析文件名为 fileName 的文件,node环境下使用

# read_opts

1. type 文件类型

type expected input
"base64" string: Base64 encoding of the file 需要将内容转成 base-64 编码的 ASCII 字符串
"binary" string: binary string (byte n is data.charCodeAt(n)) 对应 fileReader.readAsBinaryString()
"string" string: JS string (characters interpreted as UTF8)
"buffer" nodejs Buffer 对应 fileReader.readAsArrayBuffer()
"array" array: array of 8-bit unsigned int (byte n is data[n]) Uint8Array,8位无符号数组;
"file" string: path of file that will be read (nodejs only) 文件的路径(仅nodejs下支持);

# 解析type: base64

1. buffer -> BinaryString -> base64

function fixdata(data) { //文件流转BinaryString
    let o = "", l = 0;
    const w = 10240;
    for (; l < data.byteLength / w; ++l) 
        o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)));
    o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)));
    return o;
}

const fileReader = new FileReader();
fileReader.onload = (e: any) => {
    const data = fileReader.result;
    const workbook = XLSX.read(btoa(fixdata(data)), {type:"base64"})
    // TODO: ...
};
fileReader.readAsArrayBuffer(file);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  1. fixdata() 将文件流 fileReader.readAsArrayBuffer() 获取搭配的文件流转为二进制字符串。
  2. btoa() (opens new window) 将二进制字符串转化为 base-64 编码的 ASCII 字符串。
  3. XLSX.read(encodedData, {type:"base64"}) 读取excel文件,获取workbook对象

image.png

2. base64文件

const fileReader = new FileReader();
fileReader.onload = (e: any) => {
    const data = fileReader.result;
    const workbook = XLSX.read((data as string).split(';')[1].replace('base64,',''), {type:"base64"});
    // TODO: ...
};
fileReader.readAsDataURL(file);
1
2
3
4
5
6
7

# 解析 type: buffer

ini复制代码const reader = new FileReader();
fileReader.readAsArrayBuffer(file)
reader.onload = (e: any) => {
    const data = reader.result;
    const workbook = XLSX.read(data, { type: 'buffer' });
    // TODO: ...
}
1
2
3
4
5
6
7

# 解析 type: binary

const reader = new FileReader();
fileReader.readAsBinaryString(file)
reader.onload = (e: any) => {
    const data = reader.result;
    const workbook = XLSX.read(data, { type: 'binary' });
    // TODO: ...
}
1
2
3
4
5
6
7

# excel数据预览

# workbook 对象

image.png

  • SheetNames 存放excel中sheet名称
  • Sheets 存放每个sheet中的具体内容

# sheet object 表格对象 (opens new window)

Sheets 每个对象代表一张表格,表格中除了以 ! 开头的都表示单元格,以 ! 开头的表示一些特殊的含义:

  • !ref 表示所有单元格范围
  • !margin 表示页边距,包含left、right、top、bottom、header、footer
  • !merges 表示合并单元格,是个数组,每个元素包含s和e两个对象分别表示开始和结束,s和e包含r和c两个对象分别表示行和列 image.png

# cell object 单元格对象 (opens new window)

Cell Object 每一个单元格是一个对象,包括 v、w、t、f、F、r、h、c、z、l、s 字段

  • t:表示内容类型,b Boolean, e Error, n Number, d Date, s Text等
  • v:表示原始值
  • w:表示格式化后的内容
  • f:表示公式,例如 f: "C3+4"
  • h:html内容
  • r:富文本内容rich text

# XLSX.utils (opens new window)

XLSX.utils 提供了直接可用的API解析

Exporting:

  • XLSX.utils.sheet_to_csv 生成CSV格式
  • XLSX.utils.sheet_to_txt 生成文本格式
  • XLSX.utils.sheet_to_json 输出json格式
  • XLSX.utils.sheet_to_html 将excel数据转化为html(table)
  • XLSX.utils.sheet_to_formulae 输出公式列表(带有值回退)。 image.png

# 下载文件

  1. XLSX.write 生成一个 sheet
  2. new Blob 将 binary 字符串转成 blob 对象
  3. URL.createObjectURL 将 blob 对象转成 url 下载地址
// 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
function sheet2blob(workbook) {
    // 生成excel的配置项
    var wopts: any = {
        bookType: 'xlsx', // 要生成的文件类型
        bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
        type: 'binary'
    };
    var wbout = XLSX.write(workbook, wopts);
    var blob = new Blob([s2ab(wbout)], {type:"application/octet-stream"});
    // 字符串转ArrayBuffer
    function s2ab(s: any) {
        var buf = new ArrayBuffer(s.length);
        var view = new Uint8Array(buf);
        for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
        return buf;
    }
    return blob;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

参考文章 JS弹出下载对话框以及实现常见文件类型的下载 (opens new window)

/**
 * 通用的打开下载对话框方法,没有测试过具体兼容性
 * @param url 下载地址,也可以是一个blob对象,必选
 * @param saveName 保存文件名,可选
 */
export function downloadDialog(sheetDatas, saveName = '导出.xlsx') {
    let url: any = sheet2blob(sheetDatas);
    
    if (typeof url == 'object' && url instanceof Blob) {
        url = URL.createObjectURL(url); // 创建blob地址
    }
    var aLink = document.createElement('a');
    aLink.href = url;
    aLink.download = saveName; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
    var event;
    if (window.MouseEvent) event = new MouseEvent('click');
    else {
        event = document.createEvent('MouseEvents');
        event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    }
    aLink.dispatchEvent(event);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# workbook 对象

workbook 的格式和 XLSX.read 读取出来的对象格式一致,包含 SheetNames 和 Sheets

👇 通过XLSX.utils提供的API生成workbook

image.png

# XLSX.utils (opens new window)

XLSX.utils 提供了直接可用的API解析

Importing:

  • XLSX.utils.aoa_to_sheet 将csv结构的二维数组转 sheet
  • XLSX.utils.json_to_sheet 将json格式数据转 sheet
  • XLSX.utils.table_to_sheet 将一个table dom直接转成 sheet,会自动识别colspan和rowspan并将其转成对应的单元格合并
  • XLSX.utils.sheet_add_aoa 向现有的工作表中添加一个csv数组
  • XLSX.utils.sheet_add_json 将一个json对象添加到现有的工作表中
const sheetName = 'sheet1';
const aoa = [['姓名','性别','年龄','注册时间'], ['张三','男','18','9/16/21','22'], ['李四','女','22','9/16/21','26'], ['主要信息','','','其它信息']];
const csv = `姓名,性别,年龄,注册时间,\n张三,男,18,9/16/21,22\n李四,女,22,9/16/21,26\n主要信息,,,其它信息,`;
const json = [
    { '姓名': '张三', '年龄': 18, '性别': '男', '注册时间': 44455.62984811343 },
    { '姓名': '李四', '年龄': 22, '性别': '女', '注册时间': 44455.62984811343 },
    { '姓名': '主要信息', '注册时间': '其它信息' },
];

workbook.SheetNames.push(sheetName);
// workbook.Sheets[sheetName] = XLSX.utils.json_to_sheet(json);
// workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet(aoa);
// workbook.Sheets[sheetName] = csv2sheet(csv);
workbook.Sheets[sheetName] = XLSX.utils.table_to_sheet(document.getElementsByTagName('table')[0]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
编辑 (opens new window)
上次更新: 2024/6/14 18:24:46
pdfjs-dist使用
changesets

← pdfjs-dist使用 changesets→

最近更新
01
IoC 解决了什么痛点问题?
03-10
02
如何调试 Nest 项目
03-10
03
Provider注入对象
03-10
更多文章>
Copyright © 2019-2025 Study | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式