前端做导出excel功能,其实挺鸡肋的,如果数据量小可以接受,但是数据量大的话,数据稍微一多就玩不动了;走后台,你想怎么定制,多大数据量都能顺利导出;当然,纯属个人建议;
1.简单的方法,字符串拼接
import FileSaver from 'file-saver';
//columns导出标题
//allData是请求的数据循环拼接
let str = [];
columns.forEach((item)=>{
str.push(item.title)
});
allData.forEach((item, index) => {
let resData = [];
for (let key in item) {
resData += item[key] + ','
}
str += "\n" + resData
});
let exportContent = "\uFEFF";
let blob = new Blob([exportContent + str], {type: "text/plain;charset=utf-8"});
FileSaver.saveAs(blob, "信息.csv");
2.参考一位大佬写的,然后自己稍微 改了下自己需要的东西,大佬名字不记得了
//封装的js
import { File } from "better-xlsx";
import { saveAs } from "file-saver";
function ExportExcel(column, dataSource, fileName = "example") {
// 新建工作谱
const file = new File();
// 新建表
let sheet = file.addSheet("sheet-test");
// 获取表头行数---一般一个表格的行数只有一行,暂时没多级表格;
let depth = getDepth(column);
// 获取表头的列数---就是表格的标题有多少个
let columnNum = getColumns(column);
// 新建表头行数
let rowArr = [];
for (let k = 0; k < depth; k++) {
rowArr.push(sheet.addRow());
}
// 根据列数填充单元格
rowArr.map((ele) => {
for (let j = 0; j < columnNum; j++) {
let cell = ele.addCell();
cell.value = j;
}
});
// 初始化表头
init(column, 0, 0);
// 按顺序展平column
let columnLineArr = [];
columnLine(column);
// 根据column,将dataSource里面的数据排序,并且转化为二维数组
let dataSourceArr = [];
dataSource.map((ele) => {
let dataTemp = [];
columnLineArr.map((item) => {
dataTemp.push({
[item.dataIndex]: ele[item.dataIndex],
value: ele[item.dataIndex],
});
});
dataSourceArr.push(dataTemp);
});
// 绘画表格数据
dataSourceArr.forEach((item, index) => {
//根据数据,创建对应个数的行
let row = sheet.addRow();
row.setHeightCM(0.8);
//创建对应个数的单元格
item.map((ele) => {
let cell = row.addCell();
if (ele.hasOwnProperty("num")) {
cell.value = index + 1;
} else {
cell.value = ele.value;
}
//这里用来设置表格样式调整
cell.style.align.v = "center";
cell.style.align.h = "center";
// cell.style.align.wrapText=true;
//缩小最适应大小文字
//cell.style.align.shrinkToFit=true;
//console.log(cell.style)
});
});
//设置每列的宽度
for (let i = 0; i < 10; i++) {
// console.log(sheet.col(i));
sheet.col(i).width = 20;
}
file.saveAs("blob").then(function (content) {
saveAs(content, fileName + ".xlsx");
//saveAs(content, fileName + '.csv');
});
// 按顺序展平column
function columnLine(column) {
column.map((ele) => {
if (ele.children === undefined || ele.children.length === 0) {
columnLineArr.push(ele);
} else {
columnLine(ele.children);
}
});
}
// 初始化表头
function init(column, rowIndex, columnIndex) {
column.map((item) => {
let hCell = sheet.cell(rowIndex, columnIndex);
// 如果没有子元素, 撑满列
if (item.title === "操作") {
hCell.value = "";
return null;
} else if (item.children === undefined || item.children.length === 0) {
// 第一行加一个单元格
hCell.value = item.title;
hCell.vMerge = depth - rowIndex - 1;
hCell.style.align.h = "center";
hCell.style.align.v = "center";
columnIndex++;
// rowIndex++
} else {
let childrenNum = 0;
function getColumns(arr) {
arr.map((ele) => {
if (ele.children) {
getColumns(ele.children);
} else {
childrenNum++;
}
});
}
getColumns(item.children);
hCell.hMerge = childrenNum - 1;
hCell.value = item.title;
hCell.style.align.h = "center";
hCell.style.align.v = "center";
let rowCopy = rowIndex;
rowCopy++;
init(item.children, rowCopy, columnIndex);
// 下次单元格起点
columnIndex = columnIndex + childrenNum;
}
});
}
// 获取表头rows
function getDepth(arr) {
const eleDepths = [];
//console.log(arr)
arr.forEach((ele) => {
let depth = 0;
if (Array.isArray(ele.children)) {
depth = getDepth(ele.children);
}
eleDepths.push(depth);
});
return 1 + max(eleDepths);
}
function max(arr) {
return arr.reduce((accu, curr) => {
if (curr > accu) return curr;
return accu;
});
}
// 计算表头列数
function getColumns(arr) {
let columnNum = 0;
arr.map((ele) => {
if (ele.children) {
getColumns(ele.children);
} else {
columnNum++;
}
});
return columnNum;
}
}
export default ExportExcel;
//引用方法
//title是标题
//dataSource是数据
ExportExcel(title, dataSource);
网友评论