有个需求是上传一个文件,读取里面的内容,然后读取第三方的收费接口,然后将结果导出Excel,更是由于客户需要轻量级的应用,并不想进行配置运行环境和服务器部署,所以才有了这种需要前端来读写Excel的需求,博主在这里是用vue搭建了前端项目,最后用electron打包成PC端的可执行应用。在这里我们只介绍读写Excel。

首先需要用到的插件:

读取Excel的插件js-xlsx

npm install xlsx

这个插件亦可以进行Excel的导出,但是普通版本导出无法进行样式的设置,pro版本是收费的,所以还需要另一个封装的版本xlsx-style

npm install xlsx-style --save

接下来,是我画的页面:

<template><div class="content"><div class="filebox"><el-uploadclass="file"dragaction="#":multiple="false"accept=".xlsx,.xls":on-change="testUpload":auto-upload="false":on-remove="handleRemove"><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div><div class="el-upload__tip" slot="tip">只能上传xls/xlsx文件</div></el-upload></div><!-- <input type="file" @change="testUpload" /> --><div class="btnbox"><button class="btn" @click="open818">下载基本信息</button><button class="btn" @click="open848">下载风险信息</button><button class="btn" @click="open988">下载机构信息</button></div></div>
</template>

在这里使用了elementUI的上传插件,主要我写的样式不好看,功能也没有它的强大,需要注意的是:

  • auto-upload(自动上传)设置为false,因为我并不需要真的上传文件,我只是需要读取excel里面的文件数据。

  • action为必填项,不然控制台会一直报错,所以给个假地址

最终博主的页面大概如下,因为并未考虑所有浏览器的兼容性,CSS就不贴出来了:

然后我们要实现on-change的绑定事件,每当文件变动就会读取

    import XLSX from "xlsx";    // 读取excel数据并且转换为jsontestUpload(file) {const reader = new FileReader();reader.onload = function (ev) {const data = ev.target.result;// 使用XLSX的read方法可以直接读取const workbook = XLSX.read(data, { type: "binary" });const sheetNames = workbook.SheetNames; // 工作表名称集合const worksheet = workbook.Sheets[sheetNames[0]]; // 这里我们只读取第一张sheet 主要是调取查询参数信息// XLSX模块内置了工具类,可以将sheet对象直接转换为json格式的类型,key就是excel的表头const json = XLSX.utils.sheet_to_json(worksheet);let jsonstr = JSON.stringify(json);// 将json存储以备调用接口,你亦可以存放在store中sessionStorage.clear();sessionStorage.setItem("json", jsonstr);};// 这里是读取文件,只有这里执行,上面的onload才会执行reader.readAsBinaryString(file.raw);},

需要说明的地方:

  • on-change会传入文件对象,可以打印一下看看,file.raw就是blob文件

默认的input[type='file'],文件是file.target.files,files是个数组

  • XLSX.read方法的一点简单说明:

读取excel主要是通过XLSX.read(data, {type: type});方法来实现,返回一个叫WorkBook的对象,type主要取值如下:

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

将workbook转换为所需要的格式,内置了工具类,方法如下

XLSX.utils.sheet_to_csv 生成CSV格式
XLSX.utils.sheet_to_txt 生成纯文本格式
XLSX.utils.sheet_to_html 生成HTML格式
XLSX.utils.sheet_to_json 输出JSON格式

这个时候excel的读取就完成了,你在控制台已经可以看到读取到的json数据了,博主的逻辑是需要点击按钮才会调用接口,所以在此只是把json暂时存储起来,具体的需求请根据自己的业务进行实际更改,


接下来是导出了,导出我要先介绍一下XLSX.utils工具类里的几个导出方法:

导出的方法,返回worksheet对象

aoa_to_sheet 将一个二维数组转成sheet
table_to_sheet 将一个table dom直接转成sheet,会自动识别colspan和rowspan并将其转成对应的单元格合并
json_to_sheet 将一个由对象组成的数组转成sheet

在这里常用的其实是aoa_to_sheet,前端进行数据处理会简单一点,数据格式如下:

var aoa = [["姓名", "性别", "年龄", "注册时间"],["张三", "男", 18, new Date()],["李四", "女", 22, new Date()],
]

