该篇文章主要基于 vue-element-admin 框架
前置知识
FileReader
https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
XLSX 库
https://oss.sheetjs.com/ (在线 demo)
https://github.com/SheetJS/sheetjs
解析工作薄
从电子表格的字节中提取数据
var workbook = XLSX.read(data,opts)
workbook 就是 excel 中的sheet。可能会有多个。
生成 JSON和 JS数据
从工作表创建一个js对象数组
var jsa = XLSX.utils.sheet_to_json(worksheet, opts);
Excel 导出
Excel 的导入导出都是依赖于js-xlsx来实现的。
在 js-xlsx的基础上又封装了Export2Excel.js来方便导出数据。
使用
由于 Export2Excel不仅依赖js-xlsx还依赖file-saver和script-loader。
npm install xlsx file-saver -Snpm install script-loader -S -D
由于 js-xlsx 体积还是很大的,导出功能也不是一个非常常用的功能,所以使用的时候建议增加懒加载。使用方法如下:
import('@/vendor/Export2Excel').then(excel => {excel.export_json_to_excel({header: tHeader, //表头 必填data, //具体数据 必填filename: 'excel-list', //非必填autoWidth: true, //非必填bookType: 'xlsx' //非必填})})
参数
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| header | 导出数据的表头 | Array | / | [] |
| data | 导出的具体数据 | Array | / | []] |
| filename | 导出文件名 | String | / | excel-list |
| autoWidth | 单元格是否要自适应宽度 | Boolean | true / false | true |
| bookType | 导出文件类型 | String | xlsx, csv, txt, more | xlsx |
示例
import('@/vendor/Export2Excel').then(excel => {const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date']const data = this.listexcel.export_json_to_excel({header: tHeader, //表头 必填data, //具体数据 必填filename: 'excel-list', //非必填autoWidth: true, //非必填bookType: 'xlsx' //非必填})})
简单封装 json 导出 Excel 处理
/*** 导出Excel* @param json 要导出的json数据* @param name 要导出的文件名* @param type 要导出的数据类型* @constructor*/MixinExportJosnToExcel(json,name = "data",type = "application/octet-stream") {const wb = { SheetNames: [], Sheets: {}, Props: {} };if (!Array.isArray(json)) json = [json];json.forEach((item) => {wb.SheetNames.push(item.sheet_name);wb.Sheets[item.sheet_name] = XLSX.utils.json_to_sheet(item.sheet_values,item.sheet_options);});const wopts = { bookType: "xlsx", bookSST: false, type: "binary" };const blob = new Blob([s2ab(XLSX.write(wb, wopts))], { type });const link = document.createElement("a");document.body.appendChild(link);link.style.display = "none";link.href = window.URL.createObjectURL(blob);link.download = `${name}.xlsx`;link.click();// 释放资源setTimeout(() => {URL.revokeObjectURL(link.href);}, 100);function s2ab(s) {if (typeof ArrayBuffer !== "undefined") {const buf = new ArrayBuffer(s.length);const view = new Uint8Array(buf);for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;return buf;} else {const buf = new Array(s.length);for (let i = 0; i !== s.length; ++i) buf[i] = s.charCodeAt(i) & 0xff;return buf;}}},
Excel 导入
封装了UploadExcelExcel 导入组件,支持点击和拖拽上传,同样它也是依赖js-xlsx的
它提供了两个回调函数:
beforeUpload你可以在上传之前做一些自己的特殊判断,如判断文件的大小是否大于 1 兆?若大于 1 兆则停止解析并提示错误信息。
beforeUpload(file) {const isLt1M = file.size / 1024 / 1024 < 1if (isLt1M) {return true}this.$message({message: 'Please do not upload files larger than 1m in size.',type: 'warning'})return false}
onSuccess 解析成功时候会触发的回调函数,它会返回表格的表头和内容。
handleSuccess({ results, header }) {this.tableData = resultsthis.tableHeader = header}
- 在线代码
分析导入功能
<input id="fileItem" ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick">handleClick(e) {console.log(document.getElementById('fileItem').files) //也可以获取const files = e.target.filesconst rawFile = files[0] // only use files[0]if (!rawFile) return// this.(rawFile)},
说明:当input type为file时,会有两个事件,change 和 input 。
首先使用 input 组件来获取上传的文件。具体参考。因为上传的是单个文件,所以取上传文件列表(数组)中的第一条数据。
当获取到数据之后,开始对其进行处理。
在处理之前可能需要对数据进行判断(按场景)
upload(rawFile) {this.$refs['excel-upload-input'].value = null // fix can't select the same excelif (!this.beforeUpload) {this.readerData(rawFile)return}const before = this.beforeUpload(rawFile)if (before) {this.readerData(rawFile)}},
如果没传判断的方法,那么直接读取数据。
如果有判断的方法,先执行,如果验证通过在读取数据。
- 读取数据
workbook打印结果,(注意:可能会有多个 SheetNames )// 解析表格内容readerData(rawFile) {console.log(rawFile, 'rawFile')this.loading = truereturn new Promise((resolve, reject) => {const reader = new FileReader()console.log(reader)reader.onload = e => {const data = e.target.resultconst workbook = XLSX.read(data, { type: 'array' })const firstSheetName = workbook.SheetNames[0]const worksheet = workbook.Sheets[firstSheetName]const header = this.getHeaderRow(worksheet)const results = XLSX.utils.sheet_to_json(worksheet)console.log(header, results)this.generateData({ header, results })this.loading = falseresolve()}reader.readAsArrayBuffer(rawFile)})},

拿到的 results 结果
相关文章
excel 表格导入,excel表格检验
https://juejin.cn/post/6969797925220122638
https://juejin.cn/post/6844903806824611854
