qinhb пре 3 месеци
родитељ
комит
fb8b48bab1
1 измењених фајлова са 169 додато и 56 уклоњено
  1. 169 56
      src/components/ExcelView/export.js

+ 169 - 56
src/components/ExcelView/export.js

@@ -1,5 +1,7 @@
 // import { createCellPos } from './translateNumToLetter'
 import Excel from "exceljs";
+
+import Big from 'big.js';
 import FileSaver from "file-saver";
 function exportExcel(luckysheet, name, excelType) {
   // 1.创建工作簿,可以为工作簿添加属性
@@ -46,6 +48,53 @@ function exportExcel(luckysheet, name, excelType) {
   return buffer;
 }
 
+function getExcelBlob(luckysheet, name, excelType) {
+  // 1.创建工作簿,可以为工作簿添加属性
+  const workbook = new Excel.Workbook();
+  // 2.创建表格,第二个参数可以配置创建什么样的工作表
+  luckysheet.forEach(function (table) {
+    // debugger
+    if (table.data.length === 0) return true;
+    const worksheet = workbook.addWorksheet(table.name);
+    const merge = (table.config && table.config.merge) || {}; //合并单元格
+    const borderInfo = (table.config && table.config.borderInfo) || {}; //边框
+    const columnWidth = (table.config && table.config.columnlen) || {}; //列宽
+    const rowHeight = (table.config && table.config.rowlen) || {}; //行高
+    const frozen = table.frozen || {}; //冻结
+    const rowhidden = (table.config && table.config.rowhidden) || {}; //行隐藏
+    const colhidden = (table.config && table.config.colhidden) || {}; //列隐藏
+    const filterSelect = table.filter_select || {}; //筛选
+    const hide = table.hide; //工作表 sheet 1隐藏
+    if (hide === 1) {
+      // 隐藏工作表
+      worksheet.state = "hidden";
+    }
+    setStyleAndValue(table.data, worksheet);
+    setMerge(merge, worksheet);
+    setBorder(borderInfo, worksheet);
+    setImages(table, worksheet, workbook);
+    setColumnWidth(columnWidth, worksheet);
+    //行高设置50导出后在ms-excel中打开显示25,在wps-excel中打开显示50这个bug不会修复
+    setRowHeight(rowHeight, worksheet, excelType);
+    setFrozen(frozen, worksheet);
+    setRowHidden(rowhidden, worksheet);
+    setColHidden(colhidden, worksheet);
+    setFilter(filterSelect, worksheet);
+    return true;
+  });
+  const buffer = workbook.xlsx.writeBuffer().then((data) => {
+    // console.log('data', data)
+    const blob = new Blob([data], {
+      type: "application/vnd.ms-excel;charset=utf-8",
+    });
+
+    return new Promise((resolve, reject) => {
+      resolve(blob);
+    });
+  });
+  return buffer;
+}
+
 /**
  * 列宽
  * @param columnWidth
@@ -91,10 +140,10 @@ var setMerge = function (luckyMerge = {}, worksheet) {
     // 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
+        elem.r + 1,
+        elem.c + 1,
+        elem.r + elem.rs,
+        elem.c + elem.cs
     );
   });
 };
@@ -292,8 +341,8 @@ var setBorder = function (luckyBorderInfo, worksheet) {
       let border = addborderToCell(borderData, row_index, col_index);
       let border1 = worksheet.getCell(row_index + 1, col_index + 1).border;
       worksheet.getCell(row_index + 1, col_index + 1).border = mergeCellBorder(
-        border1,
-        border
+          border1,
+          border
       );
       // console.log(row_index + 1, col_index + 1, worksheet.getCell(row_index + 1, col_index + 1).border)
     }
@@ -308,13 +357,13 @@ var setStyleAndValue = function (cellArr, worksheet) {
       let fill = fillConvert(cell.bg);
 
       let font = fontConvert(
-        cell.ff,
-        cell.fc,
-        cell.bl,
-        cell.it,
-        cell.fs,
-        cell.cl,
-        cell.ul
+          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 = "";
@@ -420,7 +469,7 @@ var setStyleAndValue = function (cellArr, worksheet) {
 }*/
 
 //获取图片在单元格的位置
-var getImagePosition = function (num, arr) {
+/*var getImagePosition = function (num, arr) {
   let index = 0;
   let minIndex;
   let maxIndex;
@@ -446,46 +495,110 @@ var getImagePosition = function (num, arr) {
   let max = arr[maxIndex];
   let radio = Math.abs((num - min) / (max - min)) + index;
   return radio;
-};
+};*/
+var getImagePosition = function (num, arr) {
+  let returnObj = null;
+  for (let i = 0; i < arr.length; i++) {
+    const item = arr[i]
+    if (num < item) {
+      const cell = i > 0 ? arr[i] - arr[i - 1]:item
+      // 偏移量单位为Emu,所以单元格的宽高需要转换为Emu的单位,cellWidth = cellWidth*10000
+      const cellInEmu = cell * 10000
+      const rowOrCol = i > 0 ? (num - arr[i - 1]) / (arr[i] - arr[i - 1]) + i:num/item
+      const native = Math.floor(rowOrCol)
+      const nativeOff = parseInt(new Big(rowOrCol).minus(native).toNumber() * cellInEmu)
+      returnObj = { rowOrCol, native, nativeOff }
+      break;
+    }
+  }
+
+  if(returnObj == undefined || returnObj == null){
+    const currentV = arr[arr.length-1]
+    const frontV = arr[arr.length-2]
+    const cell = currentV - frontV
+    arr.push(currentV + cell)
+    returnObj = getImagePosition(num,arr)
+  }
+  return returnObj;
+}
 /**
  * 设置图片
  * @param images
  * @param worksheet
  * @param workbook
  */
-var setImages = function (table, worksheet, workbook) {
+/*var setImages = function (table, worksheet, workbook) {
   let {
     images,
-    visibledatacolumn, //所有行的位置
-    visibledatarow, //所有列的位置
-  } = { ...table };
-  if (typeof images != "object") return;
+    visibledatacolumn,//所有行的位置
+    visibledatarow //所有列的位置
+  } = {...table}
+  if (typeof images != 'object') return;
   for (let key in images) {
-    // console.log(images[key]);
-    // "data:image/png;base64,iVBORw0KG..."
     // 通过 base64  将图像添加到工作簿
     const myBase64Image = images[key].src;
-    //位置
-    const col_st = getImagePosition(
-      images[key].default.left,
-      visibledatacolumn
-    );
-    const row_st = getImagePosition(images[key].default.top, visibledatarow);
-    /*const tl = {col: images[key].default.left / 72, row: images[key].default.top / 19}*/
-    const tl = { col: col_st, row: row_st };
-    // 大小
-    const ext = {
-      width: images[key].default.width,
-      height: images[key].default.height,
-    };
+    //开始行 开始列 结束行 结束列
+    const item = images[key];
     const imageId = workbook.addImage({
       base64: myBase64Image,
-      //extension: 'png',
+      extension: 'png'
     });
+
+    const col_st = getImagePosition(item.default.left,visibledatacolumn);
+    const row_st = getImagePosition(item.default.top,visibledatarow);
+
+    console.log(item.default.left,item.default.top,visibledatacolumn,visibledatarow)
+    console.log("1111111111111::" + col_st)
+    console.log("2222222222222::" + row_st)
+    //模式1,图片左侧与luckysheet位置一样,像素比例保持不变,但是,右侧位置可能与原图所在单元格不一致
     worksheet.addImage(imageId, {
-      tl: tl,
-      ext: ext,
+      tl: { col: col_st, row: row_st},
+      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},
+    // });
+  }
+};*/
+
+var setImages = function (table, worksheet, workbook) {
+  let {
+    images,
+    visibledatacolumn,//所有行的位置
+    visibledatarow //所有列的位置
+  } = { ...table }
+  if (typeof images != 'object') return;
+  for (let key in images) {
+    // 通过 base64  将图像添加到工作簿
+    const myBase64Image = images[key].src;
+    //开始行 开始列 结束行 结束列
+    const item = images[key];
+    const imageId = workbook.addImage({
+      base64: myBase64Image,
+      extension: 'png'
+    });
+
+    // 只有设置tl、br的图片可以被luckysheet识别并展示,设置ext宽高的不行
+    const col_st = getImagePosition(item.default.left, visibledatacolumn);
+    const row_st = getImagePosition(item.default.top, visibledatarow);
+    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);
+    // 需要设置nativeCol,nativeColOff,nativeRow,nativeRowOff,可以省略col,row
+    if(row_ed != undefined && col_ed != undefined){
+      worksheet.addImage(imageId, {
+        tl: { nativeCol: col_st.native, nativeColOff: col_st.nativeOff, nativeRow: row_st.native, nativeRowOff: row_st.nativeOff },
+        br: { nativeCol: col_ed.native, nativeColOff: col_ed.nativeOff, nativeRow: row_ed.native, nativeRowOff: row_ed.nativeOff },
+        editAs: 'oneCell',
+      });
+    }
   }
 };
 
@@ -496,34 +609,34 @@ var setImages = function (table, worksheet, workbook) {
  */
 var setFrozen = function (frozen = {}, worksheet) {
   switch (frozen.type) {
-    // 冻结首行
+      // 冻结首行
     case "row": {
       worksheet.views = [{ state: "frozen", xSplit: 0, ySplit: 1 }];
       break;
     }
-    // 冻结首列
+      // 冻结首列
     case "column": {
       worksheet.views = [{ state: "frozen", xSplit: 1, ySplit: 0 }];
       break;
     }
-    // 冻结行列
+      // 冻结行列
     case "both": {
       worksheet.views = [{ state: "frozen", xSplit: 1, ySplit: 1 }];
       break;
     }
-    // 冻结行到选区
+      // 冻结行到选区
     case "rangeRow": {
       let row = frozen.range.row_focus + 1;
       worksheet.views = [{ state: "frozen", xSplit: 0, ySplit: row }];
       break;
     }
-    // 冻结列到选区
+      // 冻结列到选区
     case "rangeColumn": {
       let column = frozen.range.column_focus + 1;
       worksheet.views = [{ state: "frozen", xSplit: column, ySplit: 0 }];
       break;
     }
-    // 冻结行列到选区
+      // 冻结行列到选区
     case "rangeBoth": {
       let row = frozen.range.row_focus + 1;
       let column = frozen.range.column_focus + 1;
@@ -651,13 +764,13 @@ var fillConvert = function (bg) {
 };
 
 var fontConvert = function (
-  ff = 0,
-  fc = "#000000",
-  bl = 0,
-  it = 0,
-  fs = 10,
-  cl = 0,
-  ul = 0
+    ff = 0,
+    fc = "#000000",
+    bl = 0,
+    it = 0,
+    fs = 10,
+    cl = 0,
+    ul = 0
 ) {
   // luckysheet:ff(样式), fc(颜色), bl(粗体), it(斜体), fs(大小), cl(删除线), ul(下划线)
   const luckyToExcel = {
@@ -694,10 +807,10 @@ var fontConvert = function (
   return font;
 };
 var alignmentConvert = function (
-  vt = "default",
-  ht = "default",
-  tb = "default",
-  tr = "default"
+    vt = "default",
+    ht = "default",
+    tb = "default",
+    tr = "default"
 ) {
   // luckysheet:vt(垂直), ht(水平), tb(换行), tr(旋转)
   const luckyToExcel = {
@@ -850,4 +963,4 @@ function colorRGBtoHex(color) {
   var b = parseInt(rgb[2]);
   return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
 }
-export { exportExcel };
+export { exportExcel, getExcelBlob };