wwf
昨天 34f5733bc1f126c572580fa849b9403dfcddd84b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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方法
 
};