
import Excel from 'exceljs';

async function exportSheetExcel(luckysheet, name = 'file') { // 参数为luckysheet.getluckysheetfile()获取的对象
  // 1.创建工作簿，可以为工作簿添加属性
  const workbook = new Excel.Workbook();
  // 2.创建表格，第二个参数可以配置创建什么样的工作表
  const promiseArray = [luckysheet[0]].map(async (table) => {
    if (table.data.length === 0) { return true; }
    const worksheet = workbook.addWorksheet(name);
    // 3.设置单元格合并,设置单元格边框,设置单元格样式,设置值
    setStyleAndValue(table.data, worksheet);
    setMerge(table.config.merge, worksheet);
    setBorder(table, worksheet);
    setHyperlink(table.hyperlink, worksheet, table.data);
    await setImages(table, worksheet, workbook);
    return true;
  });
  await Promise.all(promiseArray);
  // 4.写入 buffer
  const buffer = await workbook.xlsx.writeBuffer();
  // 5.保存为文件
  saveFile(buffer, name);
}

const saveFile = function(buf, name) {
  let blob = new Blob([buf], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' });
  const downloadElement = document.createElement('a');
  let href = window.URL.createObjectURL(blob);
  downloadElement.href = href;
  downloadElement.download = `${name}.xlsx`; // 文件名字
  document.body.appendChild(downloadElement);
  downloadElement.click();
  document.body.removeChild(downloadElement); // 下载完成移除元素
  window.URL.revokeObjectURL(href); // 释放掉blob对象
};

function setHyperlink(hyperlink, worksheet, data) {
  if (!hyperlink) {
    return;
  }
  for (const key in hyperlink) {
    // key 的格式通常是 "行号_列号"，例如 "0_0" 表示 A1 单元格
    const [rowIndex, colIndex] = key.split('_').map(Number);
    const cell = worksheet.getCell(rowIndex + 1, colIndex + 1); // ExcelJS 行列索引从1开始
    const linkInfo = hyperlink[key];

    // 设置单元格值为超链接对象
    if (linkInfo.linkType === 'external') {
      // 外部链接
      cell.value = {
        text: cell.value || linkInfo.linkTooltip || '链接', // 显示的文本
        hyperlink: linkInfo.linkAddress, // 链接地址
        tooltip: linkInfo.linkTooltip // 鼠标悬停提示（可选）
      };
    } else {
      // 内部链接（指向本工作簿的其他位置）
      // 注意：ExcelJS 可能需要特定的内部链接格式，如 `'Sheet2!A1'`
      cell.value = {
        text: cell.value || '内部链接',
        hyperlink: `'${linkInfo.linkAddress}'` // 例如处理为 "'SheetName!A1'"
      };
    }
    const celldata = data[rowIndex][colIndex];
    let color = !celldata.fc ? '' : `${celldata.fc}`.indexOf('rgb') > -1 ? rgb2hex(celldata.fc) : celldata.fc;
    // （可选）为超链接设置特定字体样式，如蓝色和下划线
    console.log('color', color, celldata);
    cell.font = {
      ...cell.font, // 保留原有字体属性
      color: { argb: color.replace('#', '') || 'FF000000' }, // 蓝色
      underline: true
    };
  }
}

const setMerge = function(luckyMerge = {}, worksheet) {
  const mergearr = Object.values(luckyMerge);
  mergearr.forEach((elem) => { // elem格式：{r: 0, c: 0, rs: 1, cs: 2}
    // 按开始行，开始列，结束行，结束列合并（相当于 K10:M12）
    worksheet.mergeCells(elem.r + 1, elem.c + 1, elem.r + elem.rs, elem.c + elem.cs);
  });
};
let getImagePosition = (num, arr) => {
  let index = 0;
  let total = 0;

  for (let i = 0; i < arr.length; i++) {
    total = arr[i];
    if (num < total) {
      index = i;
      break;
    }

  }
  if (index === 0) {
    return [0, num];
  } else {
    return [index, num - arr[index - 1]];
  }
};
function getDPIWithCSS() {
  // 创建一个隐藏的div元素并设置其宽度为1英寸
  const div = document.createElement('div');
  div.style.width = '1in';
  div.style.height = '1in';
  div.style.position = 'absolute';
  div.style.left = '-100%';
  div.style.top = '-100%';
  div.style.visibility = 'hidden'; // 隐藏元素避免影响布局[6](@ref)

  // 将元素添加到文档中
  document.body.appendChild(div);

  // 获取元素的像素宽度，这直接对应于1英寸包含的像素数，即DPI[6](@ref)
  const dpi = div.offsetWidth;

  // 清理：从文档中移除该元素
  document.body.removeChild(div);

  return dpi;
}
/**
 * 将像素值转换为EMU
 * @param {number} px - 像素值
 * @returns {number} EMU值
 */
function pxToEMU(px) {
  const EMU_PER_INCH = 914400;
  return Math.round(px * EMU_PER_INCH / getDPIWithCSS());
}
const setImages = async function(table, worksheet, workbook) {
  let {
    images,
    visibledatacolumn,// 所有行的位置
    visibledatarow // 所有列的位置
  } = { ...table };
  if (typeof images != 'object') {
    return;
  }

  for (let key in images) {
    // 通过 base64  将图像添加到工作簿
    const myBase64Image = await urlToBase64HighPerformance(images[key].src);
    // 开始行 开始列 结束行 结束列
    const item = images[key];
    const imageId = workbook.addImage({
      base64: myBase64Image,
      extension: 'png'
    });
    const [nativeCol, nativeColOffPx] = getImagePosition(item.default.left, visibledatacolumn);
    const [nativeRow, nativeRowOffPx] = getImagePosition(item.default.top, visibledatarow);
    // 模式1，图片左侧与luckysheet位置一样，像素比例保持不变，但是，右侧位置可能与原图所在单元格不一致
    worksheet.addImage(imageId, {
      // tl: { col: col_st, row: row_st },
      tl: {
        nativeCol,      // 第2列（B列），从0开始索引
        nativeColOff: pxToEMU(nativeColOffPx), // 水平偏移量（EMU）
        nativeRow,      // 第3行
        nativeRowOff: pxToEMU(nativeRowOffPx)   // 垂直偏移量（EMU）
      },
      // br: { col: 3.5, row: 5.5 },
      ext: { width: item.default.width, height: item.default.height }
    });
    // 模式2,图片四个角位置没有变动，但是图片像素比例可能和原图不一样
    // const w_ed = item.default.left+item.default.width;
    // const h_ed = item.default.top+item.default.height;
    // const col_ed = getImagePosition(w_ed,visibledatacolumn);
    // const row_ed = getImagePosition(h_ed,visibledatarow);
    // worksheet.addImage(imageId, {
    //   tl: { col: col_st, row: row_st},
    //   br: { col: col_ed, row: row_ed},
    // });
  }
};

const setBorder = function(lucksheetfile, worksheet) {
  if (!lucksheetfile) { return; }
  const luckyToExcel = {
    style: {
      0: 'none',
      1: 'thin',
      2: 'hair',
      3: 'dotted',
      4: 'dashDot', // 'Dashed',
      5: 'dashDot',
      6: 'dashDotDot',
      7: 'double',
      8: 'medium',
      9: 'mediumDashed',
      10: 'mediumDashDot',
      11: 'mediumDashDotDot',
      12: 'slantDashDot',
      13: 'thick'
    }
  };
  // 获取所有的单元格边框的信息
  const borderInfoCompute = getBorderInfo(lucksheetfile);
  for (let x in borderInfoCompute) {
    let border = {};
    let info = borderInfoCompute[x];
    let row = parseInt(x.substr(0, x.indexOf('_')));
    let column = parseInt(x.substr(x.indexOf('_') + 1));
    if (info.t != undefined) {
      const tcolor = info.t.color.indexOf('rgb') > -1 ? rgb2hex(info.t.color) : info.t.color;
      border.top = { style: luckyToExcel.style[info.t.style], color: { argb: tcolor.replace('#', '') } };
    }
    if (info.r != undefined) {
      const rcolor = info.r.color.indexOf('rgb') > -1 ? rgb2hex(info.r.color) : info.r.color;
      border.right = { style: luckyToExcel.style[info.r.style], color: { argb: rcolor.replace('#', '') } };
    }
    if (info.b != undefined) {
      const bcolor = info.b.color.indexOf('rgb') > -1 ? rgb2hex(info.b.color) : info.b.color;
      border.bottom = { style: luckyToExcel.style[info.b.style], color: { argb: bcolor.replace('#', '') } };
    }
    if (info.l != undefined) {
      const lcolor = info.l.color.indexOf('rgb') > -1 ? rgb2hex(info.l.color) : info.l.color;
      border.left = { style: luckyToExcel.style[info.l.style], color: { argb: lcolor.replace('#', '') } };
    }
    worksheet.getCell(row + 1, column + 1).border = border;
  }
};

const getBorderInfo = function(luckysheetfile) {
  let borderInfoCompute = {};
  let cfg = luckysheetfile.config;
  let data = luckysheetfile.data;
  let borderInfo = cfg.borderInfo;
  // 设置需要计算边框的区域
  let dataset_row_st = 0; let dataset_row_ed = data.length; let dataset_col_st = 0; let dataset_col_ed = data[0].length;
  if (borderInfo != null && borderInfo.length > 0) {
    for (let i = 0; i < borderInfo.length; i++) {
      let rangeType = borderInfo[i].rangeType;

      if (rangeType == 'range') {
        let borderType = borderInfo[i].borderType;
        let borderColor = borderInfo[i].color;
        let borderStyle = borderInfo[i].style;

        let borderRange = borderInfo[i].range;

        for (let j = 0; j < borderRange.length; j++) {
          let bd_r1 = borderRange[j].row[0]; let bd_r2 = borderRange[j].row[1];
          let bd_c1 = borderRange[j].column[0]; let bd_c2 = borderRange[j].column[1];

          if (bd_r1 < dataset_row_st) {
            bd_r1 = dataset_row_st;
          }

          if (bd_r2 > dataset_row_ed) {
            bd_r2 = dataset_row_ed;
          }

          if (bd_c1 < dataset_col_st) {
            bd_c1 = dataset_col_st;
          }

          if (bd_c2 > dataset_col_ed) {
            bd_c2 = dataset_col_ed;
          }

          if (borderType == 'border-left') {
            for (let bd_r = bd_r1; bd_r <= bd_r2; bd_r++) {
              if (cfg.rowhidden != null && cfg.rowhidden[bd_r] != null) {
                continue;
              }

              if (borderInfoCompute[`${bd_r}_${bd_c1}`] == null) {
                borderInfoCompute[`${bd_r}_${bd_c1}`] = {};
              }

              borderInfoCompute[`${bd_r}_${bd_c1}`].l = { 'color': borderColor, 'style': borderStyle };

              let bd_c_left = bd_c1 - 1;

              if (bd_c_left >= 0 && borderInfoCompute[`${bd_r}_${bd_c_left}`]) {
                if (data[bd_r] != null && getObjType(data[bd_r][bd_c_left]) == 'object' && data[bd_r][bd_c_left].mc != null) {
                  let cell_left = data[bd_r][bd_c_left];

                  let mc = cfg.merge[`${cell_left.mc.r}_${cell_left.mc.c}`];

                  if (mc.c + mc.cs - 1 == bd_c_left) {
                    borderInfoCompute[`${bd_r}_${bd_c_left}`].r = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r}_${bd_c_left}`].r = { 'color': borderColor, 'style': borderStyle };
                }
              }

              let mc = cfg.merge || {};
              for (const key in mc) {
                let { c, r, cs, rs } = mc[key];
                if (bd_c1 <= c + cs - 1 && bd_c1 > c && bd_r >= r && bd_r <= r + rs - 1) {
                  borderInfoCompute[`${bd_r}_${bd_c1}`].l = null;
                }
              }
            }
          }
          else if (borderType == 'border-right') {
            for (let bd_r = bd_r1; bd_r <= bd_r2; bd_r++) {
              if (cfg.rowhidden != null && cfg.rowhidden[bd_r] != null) {
                continue;
              }

              if (borderInfoCompute[`${bd_r}_${bd_c2}`] == null) {
                borderInfoCompute[`${bd_r}_${bd_c2}`] = {};
              }

              borderInfoCompute[`${bd_r}_${bd_c2}`].r = { 'color': borderColor, 'style': borderStyle };

              let bd_c_right = bd_c2 + 1;

              if (bd_c_right < data[0].length && borderInfoCompute[`${bd_r}_${bd_c_right}`]) {
                if (data[bd_r] != null && getObjType(data[bd_r][bd_c_right]) == 'object' && data[bd_r][bd_c_right].mc != null) {
                  let cell_right = data[bd_r][bd_c_right];

                  let mc = cfg.merge[`${cell_right.mc.r}_${cell_right.mc.c}`];

                  if (mc.c == bd_c_right) {
                    borderInfoCompute[`${bd_r}_${bd_c_right}`].l = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r}_${bd_c_right}`].l = { 'color': borderColor, 'style': borderStyle };
                }
              }
              let mc = cfg.merge || {};
              for (const key in mc) {
                let { c, r, cs, rs } = mc[key];
                if (bd_c2 < c + cs - 1 && bd_c2 >= c && bd_r >= r && bd_r <= r + rs - 1) {
                  borderInfoCompute[`${bd_r}_${bd_c2}`].r = null;
                }
              }
            }
          }
          else if (borderType == 'border-top') {
            if (cfg.rowhidden != null && cfg.rowhidden[bd_r1] != null) {
              continue;
            }

            for (let bd_c = bd_c1; bd_c <= bd_c2; bd_c++) {
              if (borderInfoCompute[`${bd_r1}_${bd_c}`] == null) {
                borderInfoCompute[`${bd_r1}_${bd_c}`] = {};
              }

              borderInfoCompute[`${bd_r1}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };

              let bd_r_top = bd_r1 - 1;

              if (bd_r_top >= 0 && borderInfoCompute[`${bd_r_top}_${bd_c}`]) {
                if (data[bd_r_top] != null && getObjType(data[bd_r_top][bd_c]) == 'object' && data[bd_r_top][bd_c].mc != null) {
                  let cell_top = data[bd_r_top][bd_c];

                  let mc = cfg.merge[`${cell_top.mc.r}_${cell_top.mc.c}`];

                  if (mc.r + mc.rs - 1 == bd_r_top) {
                    borderInfoCompute[`${bd_r_top}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r_top}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                }
              }

              let mc = cfg.merge || {};
              for (const key in mc) {
                let { c, r, cs, rs } = mc[key];
                if (bd_r1 <= r + rs - 1 && bd_r1 > r && bd_c >= c && bd_c <= c + cs - 1) {
                  borderInfoCompute[`${bd_r1}_${bd_c}`].t = null;
                }
              }
            }
          }
          else if (borderType == 'border-bottom') {
            if (cfg.rowhidden != null && cfg.rowhidden[bd_r2] != null) {
              continue;
            }

            for (let bd_c = bd_c1; bd_c <= bd_c2; bd_c++) {
              if (borderInfoCompute[`${bd_r2}_${bd_c}`] == null) {
                borderInfoCompute[`${bd_r2}_${bd_c}`] = {};
              }

              borderInfoCompute[`${bd_r2}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };

              let bd_r_bottom = bd_r2 + 1;

              if (bd_r_bottom < data.length && borderInfoCompute[`${bd_r_bottom}_${bd_c}`]) {
                if (data[bd_r_bottom] != null && getObjType(data[bd_r_bottom][bd_c]) == 'object' && data[bd_r_bottom][bd_c].mc != null) {
                  let cell_bottom = data[bd_r_bottom][bd_c];

                  let mc = cfg.merge[`${cell_bottom.mc.r}_${cell_bottom.mc.c}`];

                  if (mc.r == bd_r_bottom) {
                    borderInfoCompute[`${bd_r_bottom}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r_bottom}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                }
              }

              let mc = cfg.merge || {};
              for (const key in mc) {
                let { c, r, cs, rs } = mc[key];
                if (bd_r2 < r + rs - 1 && bd_r2 >= r && bd_c >= c && bd_c <= c + cs - 1) {
                  borderInfoCompute[`${bd_r2}_${bd_c}`].b = null;
                }
              }
            }
          }
          else if (borderType == 'border-all') {
            for (let bd_r = bd_r1; bd_r <= bd_r2; bd_r++) {
              if (cfg.rowhidden != null && cfg.rowhidden[bd_r] != null) {
                continue;
              }

              for (let bd_c = bd_c1; bd_c <= bd_c2; bd_c++) {
                if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {
                  let cell = data[bd_r][bd_c];

                  let mc = cfg.merge[`${cell.mc.r}_${cell.mc.c}`];
                  if (mc == undefined || mc == null) {
                    continue;
                  }
                  if (mc.r == bd_r) {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                  }

                  if (mc.r + mc.rs - 1 == bd_r) {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                  }

                  if (mc.c == bd_c) {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                  }

                  if (mc.c + mc.cs - 1 == bd_c) {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else {
                  if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                    borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                  }

                  borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                  borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                  borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                  borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                }

                if (bd_r == bd_r1) {
                  let bd_r_top = bd_r1 - 1;

                  if (bd_r_top >= 0 && borderInfoCompute[`${bd_r_top}_${bd_c}`]) {
                    if (data[bd_r_top] != null && getObjType(data[bd_r_top][bd_c]) == 'object' && data[bd_r_top][bd_c].mc != null) {
                      let cell_top = data[bd_r_top][bd_c];

                      let mc = cfg.merge[`${cell_top.mc.r}_${cell_top.mc.c}`];

                      if (mc.r + mc.rs - 1 == bd_r_top) {
                        borderInfoCompute[`${bd_r_top}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                      }
                    }
                    else {
                      borderInfoCompute[`${bd_r_top}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                }

                if (bd_r == bd_r2) {
                  let bd_r_bottom = bd_r2 + 1;

                  if (bd_r_bottom < data.length && borderInfoCompute[`${bd_r_bottom}_${bd_c}`]) {
                    if (data[bd_r_bottom] != null && getObjType(data[bd_r_bottom][bd_c]) == 'object' && data[bd_r_bottom][bd_c].mc != null) {
                      let cell_bottom = data[bd_r_bottom][bd_c];

                      let mc = cfg.merge[`${cell_bottom.mc.r}_${cell_bottom.mc.c}`];

                      if (mc.r == bd_r_bottom) {
                        borderInfoCompute[`${bd_r_bottom}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                      }
                    }
                    else {
                      borderInfoCompute[`${bd_r_bottom}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                }

                if (bd_c == bd_c1) {
                  let bd_c_left = bd_c1 - 1;

                  if (bd_c_left >= 0 && borderInfoCompute[`${bd_r}_${bd_c_left}`]) {
                    if (data[bd_r] != null && getObjType(data[bd_r][bd_c_left]) == 'object' && data[bd_r][bd_c_left].mc != null) {
                      let cell_left = data[bd_r][bd_c_left];

                      let mc = cfg.merge[`${cell_left.mc.r}_${cell_left.mc.c}`];

                      if (mc.c + mc.cs - 1 == bd_c_left) {
                        borderInfoCompute[`${bd_r}_${bd_c_left}`].r = { 'color': borderColor, 'style': borderStyle };
                      }
                    }
                    else {
                      borderInfoCompute[`${bd_r}_${bd_c_left}`].r = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                }

                if (bd_c == bd_c2) {
                  let bd_c_right = bd_c2 + 1;

                  if (bd_c_right < data[0].length && borderInfoCompute[`${bd_r}_${bd_c_right}`]) {
                    if (data[bd_r] != null && getObjType(data[bd_r][bd_c_right]) == 'object' && data[bd_r][bd_c_right].mc != null) {
                      let cell_right = data[bd_r][bd_c_right];

                      let mc = cfg.merge[`${cell_right.mc.r}_${cell_right.mc.c}`];

                      if (mc.c == bd_c_right) {
                        borderInfoCompute[`${bd_r}_${bd_c_right}`].l = { 'color': borderColor, 'style': borderStyle };
                      }
                    }
                    else {
                      borderInfoCompute[`${bd_r}_${bd_c_right}`].l = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                }
              }
            }
          }
          else if (borderType == 'border-outside') {
            for (let bd_r = bd_r1; bd_r <= bd_r2; bd_r++) {
              if (cfg.rowhidden != null && cfg.rowhidden[bd_r] != null) {
                continue;
              }

              for (let bd_c = bd_c1; bd_c <= bd_c2; bd_c++) {
                if (!(bd_r == bd_r1 || bd_r == bd_r2 || bd_c == bd_c1 || bd_c == bd_c2)) {
                  continue;
                }

                if (bd_r == bd_r1) {
                  if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                    borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                  }

                  borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };

                  let bd_r_top = bd_r1 - 1;

                  if (bd_r_top >= 0 && borderInfoCompute[`${bd_r_top}_${bd_c}`]) {
                    if (data[bd_r_top] != null && getObjType(data[bd_r_top][bd_c]) == 'object' && data[bd_r_top][bd_c].mc != null) {
                      let cell_top = data[bd_r_top][bd_c];

                      let mc = cfg.merge[`${cell_top.mc.r}_${cell_top.mc.c}`];

                      if (mc.r + mc.rs - 1 == bd_r_top) {
                        borderInfoCompute[`${bd_r_top}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                      }
                    }
                    else {
                      borderInfoCompute[`${bd_r_top}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                }

                if (bd_r == bd_r2) {
                  if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                    borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                  }

                  borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };

                  let bd_r_bottom = bd_r2 + 1;

                  if (bd_r_bottom < data.length && borderInfoCompute[`${bd_r_bottom}_${bd_c}`]) {
                    if (data[bd_r_bottom] != null && getObjType(data[bd_r_bottom][bd_c]) == 'object' && data[bd_r_bottom][bd_c].mc != null) {
                      let cell_bottom = data[bd_r_bottom][bd_c];

                      let mc = cfg.merge[`${cell_bottom.mc.r}_${cell_bottom.mc.c}`];

                      if (mc.r == bd_r_bottom) {
                        borderInfoCompute[`${bd_r_bottom}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                      }
                    }
                    else {
                      borderInfoCompute[`${bd_r_bottom}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                }

                if (bd_c == bd_c1) {
                  if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                    borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                  }

                  borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };

                  let bd_c_left = bd_c1 - 1;

                  if (bd_c_left >= 0 && borderInfoCompute[`${bd_r}_${bd_c_left}`]) {
                    if (data[bd_r] != null && getObjType(data[bd_r][bd_c_left]) == 'object' && data[bd_r][bd_c_left].mc != null) {
                      let cell_left = data[bd_r][bd_c_left];

                      let mc = cfg.merge[`${cell_left.mc.r}_${cell_left.mc.c}`];

                      if (mc.c + mc.cs - 1 == bd_c_left) {
                        borderInfoCompute[`${bd_r}_${bd_c_left}`].r = { 'color': borderColor, 'style': borderStyle };
                      }
                    }
                    else {
                      borderInfoCompute[`${bd_r}_${bd_c_left}`].r = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                }

                if (bd_c == bd_c2) {
                  if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                    borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                  }

                  borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };

                  let bd_c_right = bd_c2 + 1;

                  if (bd_c_right < data[0].length && borderInfoCompute[`${bd_r}_${bd_c_right}`]) {
                    if (data[bd_r] != null && getObjType(data[bd_r][bd_c_right]) == 'object' && data[bd_r][bd_c_right].mc != null) {
                      let cell_right = data[bd_r][bd_c_right];

                      let mc = cfg.merge[`${cell_right.mc.r}_${cell_right.mc.c}`];

                      if (mc.c == bd_c_right) {
                        borderInfoCompute[`${bd_r}_${bd_c_right}`].l = { 'color': borderColor, 'style': borderStyle };
                      }
                    }
                    else {
                      borderInfoCompute[`${bd_r}_${bd_c_right}`].l = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                }
              }
            }
          }
          else if (borderType == 'border-inside') {
            for (let bd_r = bd_r1; bd_r <= bd_r2; bd_r++) {
              if (cfg.rowhidden != null && cfg.rowhidden[bd_r] != null) {
                continue;
              }

              for (let bd_c = bd_c1; bd_c <= bd_c2; bd_c++) {
                if (bd_r == bd_r1 && bd_c == bd_c1) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {

                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else if (bd_r == bd_r2 && bd_c == bd_c1) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {

                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else if (bd_r == bd_r1 && bd_c == bd_c2) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {

                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else if (bd_r == bd_r2 && bd_c == bd_c2) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {

                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else if (bd_r == bd_r1) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {
                    let cell = data[bd_r][bd_c];

                    let mc = cfg.merge[`${cell.mc.r}_${cell.mc.c}`];

                    if (mc.c == bd_c) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                    }
                    else if (mc.c + mc.cs - 1 == bd_c) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else if (bd_r == bd_r2) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {
                    let cell = data[bd_r][bd_c];

                    let mc = cfg.merge[`${cell.mc.r}_${cell.mc.c}`];

                    if (mc.c == bd_c) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                    }
                    else if (mc.c + mc.cs - 1 == bd_c) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else if (bd_c == bd_c1) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {
                    let cell = data[bd_r][bd_c];

                    let mc = cfg.merge[`${cell.mc.r}_${cell.mc.c}`];

                    if (mc.r == bd_r) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                    }
                    else if (mc.r + mc.rs - 1 == bd_r) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else if (bd_c == bd_c2) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {
                    let cell = data[bd_r][bd_c];

                    let mc = cfg.merge[`${cell.mc.r}_${cell.mc.c}`];

                    if (mc.r == bd_r) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                    }
                    else if (mc.r + mc.rs - 1 == bd_r) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {
                    let cell = data[bd_r][bd_c];

                    let mc = cfg.merge[`${cell.mc.r}_${cell.mc.c}`];

                    if (mc.r == bd_r) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                    }
                    else if (mc.r + mc.rs - 1 == bd_r) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                    }

                    if (mc.c == bd_c) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                    }
                    else if (mc.c + mc.cs - 1 == bd_c) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                  }
                }
              }
            }
          }
          else if (borderType == 'border-horizontal') {
            for (let bd_r = bd_r1; bd_r <= bd_r2; bd_r++) {
              if (cfg.rowhidden != null && cfg.rowhidden[bd_r] != null) {
                continue;
              }

              for (let bd_c = bd_c1; bd_c <= bd_c2; bd_c++) {
                if (bd_r == bd_r1) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {

                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else if (bd_r == bd_r2) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {

                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {
                    let cell = data[bd_r][bd_c];

                    let mc = cfg.merge[`${cell.mc.r}_${cell.mc.c}`];

                    if (mc.r == bd_r) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                    }
                    else if (mc.r + mc.rs - 1 == bd_r) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': borderColor, 'style': borderStyle };
                  }
                }
              }
            }
          }
          else if (borderType == 'border-vertical') {
            for (let bd_r = bd_r1; bd_r <= bd_r2; bd_r++) {
              if (cfg.rowhidden != null && cfg.rowhidden[bd_r] != null) {
                continue;
              }

              for (let bd_c = bd_c1; bd_c <= bd_c2; bd_c++) {
                if (bd_c == bd_c1) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {

                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else if (bd_c == bd_c2) {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {

                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                  }
                }
                else {
                  if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {
                    let cell = data[bd_r][bd_c];

                    let mc = cfg.merge[`${cell.mc.r}_${cell.mc.c}`] || {};

                    if (mc.c == bd_c) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                    }
                    else if (mc.c + mc.cs - 1 == bd_c) {
                      if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                        borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                      }

                      borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                    }
                  }
                  else {
                    if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
                      borderInfoCompute[`${bd_r}_${bd_c}`] = {};
                    }

                    borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': borderColor, 'style': borderStyle };
                    borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': borderColor, 'style': borderStyle };
                  }
                }
              }
            }
          }
          else if (borderType == 'border-none') {
            for (let bd_r = bd_r1; bd_r <= bd_r2; bd_r++) {
              if (cfg.rowhidden != null && cfg.rowhidden[bd_r] != null) {
                continue;
              }

              for (let bd_c = bd_c1; bd_c <= bd_c2; bd_c++) {
                if (borderInfoCompute[`${bd_r}_${bd_c}`] != null) {
                  delete borderInfoCompute[`${bd_r}_${bd_c}`];
                }

                if (bd_r == bd_r1) {
                  let bd_r_top = bd_r1 - 1;

                  if (bd_r_top >= 0 && borderInfoCompute[`${bd_r_top}_${bd_c}`]) {
                    delete borderInfoCompute[`${bd_r_top}_${bd_c}`].b;
                  }
                }

                if (bd_r == bd_r2) {
                  let bd_r_bottom = bd_r2 + 1;

                  if (bd_r_bottom < data.length && borderInfoCompute[`${bd_r_bottom}_${bd_c}`]) {
                    delete borderInfoCompute[`${bd_r_bottom}_${bd_c}`].t;
                  }
                }

                if (bd_c == bd_c1) {
                  let bd_c_left = bd_c1 - 1;

                  if (bd_c_left >= 0 && borderInfoCompute[`${bd_r}_${bd_c_left}`]) {
                    delete borderInfoCompute[`${bd_r}_${bd_c_left}`].r;
                  }
                }

                if (bd_c == bd_c2) {
                  let bd_c_right = bd_c2 + 1;

                  if (bd_c_right < data[0].length && borderInfoCompute[`${bd_r}_${bd_c_right}`]) {
                    delete borderInfoCompute[`${bd_r}_${bd_c_right}`].l;
                  }
                }
              }
            }
          }
        }
      }
      else if (rangeType == 'cell') {
        let value = borderInfo[i].value;

        let bd_r = value.row_index; let bd_c = value.col_index;

        if (bd_r < dataset_row_st || bd_r > dataset_row_ed || bd_c < dataset_col_st || bd_c > dataset_col_ed) {
          continue;
        }

        if (cfg.rowhidden != null && cfg.rowhidden[bd_r] != null) {
          continue;
        }

        if (value.l != null || value.r != null || value.t != null || value.b != null) {
          if (borderInfoCompute[`${bd_r}_${bd_c}`] == null) {
            borderInfoCompute[`${bd_r}_${bd_c}`] = {};
          }

          if (data[bd_r] != null && getObjType(data[bd_r][bd_c]) == 'object' && data[bd_r][bd_c].mc != null) {
            let cell = data[bd_r][bd_c];
            let mc = cfg.merge[`${cell.mc.r}_${cell.mc.c}`] || {};

            if (value.l != null && bd_c == mc.c) { // 左边框
              borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': value.l.color, 'style': value.l.style };

              let bd_c_left = bd_c - 1;

              if (bd_c_left >= 0 && borderInfoCompute[`${bd_r}_${bd_c_left}`]) {
                if (data[bd_r] != null && getObjType(data[bd_r][bd_c_left]) == 'object' && data[bd_r][bd_c_left].mc != null) {
                  let cell_left = data[bd_r][bd_c_left];

                  let mc_l = cfg.merge[`${cell_left.mc.r}_${cell_left.mc.c}`];

                  if (mc_l.c + mc_l.cs - 1 == bd_c_left) {
                    borderInfoCompute[`${bd_r}_${bd_c_left}`].r = { 'color': value.l.color, 'style': value.l.style };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r}_${bd_c_left}`].r = { 'color': value.l.color, 'style': value.l.style };
                }
              }
            }
            else {
              borderInfoCompute[`${bd_r}_${bd_c}`].l = null;
            }

            if (value.r != null && bd_c == mc.c + mc.cs - 1) { // 右边框
              borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': value.r.color, 'style': value.r.style };

              let bd_c_right = bd_c + 1;

              if (bd_c_right < data[0].length && borderInfoCompute[`${bd_r}_${bd_c_right}`]) {
                if (data[bd_r] != null && getObjType(data[bd_r][bd_c_right]) == 'object' && data[bd_r][bd_c_right].mc != null) {
                  let cell_right = data[bd_r][bd_c_right];

                  let mc_r = cfg.merge[`${cell_right.mc.r}_${cell_right.mc.c}`];

                  if (mc_r.c == bd_c_right) {
                    borderInfoCompute[`${bd_r}_${bd_c_right}`].l = { 'color': value.r.color, 'style': value.r.style };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r}_${bd_c_right}`].l = { 'color': value.r.color, 'style': value.r.style };
                }
              }
            }
            else {
              borderInfoCompute[`${bd_r}_${bd_c}`].r = null;
            }

            if (value.t != null && bd_r == mc.r) { // 上边框
              borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': value.t.color, 'style': value.t.style };

              let bd_r_top = bd_r - 1;

              if (bd_r_top >= 0 && borderInfoCompute[`${bd_r_top}_${bd_c}`]) {
                if (data[bd_r_top] != null && getObjType(data[bd_r_top][bd_c]) == 'object' && data[bd_r_top][bd_c].mc != null) {
                  let cell_top = data[bd_r_top][bd_c];

                  let mc_t = cfg.merge[`${cell_top.mc.r}_${cell_top.mc.c}`];

                  if (mc_t.r + mc_t.rs - 1 == bd_r_top) {
                    borderInfoCompute[`${bd_r_top}_${bd_c}`].b = { 'color': value.t.color, 'style': value.t.style };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r_top}_${bd_c}`].b = { 'color': value.t.color, 'style': value.t.style };
                }
              }
            }
            else {
              borderInfoCompute[`${bd_r}_${bd_c}`].t = null;
            }

            if (value.b != null && bd_r == mc.r + mc.rs - 1) { // 下边框
              borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': value.b.color, 'style': value.b.style };

              let bd_r_bottom = bd_r + 1;

              if (bd_r_bottom < data.length && borderInfoCompute[`${bd_r_bottom}_${bd_c}`]) {
                if (data[bd_r_bottom] != null && getObjType(data[bd_r_bottom][bd_c]) == 'object' && data[bd_r_bottom][bd_c].mc != null) {
                  let cell_bottom = data[bd_r_bottom][bd_c];

                  let mc_b = cfg.merge[`${cell_bottom.mc.r}_${cell_bottom.mc.c}`];

                  if (mc_b.r == bd_r_bottom) {
                    borderInfoCompute[`${bd_r_bottom}_${bd_c}`].t = { 'color': value.b.color, 'style': value.b.style };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r_bottom}_${bd_c}`].t = { 'color': value.b.color, 'style': value.b.style };
                }
              }
            }
            else {
              borderInfoCompute[`${bd_r}_${bd_c}`].b = null;
            }
          }
          else {
            if (value.l != null) { // 左边框
              borderInfoCompute[`${bd_r}_${bd_c}`].l = { 'color': value.l.color, 'style': value.l.style };

              let bd_c_left = bd_c - 1;

              if (bd_c_left >= 0 && borderInfoCompute[`${bd_r}_${bd_c_left}`]) {
                if (data[bd_r] != null && getObjType(data[bd_r][bd_c_left]) == 'object' && data[bd_r][bd_c_left].mc != null) {
                  let cell_left = data[bd_r][bd_c_left];

                  let mc_l = cfg.merge[`${cell_left.mc.r}_${cell_left.mc.c}`];

                  if (mc_l.c + mc_l.cs - 1 == bd_c_left) {
                    borderInfoCompute[`${bd_r}_${bd_c_left}`].r = { 'color': value.l.color, 'style': value.l.style };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r}_${bd_c_left}`].r = { 'color': value.l.color, 'style': value.l.style };
                }
              }
            }
            else {
              borderInfoCompute[`${bd_r}_${bd_c}`].l = null;
            }

            if (value.r != null) { // 右边框
              borderInfoCompute[`${bd_r}_${bd_c}`].r = { 'color': value.r.color, 'style': value.r.style };

              let bd_c_right = bd_c + 1;

              if (bd_c_right < data[0].length && borderInfoCompute[`${bd_r}_${bd_c_right}`]) {
                if (data[bd_r] != null && getObjType(data[bd_r][bd_c_right]) == 'object' && data[bd_r][bd_c_right].mc != null) {
                  let cell_right = data[bd_r][bd_c_right];

                  let mc_r = cfg.merge[`${cell_right.mc.r}_${cell_right.mc.c}`];

                  if (mc_r.c == bd_c_right) {
                    borderInfoCompute[`${bd_r}_${bd_c_right}`].l = { 'color': value.r.color, 'style': value.r.style };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r}_${bd_c_right}`].l = { 'color': value.r.color, 'style': value.r.style };
                }
              }
            }
            else {
              borderInfoCompute[`${bd_r}_${bd_c}`].r = null;
            }

            if (value.t != null) { // 上边框
              borderInfoCompute[`${bd_r}_${bd_c}`].t = { 'color': value.t.color, 'style': value.t.style };

              let bd_r_top = bd_r - 1;

              if (bd_r_top >= 0 && borderInfoCompute[`${bd_r_top}_${bd_c}`]) {
                if (data[bd_r_top] != null && getObjType(data[bd_r_top][bd_c]) == 'object' && data[bd_r_top][bd_c].mc != null) {
                  let cell_top = data[bd_r_top][bd_c];

                  let mc_t = cfg.merge[`${cell_top.mc.r}_${cell_top.mc.c}`];

                  if (mc_t.r + mc_t.rs - 1 == bd_r_top) {
                    borderInfoCompute[`${bd_r_top}_${bd_c}`].b = { 'color': value.t.color, 'style': value.t.style };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r_top}_${bd_c}`].b = { 'color': value.t.color, 'style': value.t.style };
                }
              }
            }
            else {
              borderInfoCompute[`${bd_r}_${bd_c}`].t = null;
            }

            if (value.b != null) { // 下边框
              borderInfoCompute[`${bd_r}_${bd_c}`].b = { 'color': value.b.color, 'style': value.b.style };

              let bd_r_bottom = bd_r + 1;

              if (bd_r_bottom < data.length && borderInfoCompute[`${bd_r_bottom}_${bd_c}`]) {
                if (data[bd_r_bottom] != null && getObjType(data[bd_r_bottom][bd_c]) == 'object' && data[bd_r_bottom][bd_c].mc != null) {
                  let cell_bottom = data[bd_r_bottom][bd_c];

                  let mc_b = cfg.merge[`${cell_bottom.mc.r}_${cell_bottom.mc.c}`];

                  if (mc_b.r == bd_r_bottom) {
                    borderInfoCompute[`${bd_r_bottom}_${bd_c}`].t = { 'color': value.b.color, 'style': value.b.style };
                  }
                }
                else {
                  borderInfoCompute[`${bd_r_bottom}_${bd_c}`].t = { 'color': value.b.color, 'style': value.b.style };
                }
              }
            }
            else {
              borderInfoCompute[`${bd_r}_${bd_c}`].b = null;
            }
          }
        }
        else {
          delete borderInfoCompute[`${bd_r}_${bd_c}`];
        }
      }
    }
  }
  return borderInfoCompute;
};

// 获取数据类型
const getObjType = function(obj) {
  let toString = Object.prototype.toString;

  let map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object'
  };
  return map[toString.call(obj)];
};


const setStyleAndValue = function(cellArr, worksheet) {
  if (!Array.isArray(cellArr)) { return; }

  cellArr.forEach((row, rowid) => {
    const dbrow = worksheet.getRow(rowid + 1);
    // 设置单元格行高,默认乘以1.2倍
    dbrow.height = luckysheet.getRowHeight([rowid])[rowid] * 0.78;
    row.every((cell, columnid) => {
      if (!cell) { return true; }
      if (rowid == 0) {
        const dobCol = worksheet.getColumn(columnid + 1);
        // 设置单元格列宽除以8
        dobCol.width = luckysheet.getColumnWidth([columnid])[columnid] / 8;
      }
      let fill = fillConvert(cell.bg);
      let font = fontConvert(cell.ff, cell.fc, cell.bl, cell.it, cell.fs, cell.cl, cell.ul);
      let alignment = alignmentConvert(cell.vt, cell.ht, cell.tb, cell.tr);
      let value;

      let v = '';
      if (cell.ct && cell.ct.t == 'inlineStr') {
        let s = cell.ct.s;
        s.forEach((val, num) => {
          v += val.v;
        });
      } else {
        v = cell.v;
      }
      if (cell.f) {
        value = { formula: cell.f, result: v };
      } else {
        value = v;
      }
      let target = worksheet.getCell(rowid + 1, columnid + 1);
      target.fill = fill;
      target.font = font;
      target.alignment = alignment;
      target.value = value;
      return true;
    });
  });
};

// 转换颜色
const rgb2hex = function(rgb) {
  if (rgb.charAt(0) == '#') {
    return rgb;
  }

  let ds = rgb.split(/\D+/);
  let decimal = Number(ds[1]) * 65536 + Number(ds[2]) * 256 + Number(ds[3]);
  return `#${zero_fill_hex(decimal, 6)}`;

  function zero_fill_hex(num, digits) {
    let s = num.toString(16);
    while (s.length < digits) { s = `0${s}`; }
    return s;
  }
};

const fillConvert = function(bg) {
  if (!bg) {
    return null;
    // return {
    // 	type: 'pattern',
    // 	pattern: 'solid',
    // 	fgColor:{argb:'#ffffff'.replace('#','')}
    // }
  }
  bg = bg.indexOf('rgb') > -1 ? rgb2hex(bg) : bg;
  let fill = {
    type: 'pattern',
    pattern: 'solid',
    fgColor: { argb: bg.replace('#', '') }
  };
  return fill;
};

const fontConvert = function(ff = 0, fc = '#000000', bl = 0, it = 0, fs = 10, cl = 0, ul = 0) { // luckysheet：ff(样式), fc(颜色), bl(粗体), it(斜体), fs(大小), cl(删除线), ul(下划线)
  const luckyToExcel = {
    0: 'Times New Roman',
    1: 'Arial',
    2: 'Tahoma',
    3: 'Verdana',
    4: '微软雅黑',
    // 5: '宋体（Song）',
    5: '宋体',
    // 6: '黑体（ST Heiti）',
    6: '黑体',
    7: '楷体（ST Kaiti）',
    8: '仿宋（ST FangSong）',
    9: '新宋体（ST Song）',
    10: '华文新魏',
    11: '华文行楷',
    12: '华文隶书',
    num2bl(num) {
      return num === 0 ? false : true;
    }
  };

  let color = fc ? '' : `${fc}`.indexOf('rgb') > -1 ? rgb2hex(fc) : fc;

  let font = {
    name: luckyToExcel[ff] || luckyToExcel[1],
    family: 1,
    size: fs,
    color: { argb: color.replace('#', '') },
    bold: luckyToExcel.num2bl(bl),
    italic: luckyToExcel.num2bl(it),
    underline: luckyToExcel.num2bl(ul),
    strike: luckyToExcel.num2bl(cl)
  };

  return font;
};

const alignmentConvert = function(vt = 'default', ht = 'default', tb = 'default', tr = 'default') { // luckysheet:vt(垂直), ht(水平), tb(换行), tr(旋转)
  const luckyToExcel = {
    vertical: {
      0: 'middle',
      1: 'top',
      2: 'bottom',
      default: 'top'
    },
    horizontal: {
      0: 'center',
      1: 'left',
      2: 'right',
      default: 'left'
    },
    wrapText: {
      0: false,
      1: false,
      2: true,
      default: false
    },
    textRotation: {
      0: 0,
      1: 45,
      2: -45,
      3: 'vertical',
      4: 90,
      5: -90,
      default: 0
    }
  };

  let alignment = {
    vertical: luckyToExcel.vertical[vt],
    horizontal: luckyToExcel.horizontal[ht],
    wrapText: luckyToExcel.wrapText[tb],
    textRotation: luckyToExcel.textRotation[tr]
  };
  return alignment;

};

/**
 * 批量图片URL转Base64（高性能并行处理）
 * @param {string[]} urls - 图片URL数组
 * @param {Object} options - 配置选项
 * @returns {Promise<Array<{url: string, base64: string, error?: string}>>}
 */
async function batchUrlsToBase64(urls, options = {}) {
  if (!Array.isArray(urls) || urls.length === 0) {
    throw new Error('URL列表不能为空');
  }

  // 限制并发数量，避免浏览器资源耗尽
  const CONCURRENT_LIMIT = 4;
  const results = [];

  // 分批处理
  for (let i = 0; i < urls.length; i += CONCURRENT_LIMIT) {
    const batch = urls.slice(i, i + CONCURRENT_LIMIT);
    const batchPromises = batch.map(url =>
      urlToBase64HighPerformance(url, options)
        .then(base64 => ({ url, base64 }))
        .catch(error => ({ url, base64: null, error: error.message }))
    );

    const batchResults = await Promise.allSettled(batchPromises);

    // 处理本批次结果
    batchResults.forEach(result => {
      if (result.status === 'fulfilled') {
        results.push(result.value);
      } else {
        results.push({
          url: 'unknown',
          base64: null,
          error: result.reason.message
        });
      }
    });

    // 批次间短暂延迟，避免阻塞主线程
    if (i + CONCURRENT_LIMIT < urls.length) {
      await new Promise(resolve => setTimeout(resolve, 100));
    }
  }

  return results;
}
/**
 * 高性能图片URL转Base64方法
 * @param {string} url - 图片URL地址
 * @param {Object} options - 配置选项
 * @param {number} options.timeout - 请求超时时间（毫秒），默认10000
 * @param {boolean} options.forceCanvas - 强制使用Canvas进行压缩/格式转换
 * @param {string} options.canvasFormat - Canvas输出格式，默认'image/jpeg'
 * @param {number} options.canvasQuality - Canvas输出质量(0-1)，默认0.8
 * @returns {Promise<string>} Base64编码的图片数据
 */
async function urlToBase64HighPerformance(url, options = {}) {
  const {
    timeout = 10000,
    forceCanvas = false,
    canvasFormat = 'image/jpeg',
    canvasQuality = 0.8
  } = options;

  // 参数验证
  if (!url || typeof url !== 'string') {
    return null;
    // throw new Error('图片URL不能为空且必须是字符串');
  }

  try {
    // 创建超时控制器
    // const controller = new AbortController();
    // const timeoutId = setTimeout(() => controller.abort(), timeout);

    // 使用Fetch API获取图片
    const response = await fetch(url, {
      // signal: controller.signal,
      // cache: 'force-cache' // 利用浏览器缓存
    });

    // clearTimeout(timeoutId);

    if (!response.ok) {
      return null;
      // throw new Error(`HTTP错误! 状态: ${response.status}`);
    }

    // 获取图片Blob
    const blob = await response.blob();

    // 性能选择：直接使用Blob转Base64或通过Canvas处理
    if (forceCanvas) {
      return await convertViaCanvas(blob, canvasFormat, canvasQuality);
    } else {
      return await convertViaFileReader(blob);
    }

  } catch (error) {
    if (error.name === 'AbortError') {
      return null;
      // throw new Error(`图片加载超时（${timeout}ms）`);
    }
    return null;
    // throw new Error(`转换失败: ${error.message}`);
  }
}

/**
 * 通过FileReader直接转换（最高性能）
 */
function convertViaFileReader(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();

    reader.onloadend = () => {
      resolve(reader.result);
    };

    reader.onerror = () => {
      reject(new Error('文件读取失败'));
    };

    reader.readAsDataURL(blob);
  });
}

/**
 * 通过Canvas转换（用于格式转换或压缩）
 */
function convertViaCanvas(blob, format = 'image/jpeg', quality = 0.8) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // 处理跨域图片
    img.crossOrigin = 'anonymous';

    img.onload = () => {
      try {
        canvas.width = img.naturalWidth;
        canvas.height = img.naturalHeight;

        // 绘制图片到Canvas
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

        // 转换为Base64（可控制格式和质量）
        const base64 = canvas.toDataURL(format, quality);
        resolve(base64);
      } catch (error) {
        reject(new Error(`Canvas转换失败: ${error.message}`));
      }
    };

    img.onerror = () => reject(new Error('图片加载失败'));

    // 通过Object URL加载图片
    img.src = URL.createObjectURL(blob);

    // 清理Object URL
    img.onload = () => {
      URL.revokeObjectURL(img.src);
    };
  });
}
export default exportSheetExcel;