最近公司有个新需求,需要前端导出规定模板的excel,导入的时候前端解析excel文件,数据处理一下传给后台,下面分享下纯前端实现excel的导出和导入:
excel导出
handleClick = () => {
// 定制化改动地方
let excelData = this.state.excelData // 数据是后台返回渲染导出的excel数据的
let data = []
if (excelData.length) {
for (let i = 0; i < excelData.length; i++) {
let obj = {
'监控面编号': excelData[i].taskName,
'监控点编号': excelData[i].monitorPointNumber,
'高程(m)': '',
};
data.push(obj);
}
} else {
let obj = {
'监控面编号': '',
'监控点编号': '',
'高程(m)': '',
};
data.push(obj);
}
// 表格标题
const options = {
dataTitle: '表名:哈哈哈',
reportCompany: '说明:XXXX',
date: `日期`,
reportType: `施工工况`,
}
// 配置文件类型
const wopts = { bookType: 'xlsx', bookSST: true, type: 'binary', cellStyles: true };
this.recordExcelDown(data, wopts, options);
}
recordExcelDown = (json, type, options) => {
var tmpdata = json[0];
// 定制化改动地方
json.unshift({}, {}, {}, {}); // 向表格数据中插入4行位置(规定的模板)
const keyMap = []; // 获取keys
for (const k in tmpdata) { // 为插入的4行位置添加数据
keyMap.push(k);
// 定制化改动地方
json[3][k] = k; // json[3][k] = k 3为插入4行的最后一行索引,用于展示列头
}
var tmpdata = []; // 用来保存转换好的json
json
.map((v, i) => {
const data = keyMap.map((k, j) => {
return Object.assign(
{},
{
v: v[k],
position: (j > 25 ? this.getCharCol(j) : String.fromCharCode(65 + j)) + (i + 2), // 表格数据的位置
}
);
});
return data;
})
.reduce((prev, next) => prev.concat(next))
.forEach(
(v, i) =>
(tmpdata[v.position] = {
v: v.v,
})
);
let outputPos = Object.keys(tmpdata); // 设置区域,比如表格从A1到D10
// 定制化改动地方
tmpdata.A1 = { v: options.dataTitle }; // A1-A4区域的内容
tmpdata.A2 = { v: options.reportCompany };
tmpdata.A3 = { v: options.date };
tmpdata.A4 = { v: options.reportType };
tmpdata.C3 = { v: '2020-1-1' };
tmpdata.C4 = { v: '1号梁段挂篮就位' };
tmpdata.C6 = { v: '1.001' };
tmpdata.C1 = { v: 'tid' };
tmpdata.D1 = { v: this.props.taskId };
tmpdata.E1 = { v: 'bid' };
tmpdata.F1 = { v: this.props.bridgeRecord.id };
// 定制化改动地方
outputPos = ['A1'].concat(['A2'], ['A3'], ['A4'], ['C1'], ['C4'], ['C5'], ['C6'], ['D1'], ['D3'], ['D4'], ['D6'], ['E1'], ['F1'], outputPos);
// 定制化改动地方
tmpdata.A1.s = {
font: { sz: 14, bold: true, vertAlign: true },
alignment: { vertical: 'center', horizontal: 'center' }, // 垂直、水平
fill: { bgColor: { rgb: 'E8E8E8' }, fgColor: { rgb: 'E8E8E8' } },
}; // <====设置xlsx单元格样式
tmpdata.A2.s = {
font: { sz: 12, bold: true, vertAlign: true },
alignment: { vertical: 'center', horizontal: 'bottom' },
}; // <====设置xlsx单元格样式
tmpdata.A3.s = {
font: { sz: 12, bold: true, vertAlign: true },
alignment: { vertical: 'center', horizontal: 'bottom' },
}; // <====设置xlsx单元格样式
tmpdata.A4.s = {
font: { sz: 12, bold: true, vertAlign: true },
alignment: { vertical: 'center', horizontal: 'bottom' },
}; // <====设置xlsx单元格样式
// s-e 代表区域 c-r 代表列-行的索引
// 定制化改动地方
tmpdata['!merges'] = [
{
s: { c: 0, r: 0 },
e: { c: 1, r: 0 },
},
{
s: { c: 0, r: 1 },
e: { c: 9, r: 1 },
},
{
s: { c: 0, r: 2 },
e: { c: 1, r: 2 },
},
{
s: { c: 0, r: 3 },
e: { c: 1, r: 3 },
},
]; // <====合并单元格
let dataArrWidth = []
// 定制化改动地方
json.forEach(item => {
dataArrWidth.push({ wpx: 100 })
})
tmpdata['!cols'] = dataArrWidth;// <====设置一列宽度, 代表20列都是300宽
const tmpWB = {
SheetNames: ['mySheet'], // 保存的表标题
Sheets: {

本文分享了纯前端实现Excel的导出与导入方法。导出部分通过定制化的数据处理和样式设置,生成符合特定模板的Excel文件;导入部分利用FileReader读取文件,并解析Excel内容,提取所需数据。
最低0.47元/天 解锁文章
473

被折叠的 条评论
为什么被折叠?



