当前位置:首页 » 《休闲阅读》 » 正文

前端 读取/导入 Excel文档

23 人参与  2024年09月21日 18:00  分类 : 《休闲阅读》  评论

点击全文阅读


情况: 需要通过Excel表,将数据导入到数据库,但是后台人员出差了,我又只会PHP,没用过node,所以只能前端导入Excel文件,然后循环调用后台的单条添加接口了。

库: Excel.js(版本4.3.0)

CDN地址:

<script src="https://cdn.bootcdn.net/ajax/libs/exceljs/4.3.0/exceljs.min.js"></script>

Excel.js 中文文档:https://gitee.com/alan_scut/exceljs

下面是动态Excel表单

在这里插入图片描述

下面是file文件(Excel文件)获取到的对象:

在这里插入图片描述

下面是代码中输出的需要插入的数据:

在这里插入图片描述

代码:

使用方法: importExcal()

// 全局函数执行完成后执行组件的钩子函数、组件事件、自定义事件// 导入Excel表async function importExcal() {  // 文件内容 (这里是从input file里面获取到的内容)  var file = input_file;  // 提交后端数据的整体数组  var data_arr = [];  // 行程的最大列数(包含前面不变的)  var stay_col_num = 0;  if (file) {    // 判断文件类型    let filetype = file.name.split('.')[file.name.split('.').length - 1]    let filetypes = '.xlsx,.xls'    if (filetypes.indexOf(filetype) === -1) {    this.$message({message: '请上传 .xlsx 或 .xls 文件。',type: 'warning'})      return;    }    // 读取文件文件    const reader = new FileReader();    // file.raw是具体的文件内容,需要看一下你获取到的是file.raw,还是file[0]即可 将文件转为 ArrayBuffer 格式    console.log("这里是获取到的file文件内容:", file)    // 这里要用 readAsArrayBuffer 转成buffer,因为下面读取要用到 buffer 才可以    reader.readAsArrayBuffer(file.raw);    reader.onload = function (event) {      try {        const result = event.target.result;        var workbook = new ExcelJS.Workbook();        // 读取 buffer 内容        workbook.xlsx.load(result)          .then(async function () {            // 迭代所有sheet (如果只有一个,可以通过名称获取 var worksheet = workbook.getWorksheet('My Sheet');)            workbook.eachSheet(async function (worksheet, sheetId) {              // 清空数据数组              data_arr = [];              // 获取 形成安排 的列数(从第8列开始的), 总不会超过100天,所以写个100              // 在这里获取 形成列的长度,是因为这里是表头,不会像内容一样出现空白单元格,造成无法获取到最终列的情况              for (let j = 8; j <= 100; j++) {                // 当列到 行程安排 且,j+1 不是 行程安排的时候,就是行程安排的列宽                if (worksheet.getCell(`${getLetter(j)}2`).value == '行程安排' && worksheet.getCell(`${getLetter(j + 1)}2`).value !== '行程安排') {                  stay_col_num = j;                  // 如果两个都有值的话,就跳出循环                  break;                }              }              // 迭代工作表中具有值的所有行              worksheet.eachRow(function (row, rowNumber) {                // 数据是从第四行开始                if (rowNumber >= 4) {                  // data_arr.push(row.values)                  // 每行的数据                  let row_data = row.values;                  // 传给后端的对象                  let data_obj = {                    "guest": "",                    "name": "",                    "sex": "",                    "company": "",                    "job": "",                    "phone": "",                    "stay": []                  }                  // 循环每行的数据                  row_data.map(function (item, index, arr) {                    // 如果是前7列,则是固定列的值,直接复制即可,否则的话则是 动态的行程安排                    if (index <= 7) {                      switch (index) {                        case 2:                          // 嘉宾类别                          data_obj.guest = item ? item : "";                          break;                        case 3:                          // 姓名                          data_obj.name = item ? item : "";                          break;                        case 4:                          // 性别                          data_obj.sex = item ? item : "";                          break;                        case 5:                          // 单位                          data_obj.company = item ? item : "";                          break;                        case 6:                          // 职务                          data_obj.job = item ? item : "";                          break;                        case 7:                          // 手机号                          data_obj.phone = item ? item : "";                          break;                      }                    } else {                      // 行程安排(从第八列开始到形成的最后一列结束)                      if (index >= 8 && index <= stay_col_num) {                        if (worksheet.getCell(`${getLetter(index)}${rowNumber}`).value == '是') data_obj.stay.push(worksheet.getCell(`${getLetter(index)}3`).value);                      }                    }                  })                  // 将插入后台的数据添加进数组                  data_arr.push(data_obj);                }              });              console.log("全部需要插入数据库的数据的数组:", data_arr)              // 这里使用了 Promise 解决在for循环内,使异步接口,进行同步提交的问题;文章后面有详细说明              for (let i = 0; i < data_arr.length; i++) {                let result_data = await createUser(data_arr[i]);                if (!result_data.result) {// 如果出错,就跳出循环this.$message({message: `第 ${i + 1} 行数据 ${data_arr[i].name}(${data_arr[i].phone}),由于 ${result_data.msg} 导入失败`,type: 'error'})// 跳出循环                break;                }              }            });          });      } catch (err) {      this.$message({message: '读取文件错误',type: 'error'})        console.log('err', err);      }    };  } else {  this.$message({message: '请选择文件',type: 'error'})  }}// 添加用户信息接口async function createUser(data) {  return await new Promise(function (resolve, reject) {    // 处理异步逻辑时候调用resolve和reject函数    axios({      method: 'POST',      url: `${base_url}/api/add`,      headers: {        // 没有可以不要token        // authorization: `bearer ${token}`      },      // 数据      data: data    }).then(res => {      let resp = res.data;      if (resp.code == 1) {        if (resp.data.code == 200) {          resolve({            "result": true          });        }      } else {        resolve({          "result": false,          "msg": resp.msg        });      }    }).catch(req => {      reject({        "result": false,        "msg": ""      });    });  });}// 获取第N个字母function getLetter(num) {  return String.fromCharCode(64 + num);}

