使用 xlsx-style 和 xlsx 导出表头带有样式的表格

648 阅读1分钟

安装依赖

npm install xlsx --save
npm install xlsx-style --save
npm install file-saver --save

安装 xlsx-style 后不出意外程序会报错 Can‘t resolve './cptable' in ‘xxx\node_modules_xlsx

解决方案

vue.config.js

// vue.config.js
module.exports = {
  // .....
  chainWebpack: config => {
    config.externals({ './cptable': 'var cptable' })
  }
}

参考版本号:

"file-saver": "^2.0.5"

"vue": "^2.6.11"

"xlsx": "^0.18.5"

"xlsx-style": "^0.8.13"

(不要问为什么,时至今日还是 vue2,问就是我只是个维护老项目的)

传入的数据格式如下:

['表头名称', '表头名称', '表头名称']

['数据', '数据', '数据']

['数据', '数据', '数据']

image.png

无样式导出版本

import { utils, writeFileXLSX } from 'xlsx'
import moment from "moment"

export function exportExecl(sheet1data, sheet2data, sheet3data) {
  const sheet1 = utils.json_to_sheet(sheet1data);
  const sheet2 = utils.json_to_sheet(sheet2data);
  const wb = utils.book_new();
  utils.book_append_sheet(wb, sheet1, "总览");
  utils.book_append_sheet(wb, sheet2, "详情");
  writeFileXLSX(wb, `数据导出_${moment().format('YYYYMMDD')}.xlsx`);
}

携带样式

1、存储工作表中的列标签

// 定义大写字母 "A" 的字符码,用于生成大写字母表
const CHARCODE_A_UC = 65

// 创建一个包含大写字母的数组,从 "A" 到 "Z"
const uppercaseAlphabet = new Array(26)
  .fill(null)
  .map((v, i) => String.fromCharCode(CHARCODE_A_UC + i))

// 包含 Excel 工作表标签的数组,从 "A1" 到 "Z1"
const sheetList = uppercaseAlphabet.map((i) => `${i}1`)
const list_1 = sheetList.slice(0, sheet1data[0].length)

2、遍历数据

for (let i in ws) {
  if (list_1.includes(i)) {
    ws[i].s = {
      alignment: {
        horizontal: 'center',
        vertical: 'center',
      },
      font: {
        bold: true,
      },
      fill: {
        fgColor: {
          rgb: '93a9d7'
        }
      }
    };
  }
}

3、表格的每个数据居中

const centerSheetDataFunc = (sheetData) => {
  let letterList = uppercaseAlphabet.slice(0, sheetData[0].length)
  let tableCount = sheetData.length
  let result = []

  const numFunc = (str, len) => {
    return new Array(len).fill(null).map((v, i) => `${str}${i + 1}`)
  }

  for (let i = 0; i < letterList.length; i++) {
    result.push(numFunc(letterList[i], tableCount))
  }

  return result.flat(Infinity)
}

// Excel 工作表中数据单元格的坐标
const centerSheet1Data = centerSheetDataFunc(sheet1data)
for (let i in ws) {
  if (centerSheet1Data.includes(i)) {
    ws[i].s = {
      alignment: {
        horizontal: 'center',
        vertical: 'center',
      }
    };
  }
  //....
}

4、数据导出

let wbout = XLSXS.write(wb, {
  bookType: "xlsx",
  bookSST: false,
  type: "binary"
});
FileSaver.saveAs(
  new Blob([s2ab(wbout)], {
    type: "application/octet-stream"
  }),
  `数据导出_${moment().format('YYYYMMDD')}.xlsx`
);

完整代码