xlsx库导出表格(单元格合并+边框)

91 阅读1分钟

直接看效果图,代码注释很详细

网页: 微信截图_20240514162729.png

excel: 微信截图_20240514162744.png

// 安装这个,网上很多回答乱七八糟的,只要装这个,xlsx是不支持改式样的
import XLSX from 'xlsx-js-style'
/**
 * sheetJS到出excel
 * @param ref 表格dom ,或是该dom 的id
 * @param tableName 导出的文件名
 */
const exportTableToSheet = (ref, tableName) => {
  const ws = XLSX.utils.table_to_sheet(ref)
  const wb = XLSX.utils.book_new()
  // 列宽,顺序设置
  ws['!cols'] = [{ wpx: 50 }, { wpx: 100 }]
  let allList = Object.keys(ws)
  // 获取所有列
  let cellList = allList.filter((f) => f.indexOf('!'))
  let allCellAddress = getAllRang(ws['!ref'])
  allCellAddress.map((m) => {
    // 合并的过后的单元格是没用边框的,所以要找到哪些单元格合并没了
    if (!allList.includes(m)) {
      // 因为空值没有border
      ws[m] = {
        t: 's',
        v: '',
        s: { border: BORDER }
      }
    } else {
      // 把空值设置成's'类型
      if (ws[m].v === '') {
        ws[m].t = 's'
        ws[m].s = { border: BORDER }
      }
    }
  })
  cellList.map((m) => {
    if (!ws[m].s) ws[m].s = {}
    // 所有cell 加上边框
    ws[m].s.border = BORDER
    // A列B列 水平垂直居中
    if (m.includes('A') || m.includes('B')) {
      ws[m].s.alignment = {
        horizontal: 'center',
        vertical: 'center'
      }
    }
    // 数据错误标红
    if (ws[m].v.length > 1 && ws[m].v.includes('√')) {
      ws[m].s.font = {
        color: { rgb: 'FF0000' }
      }
    }
  })

  // 大标题单独设置
  ws['A1'].s.font = { bold: true, name: '微软雅黑', sz: 16 }
  XLSX.utils.book_append_sheet(wb, ws, '考勤表')
  XLSX.writeFile(wb, tableName + '.xlsx')
}

// 工具函数,获取excel 的所有单元格
const getAllRang = (rangeStr) => {
  // 获取工作表的范围
  const range = XLSX.utils.decode_range(rangeStr)

  // 初始化一个数组来存储所有单元格地址
  const cellAddresses: any = []

  // 遍历范围内的所有行和列,生成单元格地址
  for (let row = range.s.r; row <= range.e.r; row++) {
    for (let col = range.s.c; col <= range.e.c; col++) {
      // row 值,和 col 值 转成excel 的cell
      const cellAddress = XLSX.utils.encode_cell({ r: row, c: col })
      cellAddresses.push(cellAddress)
    }
  }
  return cellAddresses
}