js-xlsx前端Excel操作

介绍

(因为excel有点长 这里我将用ex替代)
有时候我们会在前端进行一些数据的操作,可能是解析ex的数据,或者是将数据导出为ex文档。在前端解析ex其实还是挺方便的,任意结构的对象都可以使用。今天我遇到了一个难题所以我翻阅了很多文章,但大多都千篇一律的,并没有什么营养价值,也无法解决我的需求。所以我结合了之前项目中使用过的js-xlsx进行对ex简单得操作。

js-xlsx 提供的接口非常清晰主要分为两类、

  • xlsx对象本身提供的功能
    • 解析数据
  • utils工具类
    • 将数据添加到数据表对象上
    • 将二维数组以及符合格式的对象或者HTML转为工作表对象
    • 将工作簿转为另外一种数据格式
    • 行,列,范围之间的转码和解码
    • 工作簿操作
    • 单元格操作

常用API 解析

名称作用示例
read(data, {type: options})读取一个excel文件并返回book对象XLSX.read(data, {type: options});
book_new()创建一个book对象const wb= utils.book_new();
sheet_to_json(Sheet)将一个sheet对象转为JSON对象const sheetObj = utils.sheet_to_json(wb.Sheets[sheetName]);
json_to_sheet(data)将一个JSON对象数组转为sheet对象const sheet = utils.json_to_sheet(this.studentList);
aoa_to_sheet(data)将一个数组对象转为sheet对象const sheet = utils.aoa_to_sheet(this.studentList);
book_append_sheet(workbook, sheet, “sheet名称”)将sheet对象添加到book中utils.book_append_sheet(wb, sheet, "sheetName");

引入资源

# 可以通过npm进行引入
npm install xlsx -s
# cdn引入的话就自己去找吧

# 这里我是在组件中引用
import xlsx from "xlsx"; // 在页面中引入
import {read, writeFile, utils} from "xlsx"; // 在页面中 按序引入
# 全局引用可以在main.js中配置 
import * as XLSX from "xlsx";
Vue.prototype.$xlsx = XLSX;
#  按需引入
import {read, writeFile, utils} from "xlsx";
Vue.prototype.$xlsxRead = read;
Vue.prototype.$xlsxWriteFile = writeFile;
Vue.prototype.$xlsxUtils = utils;

简单使用

通过 读写 来举例使用

读取xlsx文件

<template>
	<div>
		<el-upload class="upload-demo" action="https://jsonplaceholder.typicode.com/posts/" :limit="1" :http-request="eradXlsx">
			<el-button type="primary">将文件拖到此处,或<em>点击上传</em></el-button>
		</el-upload>
	</div>
</template>

<script>
	import Vue from "vue";
	export default {
		name: 'Demo',
		data() {
			return {};
		},
		methods: {
			eradXlsx(params) {
				// 获取选中的文件
				const file = params.file;
				// 创建文件读取对象 用于读取file 和 blob
				const fileReader = new FileReader();
				// 读取文件到二进制 异步读取 配合 readAsBinaryString(file) 函数一起使用
				fileReader.onload = (event) => {
					console.log(event);
					// 得到二进制的result
					const { result } = event.target;
					console.log(result);
					// 通过$xlsxUtils 解析二进制流获得workbook对象
					const wb = this.$xlsx.read(result, {type: "binary"});
					console.log(wb);
					// 遍历sheet
					for (let sheetName in wb.Sheets) {
						// 虽然wb.Sheets中可以看出sheet都是一个对象 但是此处遍历只会得到sheetName
						console.log(sheetName);
						// 通过sheetName获取真正的sheet对象
						console.log(wb.Sheets[sheetName]);
						// 通过xlsxUtils.sheet_to_json() 转换成对象
						const sheetObj = this.$xlsx.utils.sheet_to_json(wb.Sheets[sheetName]);
						// 下面就是对象操作 根据实际情况自定
					}
				}
				// 以二进制方式打开文件
				fileReader.readAsBinaryString(file);
				// 阻止上传
				return false;
			}
		}
	}
</script>

写存xlsx文件

<template>
	<div>
		<el-button type="primary" @click="exportExcel">导出三年(2)班学生信息</em></el-button>
	</div>
</template>

