基于 Vue 实现 Excel 的解析与导出
前言最近在整理日常开发中长涉及到的业务需求,正好想到了excel的解析与上传方面的事情,在开发中还是比较常见的,趁着周末做一下整理学习吧基本介绍主要基于Vue+element实现文件的解析与导出,用的的插件是xlsx[1],里面的具体方法,感兴趣的去研究一下,基本的样式,配置就不赘述了,也比较简单,我们直接上主食代码实现基本结构用户点击文件上传,将excel的表格已json的格式显示在页面中,用户
前言
最近在整理日常开发中长涉及到的业务需求,正好想到了 excel
的解析与上传方面的事情,在开发中还是比较常见的,趁着周末做一下整理学习吧
基本介绍
主要基于 Vue+element
实现文件的解析与导出,用的的插件是 xlsx[1],里面的具体方法,感兴趣的去研究一下,基本的样式,配置就不赘述了,也比较简单,我们直接上主食
代码实现
基本结构
用户点击文件上传,将 excel
的表格已 json
的格式显示在页面中,用户进行操作,检查数据后对服务进行提交,上传操作用的的 element
中的 upload
组件
<!-- 上传文件按钮 -->
<div class="buttonBox">
<el-upload
action
accept=".xlsx, .xls"
:auto-upload="false"
:show-file-list="false"
:on-change="handle"
>
<el-button type="primary" slot="trigger">选取EXCEL文件</el-button>
</el-upload>
<el-button type="success" @click="submit" :disabled="disable">采集数据提交</el-button>
</div>
<!-- 解析出来的数据 -->
<div class="tableBox" v-show="show">
<h3>
<i class="el-icon-info"></i>
小主,以下是采集完成的数据,请您检查无误后,点击“采集数据提交”按钮上传至服务器哦!
</h3>
<el-table :data="tempData" style="width: 100%" :height="height" border>
<el-table-column prop="name" label="姓名" min-width="50%"></el-table-column>
<el-table-column prop="phone" label="电话" min-width="50%"></el-table-column>
</el-table>
</div>
上传解析
-
通过
upload
组件可以获取上传的文件流(下图)
-
将文件流转为二进制,这里我们可以在
utils
文件中增加对应的方法(如下)
// 把文件按照二进制进行读取
export function readFile(file) {
return new Promise(resolve => {
let reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = ev => {
resolve(ev.target.result);
};
});
}
-
通过
xlsx
将二进制六转为json
,这样才能显示
//读取FILE中的数据(变为JSON格式)
let data = await readFile(file);
let workbook = xlsx.read(data, { type: "binary" }),
worksheet = workbook.Sheets[workbook.SheetNames[0]];
data = xlsx.utils.sheet_to_json(worksheet);
// 打印结果加下图
console.log(workbook);
-
把读取出来的数据变为最后可以传递给服务器的数据,我们需要先封装一个映射表来对应传给后端的格式(如下)
// 字段对应表
export let character = {
name: {
text: "姓名",
type: 'string'
},
phone: {
text: "电话",
type: 'string'
}
};
-
转换数据格式
let arr = [];
data.forEach(item => {
let obj = {};
for (let key in character) {
if (!character.hasOwnProperty(key)) break;
let v = character[key],
text = v.text,
type = v.type;
v = item[text] || "";
type === "string" ? (v = String(v)) : null;
type === "number" ? (v = Number(v)) : null;
obj[key] = v;
}
arr.push(obj);
});
-
发送给服务器
这里要看服务器支持多条文件一起发送,如果不支持我们前端就可以采用递归逐条发送的方式进行发送,具体情况可以与后端进行沟通,我们这采用递归的方式进行传输
// 提交数据给服务器
async submit() {
if (this.tempData.length <= 0) {
this.$message({
message: "小主,请您先选择EXCEL文件!",
type: "warning",
showClose: true
});
return;
}
this.disable = true;
let loadingInstance = Loading.service({
text: "小主,请您稍等片刻,奴家正在玩命处理中!",
background: "rgba(0,0,0,.5)"
});
// 完成后处理的事情
let complate = () => {
this.$message({
message: "小主,奴家已经帮您把数据上传了!",
type: "success",
showClose: true
});
this.show = false;
this.disable = false;
loadingInstance.close();
};
// 需要把数据一条条传递给服务器
let n = 0;
let send = async () => {
if (n > this.tempData.length - 1) {
// 都传递完了
complate();
return;
}
let body = this.tempData[n];
// 走接口
let result = await createAPI(body);
if (parseInt(result.code) === 0) {
// 成功
n++;
}
send();
};
send();
}
以上就是对 Excel
文件的解析与上传的总结,其实并不是很难,都是日常开发常常涉及的业务,接下来一起看下 Excel
的导出吧
Excel 的导出
基本结构
一进来页面获取刚刚上传的文件,然后显示在表格中,然后做个分页.......这些就不说了,我们直接从点击导出 excel
按钮开始,先看下页面结构
<div class="container">
<!-- 上传按钮 -->
<div class="buttonBox">
<router-link to="/upload">
<el-tooltip content="EXCEL数据采集" placement="top">
<el-button type="primary" icon="el-icon-edit" circle></el-button>
</el-tooltip>
</router-link>
</div>
<!-- 搜索区域 -->
<div class="searchBox">
<el-input v-model="search" placeholder="基于姓名、手机模糊搜索" @change="searchHandle"></el-input>
<el-button type="success" @click="submit" :disabled="disabled">导出选中的数据</el-button>
</div>
<!-- 列表区域 -->
<div class="tableBox">
<el-table
:data="tableData"
:height="height"
style="width: 100%"
v-loading="loading"
element-loading-text="小主,奴家正在努力加载中..."
@selection-change="selectionChange"
>
<el-table-column type="selection" width="50" align="center"></el-table-column>
<el-table-column prop="id" label="编号" min-width="10%"></el-table-column>
<el-table-column prop="name" label="姓名" min-width="20%"></el-table-column>
<el-table-column prop="phone" label="电话" min-width="20%"></el-table-column>
<el-table-column prop="time" label="创建时间" min-width="25%" :formatter="formatter"></el-table-column>
</el-table>
</div>
<!-- 分页区域 -->
<div class="pageBox">
<el-pagination
background
hide-on-single-page
layout="total, sizes, prev, pager, next"
:page-size="pageSize"
:current-page="page"
:total="total"
@size-change="sizeChange"
@current-change="prevNext"
@prev-click="prevNext"
@next-click="prevNext"
></el-pagination>
</div>
</div>
导出 Excel
将 json
数据变为 sheet
数据,新建表格,在表格中插入一个 sheet
,通过 xlsx
的 writeFile
方法将文件写入
// 导出数据
submit() {
if (this.selectionList.length <= 0) {
this.$message({
message: "小主,请您先选择要导出的数据哦!",
type: "warning",
showClose: true
});
return;
}
this.disabled = true;
let loadingInstance = Loading.service({
text: "小主,请您稍等片刻,奴家正在玩命处理中...",
background: "rgba(0,0,0,.5)"
});
let arr = this.selectionList.map(item => {
return {
编号: item.id,
姓名: item.name,
电话: item.phone
};
});
// 将json数据变为sheet数据
let sheet = xslx.utils.json_to_sheet(arr),
// 新建表格
book = xslx.utils.book_new();
// 在表格中插入一个sheet
xslx.utils.book_append_sheet(book, sheet, "sheet1");
// 通过xlsx的writeFile方法将文件写入
xslx.writeFile(book, `user${new Date().getTime()}.xls`);
loadingInstance.close();
this.disabled = false;
}
以上是对 Excele
的相关操作,今天就到这了,最后送给前端小伙伴们一句话
夫学须静也,才须学也,非学无以广才,非志无以成学。淫慢则不能励精,险躁则不能治性。年与时驰,意与日去,遂成枯落
更多推荐
所有评论(0)