产品需求:后端不想写下载,导入和导出的接口,让我们前端自己实现。
这里我们就可以用xlsx插件来实现,我们不多说了,先放一下实现的图片,下面我们分别把模版下载、导入和导出的代码放上来,想用的话,直接复制粘贴即可!
首先,安装xlsx插件
//我这里用的是0.18.5版本
npm install xlsx@0.18.5
其次,配置表格导入导出的下载属性
<Button @click="downloadTemplate(tableInfo)">导出</Button>
...
data(){
return {
tableData:[],//表格数据
tableInfo:{
rowMerge:false,//行合并
columnsCheckAll: true,
columnsChecked:[],
exportColumnAll: true,
exportColumns:[],
exportColumnChecked: [],
visible:false,
importModal:false,//控制导入弹框显示
importFile:null,//存放导入excel
showImportTable:false,//控制导入展示数据表格显示
importTableData:[],//导入excel的数据
columns:[
{title: '考核维度', key: 'checkDimension'},
{title: '考核指标', key: 'checkIndicators'},
{title: '分值', key: 'score'}
],
importTableColumns:[],//导入excel的列
importTableNewData:[],//导入excel解析后的数据
},
}
}
然后,写下载方法
//下载导入模板
downloadTemplate(tableInfo){
let expData = [];
tableInfo.importColumns = this.appendTableImportColumns(tableInfo.columns);
var header = [];
tableInfo.importColumns.map((item,index)=>{
header[index] = item.title;
});
//1. 新建一个工作簿
let workbook = XLSX.utils.book_new();
//2.2 把json对象转成工作表
let sheet1 = XLSX.utils.json_to_sheet(expData,{header:header});
//3.在工作簿中添加工作表
XLSX.utils.book_append_sheet(workbook, sheet1, '导入模板'); //工作簿名称
XLSX.writeFile(workbook, '考核指标导入模板.xlsx'); // 保存的文件名
},
//获取导入表格的列
appendTableImportColumns(columns){
return columns.filter((item) =>{
if(item.hasOwnProperty("title")){
if(item.hasOwnProperty("key")){
return true;
}else{
if(item.hasOwnProperty("slot") && item.slot.split(".").length > 1){
item.key = item.slot.split(".")[1];
return true;
}else{
return false;
}
}
}
});
},
这里vue项目我用的是iview ui,也用了上传组件,我把下载模版和上传写在了一个弹窗内,如下图:
弹窗代码如下:
<Modal
title="导入数据"
v-model="tableInfo.importModal"
v-on:on-ok="poCheckKeyTableImportClass(tableInfo,tableData)"
width="400"
>
<div class="button_content_box">
<div class="finance_goods_list_main_content">
<div style="margin-bottom: 5px;" >点击此处进行 <a @click="downloadTemplate(tableInfo)">模版下载</a></div>
<Row>
<Col span="24">
<div>
<Upload type="drag" action=""
:before-upload="function(file) { return poCheckKeyTableHandleUpload(file,tableInfo)}">
<div style="padding: 20px 0">
<Icon type="ios-cloud-upload" size="52"></Icon>
<p>将文件拖到此处,<a>点击上传</a></p>
</div>
</Upload>
</div>
</Col>
</Row>
</div>
<div v-if="tableInfo.importFile"><span><Icon type="ios-podium" /></span>{{tableInfo.importFile.name }}</div>
</div>
</Modal>
下面方法能看懂最好,看不懂也无妨,直接复制粘贴拿去用就行,方法代码如下:
//上传导入文件前事件
poCheckKeyTableHandleUpload(file, tableInfo) {
let vm = this;
tableInfo.importFile = file;
let reader = new FileReader()
let rABS = typeof FileReader !== "undefined" && (FileReader.prototype || {}).readAsBinaryString
if (rABS) {
reader.readAsBinaryString(file)
} else {
reader.readAsArrayBuffer(file)
}
reader.onload = function (e) {
let data = e.target.result
if (!rABS) {
data = new Uint8Array(data)
}
let workBook = XLSX.read(data, {type: rABS ? 'binary' : 'array'})
workBook.SheetNames.forEach(name => {
let sheet = workBook.Sheets[name]
let json = XLSX.utils.sheet_to_json(sheet, {
raw: true,
header: 1,
defval: null
});
let tableData = [];
json.map((itemData, indexData) => {
if (indexData > 0) {
var attr = {};
json[0].map((item, index) => {
attr[item] = itemData[index];
});
tableData.push(attr);
}
});
let importTableColumns = [];
json[0].map((item, index) => {
var attr = {};
attr.title = item;
attr.key = item;
attr.width = 100;
importTableColumns.push(attr);
})
let tableNewData = [];
let columnCount = 0;
tableInfo.columns.map((item, index) => {
importTableColumns.some((itemColumn, indexColumn) => {
if (item.title == itemColumn.title) {
columnCount++;
var field = item.key;
if (field == undefined) {
field = item.slot.split(".")[1];
}
tableData.map((itemData, indexData) => {
if (columnCount == 1) {
var attr = {};
attr[field] = itemData[itemColumn.title];
tableNewData.push(attr);
} else {
tableNewData[indexData][field] = itemData[itemColumn.title];
}
})
return true;
}
});
});
if (tableNewData.length > 0) {
tableInfo.importTableData = tableData;
tableInfo.importTableColumns = importTableColumns;
tableInfo.importTableNewData = tableNewData;
tableInfo.showImportTable = true;
} else {
vm.$Message.error('请规范录入表格数据!');
}
})
}
return false;
},
//点击导入确认
poCheckKeyTableImportClass(tableInfo, data) {
tableInfo.showImportTable = false;
if (tableInfo.importTableNewData.length > 0) {
tableInfo.importTableNewData.map(item => {
data.push(item);
})
tableInfo.importTableNewData = [];
}
},
<Button type="primary" @click="onBtnExporttableClick(tableInfo,'考核得分信息')">
<span>导出</span>
</Button>
导出方法如下:
onBtnExporttableClick(tableInfo, fileName) {
tableInfo.visible = false;
if (tableInfo.params === undefined) {
tableInfo.params = {};
}
let expData = [];
tableInfo.columns.map((item, index) => {
this.tableData.map((itemData, indexData) => {
if (index == 0) {
var attr = {};
attr[item.title] = itemData[item.key];
expData.push(attr);
} else {
expData[indexData][item.title] = itemData[item.key];
}
})
})
//1. 新建一个工作簿
let workbook = XLSX.utils.book_new();
//2.2 把json对象转成工作表
let sheet1 = XLSX.utils.json_to_sheet(expData);
//3.在工作簿中添加工作表
XLSX.utils.book_append_sheet(workbook, sheet1, fileName); //工作簿名称
//4.输出工作表,由文件名决定的输出格式
XLSX.writeFile(workbook, fileName + '.xlsx'); // 保存的文件名
},
不要看到那么多代码就感觉很复杂,然而很简单没因为需要你作改动的并不多,当然你也可以根据自己需求去做的更加完善,简单的导入导出实现,这就足够啦,不需要做什么更改,复制粘贴就可以!