import * as XLSX from 'xlsx-js-style'; // 另一种常见的导入方式
|
export const exportToExcel = (headers, list, fileName) => {
|
// 定义自定义表头和数据映射
|
const headerData = headers.filter(item => !item.noExport).map(item => item.label);
|
const bodyData = list.map(item => {
|
let itemList = []
|
headers.forEach(header => {
|
if (header.noExport) return
|
itemList.push(item[header.value])
|
})
|
return itemList
|
});
|
|
// 将表头和数据体组合成一个二维数组
|
const allData = [headerData, ...bodyData];
|
|
// 使用 aoa_to_sheet 方法,它接受二维数组
|
const ws = XLSX.utils.aoa_to_sheet(allData);
|
|
const headerStyle = {
|
font: { bold: true, sz: 12 },
|
alignment: { horizontal: 'center', vertical: 'center' },
|
}
|
|
// 数据单元格样式:居中
|
const cellStyle = {
|
alignment: { horizontal: 'center', vertical: 'center' }
|
}
|
|
// 3. 计算并设置列宽(核心:最大宽度限制下的自适应)
|
const maxWidth = 30 // 设置最大列宽(单位:字符数)
|
const colWidths = []
|
|
// 遍历每一列计算最大宽度
|
for (let col = 0; col < allData[0].length; col++) {
|
let maxLen = 10 // 默认最小宽度
|
for (let row = 0; row < allData.length; row++) {
|
const value = allData[row][col]
|
if (value != null) {
|
// 计算单元格内容长度(中文按2个字符算)
|
let len = 0
|
const str = value.toString()
|
for (let i = 0; i < str.length; i++) {
|
const charCode = str.charCodeAt(i)
|
len += (charCode > 255) ? 2 : 1 // 中文字符算2个宽度
|
}
|
if (len > maxLen) maxLen = len
|
}
|
}
|
// 应用最大宽度限制
|
colWidths.push({ wch: Math.min(maxLen + 2, maxWidth) })
|
}
|
ws['!cols'] = colWidths
|
|
// 4. 应用样式到所有单元格
|
const range = XLSX.utils.decode_range(ws['!ref'])
|
for (let R = range.s.r; R <= range.e.r; R++) {
|
for (let C = range.s.c; C <= range.e.c; C++) {
|
const cellAddress = { c: C, r: R }
|
const cellRef = XLSX.utils.encode_cell(cellAddress)
|
|
if (!ws[cellRef]) ws[cellRef] = {} // 确保单元格存在
|
if (!ws[cellRef].s) ws[cellRef].s = {} // 确保样式对象存在
|
|
// 第一行(表头)应用headerStyle,其他行应用cellStyle
|
ws[cellRef].s = R === 0 ?
|
{ ...ws[cellRef].s, ...headerStyle } :
|
{ ...ws[cellRef].s, ...cellStyle }
|
}
|
}
|
|
// ... 后续创建工作簿和导出的步骤同上
|
|
const workbook = XLSX.utils.book_new();
|
XLSX.utils.book_append_sheet(workbook, ws, 'Sheet1');
|
|
// 3. 生成Excel文件并保存
|
XLSX.writeFile(workbook, `${fileName || '导出数据'}.xlsx`); // 使用xlsx库的writeFile方法
|
|
};
|