<script>
	import Vue from "vue";
	export default {
		name: 'Demo',
		data() {
			return {
				studentList: [
					{name: '小明', age: 9, sex: '男'},
					{name: '小红', age: 8, sex: '女'},
					{name: '小智', age: 9, sex: '男'},
					{name: '小秀', age: 8, sex: '女'},
					{name: '小林', age: 9, sex: '女'},
					{name: '小欧', age: 8, sex: '男'},
					{name: '小晨', age: 9, sex: '男'}
				]
			};
		},
		methods: {
			exportExcel() {
				// 创建一个book对象
				const wb = this.$xlsx.utils.book_new();
				// 将学生数组对象转为sheet表
			  	const sheet =	this.$xlsx.utils.json_to_sheet(this.studentList);
				// aoa_to_sheet 是将数组转为sheet
			 	// const sheet = this.$xlsx.utils.aoa_to_sheet(this.studentList);
				// 将sheet 添加到book中
				this.$xlsx.utils.book_append_sheet(wb, sheet, "sheetName");
				// 导出
				writeFile(wb, `文件名称.xlsx`);
			}
		}
	}
</script>

深入了解WorkBook对象和Sheet对象

WorkBook 对象结构

​ 在前面我们已经了解过 通过 xlsx.read(data, { type: option }); 得到一个workbook对象
这里option 的类型有以下几个:

  • base64: 以base64方式读取
  • binary: BinaryString格式(byte n is data.charCodeAt(n))
  • string: UTF8编码的字符串
  • buffer: nodejs Buffer
  • array: Uint8Array,8位无符号数组
  • file: 文件的路径(仅nodejs下支持)

通过read()函数读取到的workbook对象他的结构

workbook对象结构.png

其中主要看 Props、SheetNames、Sheets 这三个属性

  • Props:存储文档的基本信息,例如文件作者、文件创建时间、最后修改时间、最后修改作者等等信息
  • SheetNames:存储工作簿中所有工作表的名称,为数组形式
  • Sheets:存储工作簿中所有工作表的详细数据

Sheet 对象结构

sheets结构.png

Sheets 保存了每个sheet的具体内容(我们称之为Sheet Object)。每一个sheet是通过类似A1这样的键值保存每个单元格的内容,我们称之为单元格对象(Cell Object

每一个Sheet Object表示一张表格,只要不是!开头的都表示普通cell

  • !ref:表示该表中数据所占用的单元格范围

    • excelDemo.png

    • 如这个表中的内容 占据从 A1H8 的范围则记录为:A1:H8

    • // 在开发中无法直接通过 sheet.!ref 获取这个属性
      sheet['!ref'] = "A1:Zn"; // 通过[]来获取属性 或者 对属性赋值
      
  • !margins:存储单元格边框信息

  • !merges:存放一些单元格合并信息,是一个数组,每个数组由包含se构成的对象组成,s表示开始,e表示结束,r表示行,c表示列

    • sheet_merges.png
    • 可以看到 合并的单元格就是上面图中的 计划时间 所在的单元格

Cell 对象结构

每一个单元格都是一个对象(Cell Object),它主要有tvrhw等字段(详见这里

Cell对象.png

  • t:表示内容类型
    • s表示string类型
    • n表示number类型
    • b表示boolean类型
    • d表示date类型
  • v:表示原始值
  • f:表示公式,如B2+B3
  • h:HTML内容
  • w:格式化后的内容
  • r:富文本内容rich text

操作合并单元格

<template>
	<div>
		<el-button type="primary" @click="exportExcel">导出三年(2)班学生信息</el-button>
	</div>
</template>

<script>
	export default {
		name: 'Demo',
		data() {
			return {
				studentList2: [
					["三年二班学生信息"],
					["姓名", "年龄", "性别"],
					["小明", 9, "男"],
					["小红", 8, "男"],
					["小智", 9, "男"],
					["小秀", 9, "女"],
					["小林", 8, "性别"],
					["小晨", 9, "女"]
				]
			};
		},
		methods: {
			exportExcel() {
				// 创建一个book对象
				const wb = this.$xlsx.utils.book_new();
				console.log("workbook:", wb);
				// 将学生数组对象转为sheet表
				// aoa_to_sheet 是将数组转为sheet
			  	const sheet = this.$xlsx.utils.aoa_to_sheet(this.studentList2);
				console.log("sheet", sheet);
                  // 设置合并单元格区间
				sheet["!merges"] = [
					{s:{r: 0, c: 0}, e:{r: 0, c: 2}} // 合并A1:C1
				]
				// 将sheet 添加到book中
				this.$xlsx.utils.book_append_sheet(wb, sheet, "sheetName");
				// 导出
				writeFile(wb, `三年二班学生信息.xlsx`);
			}
		}
	}
</script>

引用:https://www.cnblogs.com/liuxianan/p/js-excel.html

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