最近写到一个需要实现excel文件的导入与导出功能
这边主要是借助一个插件进行文件解析,可直接通过npm引入,我这边的版本是0.17.0
前置插件引入: npm i xlsx
模块引入插件
import XLSX from 'xlsx';
curdata 即为后台返回的数据
导出功能实现(正常导出excel数字会遵循科学计数格式转为e+17,故这边转为字符串):
outExcel(): void {
let exportItems = [{ '户号': null, '手机号': null, '内容': null }];
const viewItems = JSON.parse(JSON.stringify(curdata));
const newViewItems = [];
/** 将filename转换为label */
if (viewItems && viewItems.length > 0) {
viewItems.forEach(viewItem => {
for (let key in viewItem) {
/** 提前将后台返回的表格不需要的数据删除以免后续导出出现额外数据 */
if (!this.listArrJson.find(listItem => listItem.value == key)) {
delete viewItem[key];
}
this.listArrJson.find(listItem => {
if (listItem.value === key) {
viewItem[listItem.label] = viewItem[key];
}
})
}
})
/** 对后台返回的数据进行表格键值对排序 */
viewItems.forEach(item => {
const tmpItem = new Object();
this.listArrJson.forEach(e => {
if (item[e.value]) {
tmpItem[e.label] = item[e.value];
}
})
newViewItems.push(tmpItem);
})
/** 删除多余filename */
newViewItems.forEach(viewItem => {
for (let key in viewItem) {
this.listArrJson.find(listItem => {
if (listItem.value === key) {
delete viewItem[key];
}
})
}
})
/** 数字化处理 */
newViewItems.forEach(viewItem => {
for (let key in viewItem) {
// if (typeof viewItem[key] === 'number') {
viewItem[key] = viewItem[key] ? " " + viewItem[key].toString() : null;
// }
}
})
console.log(newViewItems);
exportItems = JSON.parse(JSON.stringify(newViewItems));
}
/* generate worksheet */
const ws = XLSX.utils.json_to_sheet(exportItems)
// 设置每列的列宽,10代表10个字符,注意中文占2个字符
ws['!cols'] = [
{ wch: 10 },
{ wch: 30 },
{ wch: 25 }
]
// 新建book
const wb = XLSX.utils.book_new()
// 生成xlsx文件(book,sheet数据,sheet命名)
XLSX.utils.book_append_sheet(wb, ws, '数据详情')
// 写文件(book,xlsx文件名称)
XLSX.writeFile(wb, '导出名.csv')
}
导出效果:
导入功能实现:
html(html我这块使用的是angular的双向绑定语法,其他技术框架只需更换一下对应的file绑定方式即可):
<input id="testImport" type="file" [(ngModel)]="file" (change)="handleChange($event)" accept="*"/>
ts:
handleChange(e) {
const that = this;
//判断是否为文件
if (!e.target.files) {
return;
}
var f = e.target.files[0];
var reader = new FileReader();
reader.readAsBinaryString(f);
reader.onload = function(e) {
var data = e.target.result;
var wb = XLSX.read(data, {
type: 'binary' //设置类型,读取二进制
});
//读第一个Sheet文件内容
var items = JSON.stringify(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]));
that.excelItems = JSON.parse(items);
// 处理xlsx插件将空值过滤导致表格实际数据缺失的情况
that.excelItems.forEach((e, i, arr) => {
that.listArrJson.forEach(tmp => {
const label = tmp.label;
if (!e[label]) {
arr[i] = { label: null, ...e };
}
})
})
const reg = new RegExp('\t', 'g');
const reg1 = new RegExp('"', 'g');
that.excelItems.forEach((excelItem, index, arr) => {
for (let i in arr[index]) {
if (typeof arr[index][i] === 'string') {
arr[index][i] = arr[index][i].replace(reg, '').replace(reg1, '');
}
}
})
console.log(that.excelItems);
}
reader.onabort = function(e) {
alert("中断了")
}
reader.onerror = function(e) {
alert("出错了")
}
reader.onloadstart = function() {
console.log("onloadstart")
}
reader.onloadend = function() {
console.log("onloadend")
}
}
处理完打印出的结果是这样的(自己需要使用什么格式的数据遍历处理一下即可):
(PS:方法也是总结其他人并加以优化得到的,有可优化的地方也请不吝赐教)