代码中用到的方法总结:

新建工作簿

var workbook = new ExcelJS.Workbook();

读取 buffer 内容

workbook.xlsx.load(data).then(function() {
// 其他代码
});

迭代所有sheet

workbook.eachSheet(function(worksheet, sheetId) {
// 其他代码
});

按名称获取表格

var worksheet = workbook.getWorksheet(‘My Sheet’);

按ID获取表格

var worksheet = workbook.getWorksheet(1);

迭代工作表中具有值的所有行

worksheet.eachRow(function(row, rowNumber) {
console.log(‘Row:’ + rowNumber + ’ = ’ + JSON.stringify(row.values));
});

获取单元格(A2)

var collectcell = worksheet.getCell(‘A2’);

获取当前worksheet的最后一个单元格信息

var lastRowCell = worksheet.lastRow;
console.log(‘最后一行行数:’ + lastRowCell.number);

for循环内,使异步接口变成同步提交
我文章的地址:前端JS for循环内异步接口变成同步提交(JavaScript for循环异步变同步)

遇见的一些问题:
1. Excel.JS 支持的数据读取方式不同,获取的数据类型不同。例如:filestreambuffer

另外说一下
有兴趣的朋友也可以试试 SheetJS ,感觉好像功能更多一些,下次我再需要用到excel的时候也会尝试一下的。
SheetJS中文文档:https://github.com/rockboom/SheetJS-docs-zh-CN

尝试完成,回来记录一下: SheetJS 文档会更丰富一些,但是他分社区版(免费)和专业版(收费)。社区版不支持导出文件的样式修改,专业版才可以。

我决定还是继续用 Excel.js


点击全文阅读


本文链接:http://zhangshiyu.com/post/162870.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1