|
@ -10,10 +10,43 @@ import FileSaver from 'file-saver'; |
|
|
// export default exportExcel;
|
|
|
// export default exportExcel;
|
|
|
|
|
|
|
|
|
// 导出excel文件
|
|
|
// 导出excel文件
|
|
|
export function exportExcel (tableColumns,data,fillName,isMerge,start,end) { |
|
|
/** |
|
|
|
|
|
* |
|
|
|
|
|
* @param {*} tableColumns 表头 |
|
|
|
|
|
* @param {*} data 数据 |
|
|
|
|
|
* @param {*} fillName 文件名 |
|
|
|
|
|
* @param {*} isMerge 是否合并单元格 |
|
|
|
|
|
* @param {*} firstKey 第一个字段的key,用来判断序号列是否合并 |
|
|
|
|
|
* @param {*} start 合并单元格开始列 |
|
|
|
|
|
* @param {*} end 合并单元格结束列 |
|
|
|
|
|
* @returns |
|
|
|
|
|
*/ |
|
|
|
|
|
export function exportExcel (tableColumns,data,fillName,isMerge = false, firstKey = '',start = 0, end = 0) { |
|
|
|
|
|
debugger |
|
|
if (!data || data.length == 0) { |
|
|
if (!data || data.length == 0) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
if (isMerge) { |
|
|
|
|
|
// 需要合并序号
|
|
|
|
|
|
for (let i = 0; i < data.length; i++) { |
|
|
|
|
|
// 自定义单元格内容,这里返回序号
|
|
|
|
|
|
if (i == 0) { |
|
|
|
|
|
data[i].index = 1; |
|
|
|
|
|
// return 1;
|
|
|
|
|
|
} else if (data[i - 1][firstKey] == data[i][firstKey]) { |
|
|
|
|
|
data[i].index = data[i - 1].index; |
|
|
|
|
|
// return data.value[index].index;
|
|
|
|
|
|
} else { |
|
|
|
|
|
data[i].index = data[i - 1].index + 1; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
// 不需要合并序号
|
|
|
|
|
|
for (let i = 0; i < data.length; i++) { |
|
|
|
|
|
data[i].index = i + 1; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 创建工作簿
|
|
|
// 创建工作簿
|
|
|
const workbook = new ExcelJS.Workbook(); |
|
|
const workbook = new ExcelJS.Workbook(); |
|
|
// 添加工作表,名为sheet1
|
|
|
// 添加工作表,名为sheet1
|
|
@ -33,27 +66,22 @@ export function exportExcel (tableColumns,data,fillName,isMerge,start,end) { |
|
|
columns.push({ |
|
|
columns.push({ |
|
|
header: tableColumns[i].title, |
|
|
header: tableColumns[i].title, |
|
|
key: tableColumns[i].dataIndex, |
|
|
key: tableColumns[i].dataIndex, |
|
|
width: tableColumns[i].width / 5, |
|
|
width: tableColumns[i].width ? tableColumns[i].width / 5 : 20, |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
//传入的数据
|
|
|
//传入的数据
|
|
|
const list = data; |
|
|
const list = data; |
|
|
|
|
|
|
|
|
|
|
|
//格式化数据
|
|
|
const datas = formatJson(filterVal, list); |
|
|
const datas = formatJson(filterVal, list); |
|
|
|
|
|
|
|
|
// // 导出数据列表
|
|
|
|
|
|
// const data = [
|
|
|
|
|
|
// { 姓名: '张三', 年龄: 18, 身高: 175, 体重: 74 },
|
|
|
|
|
|
// { 姓名: '李四', 年龄: 22, 身高: 177, 体重: 84 },
|
|
|
|
|
|
// { 姓名: '王五', 年龄: 53, 身高: 155, 体重: 64 },
|
|
|
|
|
|
// ];
|
|
|
|
|
|
// 获取表头所有键
|
|
|
// 获取表头所有键
|
|
|
// const headers = Object.keys(data[0]);
|
|
|
// const headers = Object.keys(data[0]);
|
|
|
|
|
|
|
|
|
|
|
|
// 获取表头
|
|
|
sheet1.columns = columns; |
|
|
sheet1.columns = columns; |
|
|
// // 将标题写入第一行
|
|
|
|
|
|
// sheet1.addRow(tHeader);
|
|
|
|
|
|
// 将数据写入工作表
|
|
|
// 将数据写入工作表
|
|
|
datas.forEach((row) => { |
|
|
datas.forEach((row) => { |
|
|
// const values = Object.values(row);
|
|
|
// const values = Object.values(row);
|
|
@ -62,80 +90,30 @@ export function exportExcel (tableColumns,data,fillName,isMerge,start,end) { |
|
|
|
|
|
|
|
|
// 判断是否合并单元格
|
|
|
// 判断是否合并单元格
|
|
|
if (isMerge) { |
|
|
if (isMerge) { |
|
|
debugger |
|
|
// 遍历列,从 start 列到 end 列
|
|
|
// 遍历列,从第一列到 end 列
|
|
|
|
|
|
for (let col = start; col <= end; col++) { |
|
|
for (let col = start; col <= end; col++) { |
|
|
// let mergeStartRow = 2; // 每次新列开始时,重置起始行
|
|
|
|
|
|
for (let row = 3; row <= datas.length + 1; row++) { |
|
|
for (let row = 3; row <= datas.length + 1; row++) { |
|
|
const currentCellValue = sheet1.getCell(row, col).value; |
|
|
const currentCellValue = sheet1.getCell(row, col).value; |
|
|
const previousCellValue = sheet1.getCell(row - 1, col).value; |
|
|
const previousCellValue = sheet1.getCell(row - 1, col).value; |
|
|
|
|
|
|
|
|
let currentCellValue_1 = '' |
|
|
// 从第二列开始就要看前一列是否已经合并
|
|
|
let previousCellValue_1 = '' |
|
|
let isMerged = true |
|
|
if (col > 1) { |
|
|
if (col > 1) { |
|
|
currentCellValue_1 = sheet1.getCell(row, col-1).value; |
|
|
isMerged = ifMerged(sheet1,row - 1, col-1,row, col-1) |
|
|
previousCellValue_1 = sheet1.getCell(row - 1, col-1).value; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (currentCellValue === previousCellValue && currentCellValue_1 === previousCellValue_1) { |
|
|
if (currentCellValue === previousCellValue && isMerged) { |
|
|
// 当前列有变化,检查是否需要合并前面的单元格
|
|
|
// 检查是上边需要合并的单元格是否已经合并
|
|
|
// if (mergeStartRow < row - 1) {
|
|
|
const mergeInfo = getMergeInfo(sheet1, row - 1, col) |
|
|
// 只有在前面的行有超过1个时才合并
|
|
|
if ( mergeInfo.isMerged ) { |
|
|
sheet1.mergeCells(row, col, row - 1, col); |
|
|
sheet1.unMergeCells( mergeInfo.startRow, col, row - 1, col); |
|
|
// }
|
|
|
sheet1.mergeCells(mergeInfo.startRow, col, row, col); |
|
|
// 更新起始行
|
|
|
} else { |
|
|
// mergeStartRow = row;
|
|
|
sheet1.mergeCells(row, col, row - 1, col); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// // 如果是最后一行,检查是否需要合并
|
|
|
|
|
|
// if (row === datas.length + 1 && mergeStartRow < row) {
|
|
|
|
|
|
// sheet1.mergeCells(mergeStartRow, col, row, col);
|
|
|
|
|
|
// }
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
// 从第一列开始逐列检查,前提是前面的列已合并
|
|
|
|
|
|
// for (let col = start; col <= end; col++) {
|
|
|
|
|
|
// let startRow = 2; // 从数据开始的第二行开始检查
|
|
|
|
|
|
// let endRow = 2;
|
|
|
|
|
|
|
|
|
|
|
|
// while (endRow <= sheet1.rowCount) {
|
|
|
|
|
|
// let currentValue = sheet1.getCell(endRow, col).value;
|
|
|
|
|
|
// let prevValue = sheet1.getCell(endRow - 1, col).value;
|
|
|
|
|
|
|
|
|
|
|
|
// // 如果当前值等于前一个值,且前面的列是合并的,则继续合并
|
|
|
|
|
|
// if (currentValue === prevValue) {
|
|
|
|
|
|
// let mergeAllowed = true;
|
|
|
|
|
|
// for (let prevCol = 1; prevCol < col; prevCol++) {
|
|
|
|
|
|
// let range = sheet1.getCell(endRow - 1, prevCol).master;
|
|
|
|
|
|
// if (range && range.row !== startRow) {
|
|
|
|
|
|
// mergeAllowed = false;
|
|
|
|
|
|
// break;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// if (mergeAllowed) {
|
|
|
|
|
|
// endRow++;
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
// // 不允许合并,直接移动起始行到当前行
|
|
|
|
|
|
// startRow = endRow;
|
|
|
|
|
|
// endRow++;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
// // 当前值不等于前一个值或合并不允许,进行合并操作
|
|
|
|
|
|
// if (startRow < endRow - 1) {
|
|
|
|
|
|
// sheet1.mergeCells(startRow, col, endRow - 1, col);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// startRow = endRow;
|
|
|
|
|
|
// endRow++;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// // 处理最后一段相同的单元格
|
|
|
|
|
|
// if (startRow < endRow - 1) {
|
|
|
|
|
|
// sheet1.mergeCells(startRow, col, endRow - 1, col);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -208,3 +186,43 @@ function formatJson (filterVal, jsonData) { |
|
|
return jsonData.map((v) => filterVal.map((j) => v[j])); |
|
|
return jsonData.map((v) => filterVal.map((j) => v[j])); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 获取给定行和列的单元格是否为合并单元格,并返回合并起始行 |
|
|
|
|
|
* @param {Worksheet} worksheet - ExcelJS 工作表对象 |
|
|
|
|
|
* @param {number} row - 单元格的行号 (从 1 开始) |
|
|
|
|
|
* @param {number} col - 单元格的列号 (从 1 开始) |
|
|
|
|
|
* @returns {Object} - 返回一个对象,包含 isMerged 和 startRow 属性 |
|
|
|
|
|
*/ |
|
|
|
|
|
function getMergeInfo(worksheet, row, col) { |
|
|
|
|
|
// 遍历所有的合并范围
|
|
|
|
|
|
for (const mergeRange in worksheet._merges) { |
|
|
|
|
|
if (worksheet._merges.hasOwnProperty(mergeRange)) { |
|
|
|
|
|
const { top, left, bottom, right } = worksheet._merges[mergeRange]; |
|
|
|
|
|
|
|
|
|
|
|
// 检查行列是否在当前合并范围内
|
|
|
|
|
|
if (row >= top && row <= bottom && col >= left && col <= right) { |
|
|
|
|
|
return { isMerged: true, startRow: top }; // 找到合并范围,返回合并信息
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return { isMerged: false, startRow: null }; // 单元格不在任何合并范围内
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 函数:检查两个单元格是否属于同一个合并区域
|
|
|
|
|
|
function ifMerged(worksheet, row1, col1, row2, col2) { |
|
|
|
|
|
const merges = worksheet._merges; // 获取所有的合并区域
|
|
|
|
|
|
for (let mergeAddress in merges) { |
|
|
|
|
|
const mergeRange = merges[mergeAddress]; |
|
|
|
|
|
const { top, left, bottom, right } = mergeRange; |
|
|
|
|
|
|
|
|
|
|
|
const isCell1InRange = (row1 >= top && row1 <= bottom && col1 >= left && col1 <= right); |
|
|
|
|
|
const isCell2InRange = (row2 >= top && row2 <= bottom && col2 >= left && col2 <= right); |
|
|
|
|
|
|
|
|
|
|
|
if (isCell1InRange && isCell2InRange) { |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|