You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
5.1 KiB
159 lines
5.1 KiB
import XLSX from "xlsx";
|
|
import ajax from '@/utils/ajax'
|
|
import {
|
|
Message
|
|
} from 'element-ui';
|
|
const excelHeaderName = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
|
|
/**
|
|
* excel导出默认选项
|
|
*/
|
|
const exportOptionDefault = {
|
|
url: "",//*必填,导出请求地址
|
|
tableRef: undefined,//#1组合必填 导出数据对应列信息,el-table引用
|
|
columnMapping: undefined,//#1组合必填 自定义导出列映射
|
|
fileName: "export.xlsx",//导出文件名
|
|
params: {},//导出请求参数
|
|
rowFetcher: res => {//从请求结果中获取导出行的方式,默认取请求结果中的data作为导出数据
|
|
return (res || {data: []}).data;
|
|
},
|
|
columnFormatter: [],//需要格式化的列
|
|
mergeSetting: {
|
|
refs: [], //检测需要合并的数据列属性名
|
|
columns: [] //检测需要合并后,要合并的列,以第一条数据为准合并
|
|
},
|
|
dropColumns: [],//导出时需要过滤掉的列
|
|
};
|
|
let HEADERS = [];
|
|
for (let i =0;i< 200;i++) {
|
|
let c = parseInt(i / 26);
|
|
let m = i % 26;
|
|
HEADERS.push((c > 0 ? excelHeaderName[c - 1] : "") + excelHeaderName[m]);
|
|
}
|
|
let validOption = opt => {
|
|
let option = Object.assign({}, opt);
|
|
if (!option.url) {
|
|
throw new Error("request url is required.");
|
|
}
|
|
if (!option.tableRef && !option.columnMapping) {
|
|
throw new Error("element table ref object or columnMapping is required.");
|
|
}
|
|
if (option.rowFetcher != undefined && typeof option.rowFetcher != "function") {
|
|
throw new Error("rowFetcher must be a function with one param.");
|
|
}
|
|
}
|
|
|
|
let getMergeSetting = (data, s, allCols) => {
|
|
let refCols = s.refs;
|
|
let mcols = s.columns;
|
|
let mergeList = [];
|
|
|
|
let refRow = data[0];
|
|
let mergeSetting = {
|
|
s: 0,
|
|
e: 0
|
|
};
|
|
for (let i = 0; i < data.length; i++) {
|
|
let same = refCols.map(c => data[i][c] === refRow[c]).filter(r => !!r).length == refCols.length;
|
|
if (!same) {
|
|
mergeSetting.e > mergeSetting.s && (mergeList.push(mergeSetting));
|
|
refRow = data[i];
|
|
mergeSetting = {
|
|
s: i,
|
|
e: i
|
|
};
|
|
} else {
|
|
i > mergeSetting.e && (mergeSetting.e = i);
|
|
i == data.length - 1 && (mergeList.push(mergeSetting));
|
|
}
|
|
|
|
}
|
|
|
|
let setting = [];
|
|
mergeList.forEach(e => {
|
|
mcols.forEach(c => {
|
|
let ci = allCols.indexOf(c);
|
|
setting.push({
|
|
s: {
|
|
r: e.s + 1,
|
|
c: ci
|
|
},
|
|
e: {
|
|
r: e.e + 1,
|
|
c: ci
|
|
}
|
|
});
|
|
});
|
|
});
|
|
return setting;
|
|
}
|
|
|
|
let setStyle = (ws, s) => {}
|
|
|
|
let getColSetting = (mapping,dropColums) => {
|
|
let columns = [];
|
|
for (let i = 0; i < mapping.length; i++) {
|
|
let c = mapping[i];
|
|
if (dropColums.indexOf(c.columnProp) == -1) {
|
|
columns.push({
|
|
property: c.columnProp || c.property,
|
|
label: c.columnLabel,
|
|
type: "default"
|
|
});
|
|
}
|
|
}
|
|
return {
|
|
columns: columns
|
|
};
|
|
}
|
|
let export2Excel = opt => {
|
|
validOption(opt);
|
|
let options = Object.assign({}, exportOptionDefault, opt);
|
|
let expColSetting = !!options.tableRef ? options.tableRef : getColSetting(options.columnMapping, options.dropColumns);
|
|
ajax.$post(options.url, options.params, resp => {
|
|
if (resp.status !== 200) {
|
|
Message.error({
|
|
message: resp.description
|
|
});
|
|
}
|
|
let rows = !!resp.data.rows?options.rowFetcher(resp).rows:resp.data.page.list;
|
|
var columns = [
|
|
[]
|
|
];
|
|
var keys = [];
|
|
let formaters = new Array();
|
|
expColSetting.columns.forEach(column => {
|
|
if (!!column.label && column.type === "default") {
|
|
columns[0].push(column.label);
|
|
keys.push(column.property);
|
|
let formater = options.columnFormatter.find(f => !!f[column.property] && typeof f[column.property] == 'function');
|
|
!!formater && (formaters[column.property] = formater[column.property]);
|
|
}
|
|
});
|
|
rows.forEach(o => {
|
|
let list = [];
|
|
keys.forEach(k => {
|
|
let formater = formaters[k];
|
|
if (!!formater) {
|
|
list.push(formater(o[k]));
|
|
} else {
|
|
list.push(o[k]);
|
|
}
|
|
});
|
|
columns.push(list);
|
|
});
|
|
const ws = XLSX.utils.aoa_to_sheet(columns);
|
|
if (!!options.mergeSetting && !!options.mergeSetting.refs && options.mergeSetting.refs.length > 0) {
|
|
let merges = getMergeSetting(rows, options.mergeSetting, keys);
|
|
ws["!merges"] = merges;
|
|
setStyle(ws, merges);
|
|
}
|
|
// console.log(ws);
|
|
const wb = XLSX.utils.book_new();
|
|
XLSX.utils.book_append_sheet(wb, ws, options.fileName.replace(/\.xlsx/, ""));
|
|
XLSX.writeFile(wb, options.fileName);
|
|
});
|
|
}
|
|
|
|
export default {
|
|
exportTable: export2Excel
|
|
}
|