该篇文章主要基于 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

解析工作薄

从电子表格的字节中提取数据

  1. var workbook = XLSX.read(data,opts)

workbook 就是 excel 中的sheet。可能会有多个。

生成 JSON和 JS数据

从工作表创建一个js对象数组

  1. var jsa = XLSX.utils.sheet_to_json(worksheet, opts);

Excel 导出

Excel 的导入导出都是依赖于js-xlsx来实现的。
在 js-xlsx的基础上又封装了Export2Excel.js来方便导出数据。

使用

由于 Export2Excel不仅依赖js-xlsx还依赖file-saver和script-loader。

  1. npm install xlsx file-saver -S
  2. npm install script-loader -S -D

由于 js-xlsx 体积还是很大的,导出功能也不是一个非常常用的功能,所以使用的时候建议增加懒加载。使用方法如下:

  1. import('@/vendor/Export2Excel').then(excel => {
  2. excel.export_json_to_excel({
  3. header: tHeader, //表头 必填
  4. data, //具体数据 必填
  5. filename: 'excel-list', //非必填
  6. autoWidth: true, //非必填
  7. bookType: 'xlsx' //非必填
  8. })
  9. })


参数

参数 说明 类型 可选值 默认值
header 导出数据的表头 Array / []
data 导出的具体数据 Array / []]
filename 导出文件名 String / excel-list
autoWidth 单元格是否要自适应宽度 Boolean true / false true
bookType 导出文件类型 String xlsx, csv, txt, more xlsx

示例

  1. import('@/vendor/Export2Excel').then(excel => {
  2. const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date']
  3. const data = this.list
  4. excel.export_json_to_excel({
  5. header: tHeader, //表头 必填
  6. data, //具体数据 必填
  7. filename: 'excel-list', //非必填
  8. autoWidth: true, //非必填
  9. bookType: 'xlsx' //非必填
  10. })
  11. })

简单封装 json 导出 Excel 处理

  1. /**
  2. * 导出Excel
  3. * @param json 要导出的json数据
  4. * @param name 要导出的文件名
  5. * @param type 要导出的数据类型
  6. * @constructor
  7. */
  8. MixinExportJosnToExcel(
  9. json,
  10. name = "data",
  11. type = "application/octet-stream"
  12. ) {
  13. const wb = { SheetNames: [], Sheets: {}, Props: {} };
  14. if (!Array.isArray(json)) json = [json];
  15. json.forEach((item) => {
  16. wb.SheetNames.push(item.sheet_name);
  17. wb.Sheets[item.sheet_name] = XLSX.utils.json_to_sheet(
  18. item.sheet_values,
  19. item.sheet_options
  20. );
  21. });
  22. const wopts = { bookType: "xlsx", bookSST: false, type: "binary" };
  23. const blob = new Blob([s2ab(XLSX.write(wb, wopts))], { type });
  24. const link = document.createElement("a");
  25. document.body.appendChild(link);
  26. link.style.display = "none";
  27. link.href = window.URL.createObjectURL(blob);
  28. link.download = `${name}.xlsx`;
  29. link.click();
  30. // 释放资源
  31. setTimeout(() => {
  32. URL.revokeObjectURL(link.href);
  33. }, 100);
  34. function s2ab(s) {
  35. if (typeof ArrayBuffer !== "undefined") {
  36. const buf = new ArrayBuffer(s.length);
  37. const view = new Uint8Array(buf);
  38. for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
  39. return buf;
  40. } else {
  41. const buf = new Array(s.length);
  42. for (let i = 0; i !== s.length; ++i) buf[i] = s.charCodeAt(i) & 0xff;
  43. return buf;
  44. }
  45. }
  46. },

Excel 导入

封装了UploadExcelExcel 导入组件,支持点击和拖拽上传,同样它也是依赖js-xlsx的
它提供了两个回调函数:

  • beforeUpload你可以在上传之前做一些自己的特殊判断,如判断文件的大小是否大于 1 兆?若大于 1 兆则停止解析并提示错误信息。

    1. beforeUpload(file) {
    2. const isLt1M = file.size / 1024 / 1024 < 1
    3. if (isLt1M) {
    4. return true
    5. }
    6. this.$message({
    7. message: 'Please do not upload files larger than 1m in size.',
    8. type: 'warning'
    9. })
    10. return false
    11. }
  • onSuccess 解析成功时候会触发的回调函数,它会返回表格的表头和内容。

    1. handleSuccess({ results, header }) {
    2. this.tableData = results
    3. this.tableHeader = header
    4. }
  • 在线 DEMO

  • 在线代码

分析导入功能

  1. <input id="fileItem" ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick">
  2. handleClick(e) {
  3. console.log(document.getElementById('fileItem').files) //也可以获取
  4. const files = e.target.files
  5. const rawFile = files[0] // only use files[0]
  6. if (!rawFile) return
  7. // this.(rawFile)
  8. },

说明:当input type为file时,会有两个事件,change 和 input 。

  1. 首先使用 input 组件来获取上传的文件。具体参考。因为上传的是单个文件,所以取上传文件列表(数组)中的第一条数据。

  2. 当获取到数据之后,开始对其进行处理。

在处理之前可能需要对数据进行判断(按场景)

  1. upload(rawFile) {
  2. this.$refs['excel-upload-input'].value = null // fix can't select the same excel
  3. if (!this.beforeUpload) {
  4. this.readerData(rawFile)
  5. return
  6. }
  7. const before = this.beforeUpload(rawFile)
  8. if (before) {
  9. this.readerData(rawFile)
  10. }
  11. },

如果没传判断的方法,那么直接读取数据。
如果有判断的方法,先执行,如果验证通过在读取数据。

  1. 读取数据
    1. // 解析表格内容
    2. readerData(rawFile) {
    3. console.log(rawFile, 'rawFile')
    4. this.loading = true
    5. return new Promise((resolve, reject) => {
    6. const reader = new FileReader()
    7. console.log(reader)
    8. reader.onload = e => {
    9. const data = e.target.result
    10. const workbook = XLSX.read(data, { type: 'array' })
    11. const firstSheetName = workbook.SheetNames[0]
    12. const worksheet = workbook.Sheets[firstSheetName]
    13. const header = this.getHeaderRow(worksheet)
    14. const results = XLSX.utils.sheet_to_json(worksheet)
    15. console.log(header, results)
    16. this.generateData({ header, results })
    17. this.loading = false
    18. resolve()
    19. }
    20. reader.readAsArrayBuffer(rawFile)
    21. })
    22. },
    workbook打印结果,(注意:可能会有多个 SheetNames )
    image.png

拿到的 results 结果
image.png

相关文章

excel 表格导入,excel表格检验

https://juejin.cn/post/6969797925220122638

https://juejin.cn/post/6844903806824611854

https://xrkffgg.js.cool/Kvue/#/Js/002

https://lavine-30.com/archives/1423.html