0


纯前端实现 导入 与 导出 Excel

最近经常在做 不规则

Excel

的导入,或者一些普通

Excel

的导出,当前以上说的都是纯前端来实现;下面我们来聊聊经常用到的Excel导出与导入的实现方案,本文实现技术栈以 Vue2 + JS 为例

导入分类:

  1. 调用 API 完全由后端来解析数据,清洗数据,前端只负责调用 API
  2. 前端解析 Excel ,清洗数据,把对应的数据处理成 API需要的 JSON;(本文主要介绍这个)

导出分类:

  1. 调用API 完全由后端来生成Excel,前端获得 API 返回的文件名,下载即可;
  2. 前端根据 JSON 数据来生成 Excel, 然后利用第三方库 file-saver 进行下载;(本文主要介绍这个)

导入

Excel

需要用到

xlsx

这个 npm 库

导出

Excel

需要用到

exceljs

,

file-saver

这两个

直接 npm install 对应库即可;

1. 导入Excel,处理数据

1.1 需求示例

在这里插入图片描述

假如我现在有一个这种 Excel 需要导入,前端负责解析 Excel,清洗数据,API 只需要 4-5 个有用的字段

1.2 具体实现 – html 部分

<section><el-button@click="handleUpload"size="mini"type="primary">{{l("ChooseFile")}}</el-button><inputv-show="false"@change="handleFileChange"ref="inputFile"type="file"/><el-alerttype="warning":closable="false"style="margin-top:6px;">
      {{'Please Upload (xls | xlsx) Type File'}}
    </el-alert></section>
importXLSXfrom"xlsx";handleUpload(){if(!this.importResult){this.$refs["inputFile"].click();}},handleFileChange(e){const file = e.target.files[0];const fileName = file.name.substring(file.name.lastIndexOf(".")+1);if(fileName !=="xlsx"&& fileName !=="xls"){this.$message.error(this.l("FileTypeError,PleaseTryAgain"));return;}const reader =newFileReader();
      reader.readAsBinaryString(file);
      reader.onload=(e)=>{const result = e.target.result;if(!result){this.errorMsg =this.l("NoData");this.step =1;return;}if(this.importType ===1){this.handleSinglePageExcel(result);}else{this.handleMultiplePageExcel(result);}};
      reader.onerror=(err)=>{thrownewError("UpLoadError: "+ err.stack);};},

1.3 具体实现 – 单个 sheet

handleSinglePageExcel(data){const wb =XLSX.read(data,{type:"binary",cellDates:true,});const sheet = wb.SheetNames[0];const importData =XLSX.utils.sheet_to_json(wb.Sheets[sheet],{range:-1,});const arr =[];for(let i =3; i < importData.length; i++){// 处理业务逻辑}this.importResult = arr;},

1.4 具体实现 – 多个 sheet

handleMultiplePageExcel(data){const wb =XLSX.read(data,{type:"binary",cellDates:true,});const sheetList = wb.SheetNames;const arrMap ={};// 多 Sheet 页数据;
  sheetList.forEach((t)=>{const importData =XLSX.utils.sheet_to_json(wb.Sheets[t],{range:2,});
    arrMap[t]= importData;});const arr =[];for(let t in arrMap){const importData = arrMap[t];// importData : 代表每个 Sheet 页的 Excel 数据}this.importResult = arr;},

1.4 相关参数

文件读取类型
类型预期输入base64Base64编码类型字符串binary二进制字符串(字节n是data.charCodeAt(n))stringJS字符串(仅适用于UTF-8文本格式)buffernodejs的buffer类型array数组file将被读取的文件路径(仅限nodejs)
常用方法

  • sheet_to_* 函数接受一个工作表和一个可选的options对象,主要是将excel文件转化为对应的数据格式,一般导入excel文件的时候使用
  • *_to_sheet 函数接受一个数据对象和一个可选的options对象,主要是将数据格式转化为excel文件,一般导出文件的时候使用
  • sheet_add_* 函数接受工作表、数据和可选选项。主要用途是更新一个现有的工作表对象

2. 根据已有数据,按需导出Excel

1.1 需求示例

在这里插入图片描述

假如我现在有一个这种查询表格需要导出,因为所有的数据都在表格中,所以不需要调用

API

也可以实现

1.2 具体实现

import{ Workbook }from"exceljs";import{ saveAs }from"file-saver";try{this.loading =true;// 创建一个工作簿const workbook =newWorkbook();// columns 需要生成的Excel列 { prop, label, width, sheetName | Detail }// sheetName 需要生成的 Sheet 页, 如果只生成一个 Sheet Excel 不用考虑这里const sheets = _.uniq(this.columns.map((t)=> t.sheetName ||"Detail"));for(let i =0; i < sheets.length; i++){const columns =this.columns.filter((t)=>(t.sheetName ||"Detail")=== sheets[i]);// addWorksheet 添加一个 Sheet 页const worksheet = workbook.addWorksheet(sheets[i]);
    worksheet.columns = columns.map((t)=>{// 需求处理const label = t.label ? t.label :this.propToLabel(t.prop);return{header:this.l(label),// Excel 第一行标题key: t.prop,width: label.length *2,// Excel 列的宽度};});// this.list -> 当前 table 数据 this.list.forEach((t)=>{const row =[];
      columns.forEach((x)=>{
        row.push(t[x.prop]||"");});// 生成的 Excel Sheet 添加数据
      worksheet.addRow(row);});// 第一行 Header 行添加自定义样式
    worksheet.getRow(1).eachCell((cell, colNumber)=>{
      cell.fill ={type:"pattern",pattern:"solid",fgColor:{argb:"cccccc",},bgColor:{argb:"#96C8FB",},};});}// 导出的文件名const code =this.exportTemple.code ||newDate().getTime();
  workbook.xlsx.writeBuffer().then((buffer)=>{// 调用 第三方库 下载刚生成好的ExcelsaveAs(newBlob([buffer],{type:"application/octet-stream",}),
      code +"."+"xlsx");this.loading =false;});}catch(e){
  console.error("clinet export error", e);}finally{this.loading =false;}

如果

大数据的量导出

建议还是后端来实现,前端要用

websocket

做优化,避免长时间 loading 带来不好的用户体验

标签: 前端 excel vue

本文转载自: https://blog.csdn.net/weixin_56650035/article/details/132666602
版权归原作者 程序员啊楠 所有, 如有侵权,请联系我们删除。

“纯前端实现 导入 与 导出 Excel”的评论:

还没有评论