所以博主下载的方法如下:

// 查询基本信息
export async function getInfo() {let json = sessionStorage.getItem("json");let data = JSON.parse(json);// 构建二维数组,准备生成excel,第一个位列名let exceldata = [["统一社会信用代码","企业名","企业评分"]];// 循环调用接口,因为接口并未提供批量操作,请根据自己的业务进行更改for (const item of data) {await getBaseinfo818(item).then(res => {exceldata.push([res.creditCode ?? "",res.name ?? "",res.percentileScore ?? ""]);});}const sheet = XLSX.utils.aoa_to_sheet(exceldata);openDownloadDialog(sheet2blob(sheet), "基本信息.xlsx")
}

sheet2blob:将worksheet对象转换为blob,并设置一部分excel样式:

import XLSXSTYLE from "xlsx-style"export function sheet2blob(sheet, sheetName) {sheetName = sheetName || 'sheet1';var workbook = {SheetNames: [sheetName],Sheets: {}};// 设置单元格格式setExlStyle(sheet)workbook.Sheets[sheetName] = sheet;// 生成excel的配置项var wopts = {bookType: 'xlsx', // 要生成的文件类型bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性type: 'binary'};// 注意这里不是用XLSX来写了,因为不支持样式var wbout = XLSXSTYLE.write(workbook, wopts);var blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });// 字符串转ArrayBufferfunction s2ab(s) {var buf = new ArrayBuffer(s.length);var view = new Uint8Array(buf);for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;return buf;}return blob;
}// 设置excel单元格样式
function setExlStyle(data) {let borderAll = {  //单元格外侧框线top: {style: 'thin',},bottom: {style: 'thin'},left: {style: 'thin'},right: {style: 'thin'}};data['!cols'] = [];let fgColor = ""for (let key in data) {if (data[key] instanceof Object) {// 设置首行颜色,key实际就是excel的坐标,如:A1,B5,CH4。如果有更好的办法欢迎留言if(/^[A-Z]+1$/.test(key)){fgColor = "D8D8D8"}else{fgColor = "FFFFFF"}data[key].t = "String";       // 设置单元格格式为文本类型data[key].s = {border: borderAll,alignment: {horizontal: 'center',     //水平居中对齐vertical: 'center'},font: {sz: 11},fill: {fgColor: {rgb: fgColor},},bold: true,// numFmt: 0}// 设置列宽data['!cols'].push({ wpx: 150 });}}return data;
}

关于样式的设置,单元格的合并,建议还是看官方文档,博主仅仅是抛砖引玉为大家提供思路,介于一定会有人疑问data[key].t和data[key].s是什么,还是把官方文档拿过来给大家看一下,英语不好,翻译有问题的地方还请见谅:

key值 描述
v 初始值
w 格式化的文本(如果适用)
t 单元格格式:Boolean, Number, error, String, Date
f 单元格公式(如果适用)
e 富文本编码(如果适用)
h 富文本的 HTML 呈现(如果适用)
c 与单元格关联的注释 **
z 已弃用
l 单元格超链接对象
s 单元格的样式/主题(如果适用)

最后是导出方法openDownloadDialog,原理是创建a标签,然后模拟点击效果实现下载:

export function openDownloadDialog(url, saveName) {if (typeof url == "object" && url instanceof Blob) {url = URL.createObjectURL(url); // 创建blob地址}var aLink = document.createElement("a");aLink.href = url;aLink.download = saveName || ""; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效var event;if (window.MouseEvent) event = new MouseEvent("click");else {event = document.createEvent("MouseEvents");event.initMouseEvent("click",true,false,window,0,0,0,0,0,false,false,false,false,0,null);}aLink.dispatchEvent(event);
}

至此,完结


可能会遇到的问题:

  1. 出现类似如下的错误:

This relative module was not found:
* ./cptable in ./node_modules/xlsx-style/dist/cpexcel.js

修改你的vue.config.js,添加如下:


module.exports = {...chainWebpack: (config) => {...config.externals({ './cptable': 'var cptable' })  /* 这里是xlsx-style会报奇怪的错误添加的 */},...
};

vue读写excel相关推荐

  1. 前端实现生成带有样式的excel表格 Node和浏览器读写Excel文件探究实践

    最近碰到个需要自动生成表格的任务,作为前端的我,就想在 node 和浏览器中生成强大的表格,所以特此研究了很多关于表格的 npm 库 支持读写 Excel 的 node.js 模块 node-xlsx ...

  2. 封装vue导出excel组件(扩展嵌入图片、操作工作表、表格样式等功能)

    导出的excel中嵌入图片,同时还需要操作多个工作表与表格样式, 看了一些java的插件不太适合,因为我这边的需求是动态表单,字段不固定.后端的插件大部分依赖实体类注解,要不就是操作比较繁琐.又看了一 ...

  3. NPOI读写Excel

    1.整个Excel表格叫做工作表:WorkBook(工作薄),包含的叫页(工作表):Sheet:行:Row:单元格Cell. 2.NPOI是POI的C#版本,NPOI的行和列的index都是从0开始 ...

  4. .NET读写Excel工具Spire.Xls使用(1)入门介绍

    原文:[原创].NET读写Excel工具Spire.Xls使用(1)入门介绍 在.NET平台,操作Excel文件是一个非常常用的需求,目前比较常规的方法有以下几种: 1.Office Com组件的方式 ...

  5. 数据分析从零开始实战,Pandas读写Excel/XML数据

    点击查看第一篇文章: 数据分析从零开始实战,Pandas读取HTML页面+数据处理解析_ 数据分析 从零开始到实战,Pandas读写CSV数据_ 数据分析 从零开始到实战,Pandas读写CSV数据 ...

  6. php如何读写excel

    php如何读写excel 一.总结 一句话总结:PHP操作Excel最好的方法是使用PHPExcel类, 可以到官网下载PHPExcel类库 http://phpexcel.codeplex.com ...

  7. python怎么读excelsheet_python3 excle(python怎么读写excel文件)

    python读取已经打开的3个word和excle文件的路径 用 win32com 操控 word和Excel就可以实现 咋样把python写入excle中 # 需安装 xlrd-0.9.2 和 xl ...

  8. python读写excel数据--pandas

    文章目录 1读写excel数据 1.1 读: 1.1 写: 2举例 2.1 要求 2.2 实现 1读写excel数据 利用pandas可以很方便的读写excel数据 1.1 读: data_in = ...

  9. 解决读写Excel的第三方类库as3xls无法读取中文和写入中文的问题

    原文 http://blog.csdn.net/pizzaman/article/details/5700954 最近做地图编辑器需要用As3读写Excel,找到了as3xls但存在诸多问题,1.无法 ...

最新文章

  1. oracle修改数据高性能,oracle数据库的性能调整
  2. 七步带你认识计算机视觉
  3. 什么是Incremental Link Table[转]
  4. linux查询字段排序,Linux 操作命令 sort
  5. 代码合并工具_分享几款比较常用的代码比较工具
  6. vue2.X slot 分发内容
  7. Gray Code(格雷码) C++多方法实现
  8. Sharepoint COMException 0x81020037
  9. linux安装软件w,Linux软件安装小结
  10. 私教课程 Day2 2017-09-14
  11. 软件以人为本5 - 敏捷3 - 拯救每日立会2
  12. 区域生长算法原理及实现
  13. 重磅丨教育部《高校人工智能创新行动计划》权威解读, AI人才缺口竟有500万!
  14. Neon Love(霓虹爱)
  15. 愚人节的幽默感,我只服阿里云......
  16. Excel 筛选 多表查找
  17. 面试中关于MySQL十连问
  18. 面向对象 --OOP
  19. 吉尔伯特定律(转载)
  20. html微信网页字体被放大问题

热门文章

  1. Spring boot整合Redis实现发布订阅(超详细)
  2. Spring Cloud Gateway配置详解-过滤器
  3. 中国著名大学校训中英文对照
  4. 编程为什么要立flag
  5. 长期熬夜——真的不好
  6. Iowait的成因、对系统影响及对策
  7. Android实现客制化系统apk在线签名
  8. 35岁的程序员:第42章,复活
  9. echars地图 省市二级联动 插件
  10. pandas数据分析给力教程【完整版】(一)