实现excel文件转为luckysheet格式

707 阅读2分钟

前言

对于luckysheet导出功能,在另外一篇文章里边,有兴趣的小伙伴可以移步:luckysheet文件导出

针对excel文件读取转换,官方有对应的插件,但是在开发的过程发现,对于批注的转换,官方并没有实现。

解决方案是配合 xlsx.js 实现批注读取设置。

准备工作

  1. 安装 xlsx
npm i xlsx
  1. 安装 luckyexcel
npm i luckyexcel

实现

createLuckySheet.js


import XLSX from 'xlsx';
import LuckyExcel from 'luckyexcel';
import { getColumnNameFromId } from './utils';

export default file => {
  let excelSheet = [];

  // 读取文件
  loadExcel(file);

  // 读取file文件,
  function loadExcel(file) {
    // 创建 FileReader 示例
    let showPreview = new FileReader();
    // 读取文件
    showPreview.readAsBinaryString(file);
    // 文件读取成功时的回调函数
    showPreview.onload = e => {
      // 获取传递的表格
      let data = e.target.result;
      // 以二进制流方式读取到整份的excel 表格对象
      getExcelWorkSheet(data);
      // 将file文件转为luckysheet格式
      createLuckSheet(file);
    };
  }

  // 读取excel 表格对象
  function getExcelWorkSheet(data) {
    if (!data) {
      return;
    }
    const workbook = XLSX.read(data, {
      type: 'binary',
      cellNF: true,
      raw: true
    });
    excelSheet = workbook.Sheets;
  }

  // 将file文件转换为luckysheet格式数据
  function createLuckSheet(file) {
    LuckyExcel.transformExcelToLucky(
      file,
      function (exportJson, luckysheetfile) {
        if (exportJson.sheets == null || exportJson.sheets.length == 0) {
          console.error(
            'Failed to read the content of the excel file, currently does not support xls files!'
          );
          return;
        }
        initLuckySheet(exportJson);
      }
    );
  }

  // 对luckysheet数据做处理
  function transLuckysheetData() {
    if (exportJson && exportJson.sheets) {
      exportJson.sheets.forEach(sheet => {
        const { name = '', celldata = [] } = sheet;
        // 根据sheets页名称,获取当前sheet页的解析数据集
        const sheetCellData = excelSheet[name];
        celldata.forEach(ele => {
          const { r, c } = ele;
          // 获取对应单元格的数据
          const coordinate = getColumnNameFromId([c, r]);
          // 判断该单元格是否有批注
          if (sheetCellData[coordinate] && sheetCellData[coordinate].c) {
            const c = sheetCellData[coordinate].c;
            // 给单元格添加批注
            if (ele.v) {
              ele.v.ps = {
                value: c?.[0]?.t || ''
              };
            }
          }
        });
      });
    }
  }

  // 初始化luckysheet
  function initLuckySheet(exportJson) {
    // 数据做额外处理
    transLuckysheetData(exportJson);
    // 初始化luckysheet 表格
    window.luckysheet.create({
      container: 'luckysheet', // 渲染的容器id
      lang: 'zh', // 渲染语言
      data: exportJson?.sheets, // 数据
      title: exportJson?.info?.name, // 标题
      userInfo: exportJson?.info?.name?.creator // 用户列表
    });
  }
};

utils.js

/**
 * @description: 只获取列坐标
 * @param {number} i 坐标
 * @return {String}
 * 示例
console.log(getColumnName(3)) => D
console.log(getColumnName(5)) => F
console.log(getColumnName(9)) => J
 */
export function getColumnName(i) {
  var letter = ''
  if (i > 701) {
    letter += String.fromCharCode(64 + parseInt(i / 676))
    letter += String.fromCharCode(64 + parseInt((i % 676) / 26))
  } else if (i > 25) {
    letter += String.fromCharCode(64 + parseInt(i / 26))
  }
  letter += String.fromCharCode(65 + (i % 26))
  // console.log(letter)
  return letter
}

/**
 * @description: 坐标转数组
 * @param {Array} cellId 坐标轴
 * @return {String}
 */
//console.log(getColumnNameFromId([8,9])) =>I10
//console.log(getColumnNameFromId([2,5])) =>C6
//console.log(getColumnNameFromId([6,7])) =>G8
export function getColumnNameFromId(cellId) {
  if (!Array.isArray(cellId)) {
    cellId = cellId.split('-')
  }
  return getColumnName(parseInt(cellId[0])) + (parseInt(cellId[1]) + 1)
}