فهرست منبع

feature/在线表格优化图片导入

dy 11 ماه پیش
والد
کامیت
e757baa0dd
5فایلهای تغییر یافته به همراه718 افزوده شده و 193 حذف شده
  1. 1 1
      .env.development
  2. 2 5
      .env.production
  3. 137 145
      src/views/excel/components/LuckySheet.vue
  4. 36 6
      src/views/excel/index.vue
  5. 542 36
      src/views/excel/utils/export.js

+ 1 - 1
.env.development

@@ -11,7 +11,7 @@ VITE_APP_BASE_API = '/dev-api'
 VITE_APP_UPLOAD_URL = 'http://192.168.101.4:9000'
 
 # 开发接口地址
-VITE_APP_API_URL = 'http://192.168.101.4:8079'
+VITE_APP_API_URL = 'http://192.168.101.4:7103'
 # Websocket地址
 VITE_WEBSOCKET_URL = 'ws://192.168.101.4:8079'
 ``

+ 2 - 5
.env.production

@@ -5,11 +5,8 @@ NODE_ENV='production'
 VITE_APP_BASE_API = '/client-server'
 
 # 上传文件接口地址
-VITE_APP_UPLOAD_URL = 'http://192.168.101.4:9000'
-
-# 开发接口地址
-VITE_APP_API_URL = 'http://192.168.101.4:8079'
-
+# VITE_APP_UPLOAD_URL = 'http://192.168.101.4:9000'
+VITE_APP_UPLOAD_URL = '/minio-server'
 
 # Websocket地址
 VITE_WEBSOCKET_URL = 'ws://192.168.101.4:8079'

+ 137 - 145
src/views/excel/components/LuckySheet.vue

@@ -1,23 +1,22 @@
 <template>
-  <div style="position: absolute; top: 0">
-    <input id="uploadBtn" type="file" @change="loadExcel" />
-
-    <span>Or Load remote xlsx file:</span>
-
-    <select v-model="selected" @change="selectExcel">
-      <option disabled value="">Choose</option>
-      <option
-        v-for="option in options"
-        :key="option.text"
-        :value="option.value"
-      >
-        {{ option.text }}
-      </option>
-    </select>
+  <div class="oprea">
+    <el-button type="primary" class="btn">提 交</el-button>
+    <el-button type="primary" class="btn" @click="downloadExcel"
+      >导 出</el-button
+    >
 
-    <a href="javascript:void(0)" @click="downloadExcel"
-      >Download source xlsx file</a
+    <el-upload
+      accept=".xlsx"
+      ref="upload"
+      :on-change="leadingExcel"
+      :auto-upload="false"
+      :show-file-list="false"
     >
+      <template #trigger>
+        <el-button type="primary" class="btn">导 入</el-button>
+      </template>
+    </el-upload>
+    <el-button type="primary" class="btn">打 印</el-button>
   </div>
   <div id="luckysheet"></div>
   <div v-show="isMaskShow" id="tip">Downloading</div>
@@ -31,151 +30,144 @@ import LuckyExcel from "luckyexcel";
 const isMaskShow = ref(false);
 const selected = ref("");
 const jsonData = ref({});
-const options = ref([
-  {
-    text: "Money Manager.xlsx",
-    value: "https://minio.cnbabylon.com/public/luckysheet/money-manager-2.xlsx",
-  },
-  {
-    text: "Activity costs tracker.xlsx",
-    value:
-      "https://minio.cnbabylon.com/public/luckysheet/Activity%20costs%20tracker.xlsx",
-  },
-  {
-    text: "House cleaning checklist.xlsx",
-    value:
-      "https://minio.cnbabylon.com/public/luckysheet/House%20cleaning%20checklist.xlsx",
-  },
-  {
-    text: "Student assignment planner.xlsx",
-    value:
-      "https://minio.cnbabylon.com/public/luckysheet/Student%20assignment%20planner.xlsx",
-  },
-  {
-    text: "Credit card tracker.xlsx",
-    value:
-      "https://minio.cnbabylon.com/public/luckysheet/Credit%20card%20tracker.xlsx",
-  },
-  {
-    text: "Blue timesheet.xlsx",
-    value:
-      "https://minio.cnbabylon.com/public/luckysheet/Blue%20timesheet.xlsx",
-  },
-  {
-    text: "Student calendar (Mon).xlsx",
-    value:
-      "https://minio.cnbabylon.com/public/luckysheet/Student%20calendar%20%28Mon%29.xlsx",
+const options = ref([]);
+const data = ref(null);
+let sheets = null;
+//表格初始化默认值
+const resetOb = ref({
+  container: "luckysheet", // 设定DOM容器的id
+  title: "Luckysheet Demo", // 设定表格名称
+  lang: "zh", // 设定表格语言
+  title: false, // 工作簿名称
+  enableAddBackTop: true, //返回头部按钮
+  userInfo: false, // 右上角的用户信息展示样式
+  showinfobar: false, // 是否显示顶部信息栏
+  enableAddRow: false, // 是否允许添加行
+  enableAddBackTop: false, // 允许回到顶部
+  showConfigWindowResize: true, // 自动缩进界面
+  // showtoolbar:false, // 工具栏
+  column: 30,
+  row: 30,
+  showsheetbar: false, // 是否显示底部sheet页按钮
+  showsheetbarConfig: {
+    add: false, //新增sheet
+    menu: false, //sheet管理菜单
+    sheet: false, //sheet页显示
   },
-  {
-    text: "Blue mileage and expense report.xlsx",
-    value:
-      "https://minio.cnbabylon.com/public/luckysheet/Blue%20mileage%20and%20expense%20report.xlsx",
+  data: data.value ? data.value : null,
+  showtoolbarConfig: {
+    undoRedo: true, //撤销重做,注意撤消重做是两个按钮,由这一个配置决定显示还是隐藏
+    paintFormat: false, //格式刷
+    currencyFormat: false, //货币格式
+    percentageFormat: false, //百分比格式
+    numberDecrease: false, // '减少小数位数'
+    numberIncrease: false, // '增加小数位数
+    moreFormats: true, // '更多格式'
+    font: true, // '字体'
+    fontSize: true, // '字号大小'
+    bold: true, // '粗体 (Ctrl+B)'
+    italic: true, // '斜体 (Ctrl+I)'
+    strikethrough: true, // '删除线 (Alt+Shift+5)'
+    underline: true, // '下划线 (Alt+Shift+6)'
+    textColor: true, // '文本颜色'
+    fillColor: true, // '单元格颜色'
+    border: true, // '边框'
+    mergeCell: true, // '合并单元格'
+    horizontalAlignMode: true, // '水平对齐方式'
+    verticalAlignMode: true, // '垂直对齐方式'
+    textWrapMode: false, // '换行方式'
+    textRotateMode: false, // '文本旋转方式'
+    image: true, // '插入图片'
+    link: true, // '插入链接'
+    chart: false, // '图表'(图标隐藏,但是如果配置了chart插件,右击仍然可以新建图表)
+    postil: false, //'批注'
+    pivotTable: false, //'数据透视表'
+    function: false, // '公式'
+    frozenMode: false, // '冻结方式'
+    sortAndFilter: false, // '排序和筛选'
+    conditionalFormat: false, // '条件格式'
+    dataVerification: false, // '数据验证'
+    splitColumn: false, // '分列'
+    screenshot: false, // '截图'
+    findAndReplace: true, // '查找替换'
+    protection: false, // '工作表保护'
+    print: true, // '打印'
   },
-]);
-
-const loadExcel = (evt) => {
-  const files = evt.target.files;
-  if (files == null || files.length == 0) {
-    alert("No files wait for import");
+});
+//设置第一个sheet
+const getActiveSheet = (sheets = []) => {
+  let data = [];
+  // 取激活项
+  sheets.some((item) => {
+    if (item.status === "1") {
+      data.push(item);
+      return true;
+    }
+  });
+  // 没有激活项,取第一项
+  if (data.length === 0) {
+    data.push(sheets[0]);
+  }
+  return data;
+};
+//导入
+const leadingExcel = (item, fileList) => {
+  const file = item.raw;
+  console.log("file", file);
+  if (file == null || file.name == "") {
     return;
   }
-
-  let name = files[0].name;
+  let name = file.name;
   let suffixArr = name.split("."),
     suffix = suffixArr[suffixArr.length - 1];
   if (suffix != "xlsx") {
-    alert("Currently only supports the import of xlsx files");
+    ElMessage.error("请导入xlsx格式的文件");
     return;
   }
-  LuckyExcel.transformExcelToLucky(
-    files[0],
-    function (exportJson, luckysheetfile) {
-      if (exportJson.sheets == null || exportJson.sheets.length == 0) {
-        alert(
-          "Failed to read the content of the excel file, currently does not support xls files!"
-        );
-        return;
-      }
-      console.log("exportJson", exportJson);
-      jsonData.value = exportJson;
-
-      window.luckysheet.destroy();
-
-      window.luckysheet.create({
-        container: "luckysheet", //luckysheet is the container id
-        showinfobar: false,
-        data: exportJson.sheets,
-        title: exportJson.info.name,
-        userInfo: exportJson.info.name.creator,
-      });
-    }
-  );
-};
-const selectExcel = (evt) => {
-  const value = selected.value;
-  const name = evt.target.options[evt.target.selectedIndex].innerText;
-
-  if (value == "") {
-    return;
-  }
-  isMaskShow.value = true;
-
-  LuckyExcel.transformExcelToLuckyByUrl(
-    value,
-    name,
-    (exportJson, luckysheetfile) => {
-      if (exportJson.sheets == null || exportJson.sheets.length == 0) {
-        alert(
-          "Failed to read the content of the excel file, currently does not support xls files!"
-        );
-        return;
-      }
-      console.log("exportJson", exportJson);
-      jsonData.value = exportJson;
-
-      isMaskShow.value = false;
-      window.luckysheet.destroy();
-
-      window.luckysheet.create({
-        container: "luckysheet", //luckysheet is the container id
-        showinfobar: false,
-        data: exportJson.sheets,
-        title: exportJson.info.name,
-        userInfo: exportJson.info.name.creator,
-      });
+  LuckyExcel.transformExcelToLucky(file, function (exportJson, luckysheetfile) {
+    if (exportJson.sheets == null || exportJson.sheets.length == 0) {
+      ElMessage.error("请导入xlsx格式的文件");
+      return;
     }
-  );
+    window.luckysheet.destroy();
+    const data = getActiveSheet(exportJson.sheets);
+    resetOb.value.data = data;
+    console.log(data, "data");
+    console.log("exportJson", exportJson);
+    sheets = data;
+    window.luckysheet.create(resetOb.value);
+  });
 };
+//导出
 const downloadExcel = () => {
-  // const value = selected.value;;
-  //
-  // if(value.length==0){
-  //     alert("Please select a demo file");
-  //     return;
-  // }
-  //
-  // var elemIF = document.getElementById("Lucky-download-frame");
-  // if(elemIF==null){
-  //     elemIF = document.createElement("iframe");
-  //     elemIF.style.display = "none";
-  //     elemIF.id = "Lucky-download-frame";
-  //     document.body.appendChild(elemIF);
-  // }
-  // elemIF.src = value;
-  exportExcel(luckysheet.getAllSheets(), "下载");
+  // console.log(luckysheet.getAllSheets())
+  // exportExcel(luckysheet.getAllSheets(), "TDM-excel");
+  // // 导出excel回调
+  // this.$emit("downloadExcel", "");
+  // window.open(process.env.VUE_APP_BASE_API+this.filePath)
+  exportExcel(sheets, "TDM-excel");
 };
-
-// !!! create luckysheet after mounted
 onMounted(() => {
-  luckysheet.create({
-    container: "luckysheet",
-  });
+  luckysheet.create(resetOb.value);
 });
 </script>
 
 <style lang="scss" scoped>
-.body {
-  max-height: 300px !important;
+.oprea {
+  padding: 0 20px;
+  width: 100%;
+  height: 60px;
+  display: flex;
+  align-items: center;
+  justify-content: space-evenly;
+
+  .btn {
+    margin: 0px !important;
+    width: 140px;
+    border-radius: 16px;
+    height: 40px;
+    font-size: $f16;
+  }
 }
 #luckysheet {
   margin: 0px;
@@ -183,7 +175,7 @@ onMounted(() => {
   position: absolute;
   width: 100%;
   left: 0px;
-  top: 30px;
+  top: 60px;
   bottom: 0px;
 }
 

+ 36 - 6
src/views/excel/index.vue

@@ -1,6 +1,14 @@
 <template>
-  <div id="ss">
-    <ExcelView />
+  <div class="excelview">
+    <div class="view">
+      <ExcelView />
+    </div>
+    <!-- <div class="oprea">
+      <el-button type="primary" class="btn">提交</el-button>
+      <el-button type="primary" class="btn">导出</el-button>
+      <el-button type="primary" class="btn">导入</el-button>
+      <el-button type="primary" class="btn">打印</el-button>
+    </div> -->
   </div>
 </template>
 
@@ -9,10 +17,32 @@ import ExcelView from "@/views/excel/components/LuckySheet.vue";
 </script>
 
 <style lang="scss" scoped>
-#ss {
-  position: relative;
-  width: 500px;
+.excelview {
+  display: flex;
+  width: 100%;
   height: 100%;
-  background-color: red;
+  .view {
+    position: relative;
+    width: 80%;
+    height: 80%;
+  }
+  .oprea {
+    flex: 1;
+    padding: 0 20px;
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: space-evenly;
+
+    .btn {
+      margin: 0px !important;
+      width: 80%;
+      border-radius: 16px;
+      height: 50px;
+      font-size: $f20;
+    }
+  }
 }
 </style>

+ 542 - 36
src/views/excel/utils/export.js

@@ -1,42 +1,90 @@
 // import { createCellPos } from './translateNumToLetter'
 import Excel from "exceljs";
-
 import FileSaver from "file-saver";
-
-const exportExcel = function (luckysheet, value) {
-  // 参数为luckysheet.getluckysheetfile()获取的对象
+function exportExcel(luckysheet, name, excelType) {
   // 1.创建工作簿,可以为工作簿添加属性
   const workbook = new Excel.Workbook();
   // 2.创建表格,第二个参数可以配置创建什么样的工作表
-  if (Object.prototype.toString.call(luckysheet) === "[object Object]") {
-    luckysheet = [luckysheet];
-  }
   luckysheet.forEach(function (table) {
+    // debugger
     if (table.data.length === 0) return true;
-    // ws.getCell('B2').fill = fills.
     const worksheet = workbook.addWorksheet(table.name);
-    const merge = (table.config && table.config.merge) || {};
-    const borderInfo = (table.config && table.config.borderInfo) || {};
-    // 3.设置单元格合并,设置单元格边框,设置单元格样式,设置值
+    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;
   });
-
-  // return
-  // 4.写入 buffer
   const buffer = workbook.xlsx.writeBuffer().then((data) => {
     // console.log('data', data)
     const blob = new Blob([data], {
       type: "application/vnd.ms-excel;charset=utf-8",
     });
     console.log("导出成功!");
-    FileSaver.saveAs(blob, `${value}.xlsx`);
+    FileSaver.saveAs(blob, name + `.xlsx`);
   });
   return buffer;
+}
+
+/**
+ * 列宽
+ * @param columnWidth
+ * @param worksheet
+ */
+var setColumnWidth = function (columnWidth, worksheet) {
+  for (let key in columnWidth) {
+    worksheet.getColumn(parseInt(key) + 1).width = columnWidth[key] / 7.5;
+  }
 };
 
+/**
+ * 行高
+ * @param rowHeight
+ * @param worksheet
+ * @param excelType
+ */
+var setRowHeight = function (rowHeight, worksheet, excelType) {
+  for (let key in rowHeight) {
+    worksheet.getRow(parseInt(key) + 1).height = rowHeight[key] * 0.75;
+  }
+  /*//导出的文件用wps打开和用excel打开显示的行高大一倍
+  if (excelType == "wps") {
+    for (let key in rowHeight) {
+      worksheet.getRow(parseInt(key) + 1).height = rowHeight[key] * 0.75
+    }
+  }
+  if (excelType == "office" || excelType == undefined) {
+    for (let key in rowHeight) {
+      worksheet.getRow(parseInt(key) + 1).height = rowHeight[key] * 1.5
+    }
+  }*/
+};
+
+/**
+ * 合并单元格
+ * @param luckyMerge
+ * @param worksheet
+ */
 var setMerge = function (luckyMerge = {}, worksheet) {
   const mergearr = Object.values(luckyMerge);
   mergearr.forEach(function (elem) {
@@ -51,8 +99,21 @@ var setMerge = function (luckyMerge = {}, worksheet) {
   });
 };
 
+/**
+ * 设置边框
+ * @param luckyBorderInfo
+ * @param worksheet
+ */
 var setBorder = function (luckyBorderInfo, worksheet) {
   if (!Array.isArray(luckyBorderInfo)) return;
+
+  //合并边框信息
+  var mergeCellBorder = function (border1, border2) {
+    if (undefined === border1 || Object.keys(border1).length === 0)
+      return border2;
+    return Object.assign({}, border1, border2);
+  };
+
   // console.log('luckyBorderInfo', luckyBorderInfo)
   luckyBorderInfo.forEach(function (elem) {
     // 现在只兼容到borderType 为range的情况
@@ -60,12 +121,160 @@ var setBorder = function (luckyBorderInfo, worksheet) {
     if (elem.rangeType === "range") {
       let border = borderConvert(elem.borderType, elem.style, elem.color);
       let rang = elem.range[0];
-      // console.log('range', rang)
       let row = rang.row;
       let column = rang.column;
-      for (let i = row[0] + 1; i < row[1] + 2; i++) {
-        for (let y = column[0] + 1; y < column[1] + 2; y++) {
+
+      let rowBegin = row[0];
+      let rowEnd = row[1];
+      let colBegin = column[0];
+      let colEnd = column[1];
+      //处理外边框的情况 没有直接对应的外边框 需要转换成上下左右
+      if (border.all) {
+        //全部边框
+        let b = border.all;
+        for (let i = row[0] + 1; i <= row[1] + 1; i++) {
+          for (let y = column[0] + 1; y <= column[1] + 1; y++) {
+            let border = {};
+            border["top"] = b;
+            border["bottom"] = b;
+            border["left"] = b;
+            border["right"] = b;
+            worksheet.getCell(i, y).border = border;
+            // console.log(i, y, worksheet.getCell(i, y).border)
+          }
+        }
+      } else if (border.top) {
+        //上边框
+        let b = border.top;
+        let i = row[0] + 1;
+        for (let y = column[0] + 1; y <= column[1] + 1; y++) {
+          let border = {};
+          border["top"] = b;
           worksheet.getCell(i, y).border = border;
+          // console.log(i, y, worksheet.getCell(i, y).border)
+        }
+      } else if (border.right) {
+        //右边框
+        let b = border.right;
+        for (let i = row[0] + 1; i <= row[1] + 1; i++) {
+          let y = column[1] + 1;
+          let border = {};
+          border["right"] = b;
+          worksheet.getCell(i, y).border = border;
+          // console.log(i, y, worksheet.getCell(i, y).border)
+        }
+      } else if (border.bottom) {
+        //下边框
+        let b = border.bottom;
+        let i = row[1] + 1;
+        for (let y = column[0] + 1; y <= column[1] + 1; y++) {
+          let border = {};
+
+          border["bottom"] = b;
+          worksheet.getCell(i, y).border = border;
+          // console.log(i, y, worksheet.getCell(i, y).border)
+        }
+      } else if (border.left) {
+        //左边框
+        let b = border.left;
+        for (let i = row[0] + 1; i <= row[1] + 1; i++) {
+          let y = column[0] + 1;
+          let border = {};
+          border["left"] = b;
+          worksheet.getCell(i, y).border = border;
+          // console.log(i, y, worksheet.getCell(i, y).border)
+        }
+      } else if (border.outside) {
+        //外边框
+        let b = border.outside;
+        for (let i = row[0] + 1; i <= row[1] + 1; i++) {
+          for (let y = column[0] + 1; y <= column[1] + 1; y++) {
+            let border = {};
+            if (i === rowBegin + 1) {
+              border["top"] = b;
+            }
+            if (i === rowEnd + 1) {
+              border["bottom"] = b;
+            }
+            if (y === colBegin + 1) {
+              border["left"] = b;
+            }
+            if (y === colEnd + 1) {
+              border["right"] = b;
+            }
+            let border1 = worksheet.getCell(i, y).border;
+            worksheet.getCell(i, y).border = mergeCellBorder(border1, border);
+            // console.log(i, y, worksheet.getCell(i, y).border)
+          }
+        }
+      } else if (border.inside) {
+        //内边框
+        let b = border.inside;
+        for (let i = row[0] + 1; i <= row[1] + 1; i++) {
+          for (let y = column[0] + 1; y <= column[1] + 1; y++) {
+            let border = {};
+            if (i !== rowBegin + 1) {
+              border["top"] = b;
+            }
+            if (i !== rowEnd + 1) {
+              border["bottom"] = b;
+            }
+            if (y !== colBegin + 1) {
+              border["left"] = b;
+            }
+            if (y !== colEnd + 1) {
+              border["right"] = b;
+            }
+            let border1 = worksheet.getCell(i, y).border;
+            worksheet.getCell(i, y).border = mergeCellBorder(border1, border);
+            // console.log(i, y, worksheet.getCell(i, y).border)
+          }
+        }
+      } else if (border.horizontal) {
+        //内侧水平边框
+        let b = border.horizontal;
+        for (let i = row[0] + 1; i <= row[1] + 1; i++) {
+          for (let y = column[0] + 1; y <= column[1] + 1; y++) {
+            let border = {};
+            if (i === rowBegin + 1) {
+              border["bottom"] = b;
+            } else if (i === rowEnd + 1) {
+              border["top"] = b;
+            } else {
+              border["top"] = b;
+              border["bottom"] = b;
+            }
+            let border1 = worksheet.getCell(i, y).border;
+            worksheet.getCell(i, y).border = mergeCellBorder(border1, border);
+            // console.log(i, y, worksheet.getCell(i, y).border)
+          }
+        }
+      } else if (border.vertical) {
+        //内侧垂直边框
+        let b = border.vertical;
+        for (let i = row[0] + 1; i <= row[1] + 1; i++) {
+          for (let y = column[0] + 1; y <= column[1] + 1; y++) {
+            let border = {};
+            if (y === colBegin + 1) {
+              border["right"] = b;
+            } else if (y === colEnd + 1) {
+              border["left"] = b;
+            } else {
+              border["left"] = b;
+              border["right"] = b;
+            }
+            let border1 = worksheet.getCell(i, y).border;
+            worksheet.getCell(i, y).border = mergeCellBorder(border1, border);
+            // console.log(i, y, worksheet.getCell(i, y).border)
+          }
+        }
+      } else if (border.none) {
+        //当luckysheet边框为border-none的时候表示没有边框 则将对应的单元格border清空
+        for (let i = row[0] + 1; i <= row[1] + 1; i++) {
+          for (let y = column[0] + 1; y <= column[1] + 1; y++) {
+            worksheet.getCell(i, y).border = {};
+            // console.log(i, y, worksheet.getCell(i, y).border)
+          }
         }
       }
     }
@@ -81,13 +290,16 @@ var setBorder = function (luckyBorderInfo, worksheet) {
       delete borderData.col_index;
       delete borderData.row_index;
       let border = addborderToCell(borderData, row_index, col_index);
-      // console.log('bordre', border, borderData)
-      worksheet.getCell(row_index + 1, col_index + 1).border = border;
+      let border1 = worksheet.getCell(row_index + 1, col_index + 1).border;
+      worksheet.getCell(row_index + 1, col_index + 1).border = mergeCellBorder(
+        border1,
+        border
+      );
+      // console.log(row_index + 1, col_index + 1, worksheet.getCell(row_index + 1, col_index + 1).border)
     }
-    // console.log(rang.column_focus + 1, rang.row_focus + 1)
-    // worksheet.getCell(rang.row_focus + 1, rang.column_focus + 1).border = border
   });
 };
+
 var setStyleAndValue = function (cellArr, worksheet) {
   if (!Array.isArray(cellArr)) return;
   cellArr.forEach(function (row, rowid) {
@@ -134,6 +346,296 @@ var setStyleAndValue = function (cellArr, worksheet) {
     });
   });
 };
+/*/!**
+ * 设置带样式的值
+ * @param cellArr
+ * @param worksheet
+ *!/
+var setStyleAndValue = function (cellArr, worksheet) {
+  if (!Array.isArray(cellArr)) return
+  cellArr.forEach(function (row, rowid) {
+    row.every(function (cell, columnid) {
+      if (!cell) return true
+      let fill = fillConvert(cell.bg)
+
+      let font = fontConvert(
+          cell.ff,
+          cell.fc,
+          cell.bl,
+          cell.it,
+          cell.fs,
+          cell.cl,
+          cell.un
+      )
+      let alignment = alignmentConvert(cell.vt, cell.ht, cell.tb, cell.tr)
+      let value = ''
+
+      if (cell.f) {
+        value = {formula: cell.f, result: cell.v}
+      } else if (!cell.v && cell.ct && cell.ct.s) {
+        // xls转为xlsx之后,内部存在不同的格式,都会进到富文本里,即值不存在与cell.v,而是存在于cell.ct.s之后
+        let richText = [];
+        let cts = cell.ct.s
+        for (let i = 0; i < cts.length; i++) {
+          let rt = {
+            text: cts[i].v,
+            font: fontConvert(cts[i].ff, cts[i].fc, cts[i].bl, cts[i].it, cts[i].fs, cts[i].cl, cts[i].un)
+          }
+          richText.push(rt)
+        }
+        value = {
+          richText: richText
+        };
+
+      } else {
+        //设置值为数字格式
+        if (cell.v !== undefined && cell.v !== '') {
+          var v = +cell.v;
+          if (isNaN(v)) v = cell.v
+          value = v
+        }
+      }
+      //  style 填入到_value中可以实现填充色
+      let letter = createCellPos(columnid)
+      let target = worksheet.getCell(letter + (rowid + 1))
+      // console.log('1233', letter + (rowid + 1))
+      for (const key in fill) {
+        target.fill = fill
+        break
+      }
+      target.font = font
+      target.alignment = alignment
+      target.value = value
+
+      try {
+        //设置单元格格式
+        target.numFmt = cell.ct.fa;
+      } catch (e) {
+        console.warn(e)
+      }
+
+      return true
+    })
+  })
+}*/
+
+//获取图片在单元格的位置
+var getImagePosition = function (num, arr) {
+  let index = 0;
+  let minIndex;
+  let maxIndex;
+  for (let i = 0; i < arr.length; i++) {
+    if (num < arr[i]) {
+      index = i;
+      break;
+    }
+  }
+
+  if (index == 0) {
+    minIndex = 0;
+    maxIndex = 1;
+    return Math.abs((num - 0) / (arr[maxIndex] - arr[minIndex])) + index;
+  } else if (index == arr.length - 1) {
+    minIndex = arr.length - 2;
+    maxIndex = arr.length - 1;
+  } else {
+    minIndex = index - 1;
+    maxIndex = index;
+  }
+  let min = arr[minIndex];
+  let max = arr[maxIndex];
+  let radio = Math.abs((num - min) / (max - min)) + index;
+  return radio;
+};
+/**
+ * 设置图片
+ * @param images
+ * @param worksheet
+ * @param workbook
+ */
+var setImages = function (table, worksheet, workbook) {
+  let {
+    images,
+    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 imageId = workbook.addImage({
+      base64: myBase64Image,
+      //extension: 'png',
+    });
+    worksheet.addImage(imageId, {
+      tl: tl,
+      ext: ext,
+    });
+  }
+};
+
+/**
+ * 冻结行列
+ * @param frozen
+ * @param worksheet
+ */
+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;
+      worksheet.views = [{ state: "frozen", xSplit: column, ySplit: row }];
+    }
+  }
+};
+
+/**
+ * 行隐藏
+ * @param rowhidden
+ * @param worksheet
+ */
+var setRowHidden = function (rowhidden = {}, worksheet) {
+  for (const key in rowhidden) {
+    //如果当前行没有内容则隐藏不生效
+    const row = worksheet.getRow(parseInt(key) + 1);
+    row.hidden = true;
+  }
+};
+
+/**
+ * 列隐藏
+ * @param colhidden
+ * @param worksheet
+ */
+var setColHidden = function (colhidden = {}, worksheet) {
+  for (const key in colhidden) {
+    const column = worksheet.getColumn(parseInt(key) + 1);
+    column.hidden = true;
+  }
+};
+
+/**
+ * 自动筛选器
+ * @param filter
+ * @param worksheet
+ */
+var setFilter = function (filter = {}, worksheet) {
+  if (Object.keys(filter).length === 0) return;
+  const from = {
+    row: filter.row[0] + 1,
+    column: filter.column[0] + 1,
+  };
+
+  const to = {
+    row: filter.row[1] + 1,
+    column: filter.column[1] + 1,
+  };
+
+  worksheet.autoFilter = {
+    from: from,
+    to: to,
+  };
+};
+
+/*var fillConvert = function (bg) {
+  if (!bg) {
+    return {}
+  }
+  // const bgc = bg.replace('#', '')
+  let fill = {
+    type: 'pattern',
+    pattern: 'solid',
+    fgColor: {argb: bg.startsWith("#") ? bg.replace('#', '') : colorRGBtoHex(bg).replace("#", "")},
+  }
+  return fill;
+}
+
+var 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: '微软雅黑',
+    1: '宋体(Song)',
+    2: '黑体(ST Heiti)',
+    3: '楷体(ST Kaiti)',
+    4: '仿宋(ST FangSong)',
+    5: '新宋体(ST Song)',
+    6: '华文新魏',
+    7: '华文行楷',
+    8: '华文隶书',
+    9: 'Arial',
+    10: 'Times New Roman ',
+    11: 'Tahoma ',
+    12: 'Verdana',
+    num2bl: function (num) {
+      return num !== 0
+    }
+  }
+  // 出现Bug,导入的时候ff为luckyToExcel的val
+
+  let font = {
+    name: typeof ff === 'number' ? luckyToExcel[ff] : ff,
+    family: 1,
+    size: fs,
+    color: {argb: fc.startsWith("#") ? fc.replace('#', '') : colorRGBtoHex(fc).replace("#", "")},
+    bold: luckyToExcel.num2bl(bl),
+    italic: luckyToExcel.num2bl(it),
+    underline: luckyToExcel.num2bl(ul),
+    strike: luckyToExcel.num2bl(cl)
+  }
+
+  return font
+}*/
 
 var fillConvert = function (bg) {
   if (!bg) {
@@ -191,7 +693,6 @@ var fontConvert = function (
 
   return font;
 };
-
 var alignmentConvert = function (
   vt = "default",
   ht = "default",
@@ -204,13 +705,13 @@ var alignmentConvert = function (
       0: "middle",
       1: "top",
       2: "bottom",
-      default: "top",
+      default: "middle",
     },
     horizontal: {
       0: "center",
       1: "left",
       2: "right",
-      default: "left",
+      default: "center",
     },
     wrapText: {
       0: false,
@@ -250,6 +751,11 @@ var borderConvert = function (borderType, style = 1, color = "#000") {
       "border-right": "right",
       "border-bottom": "bottom",
       "border-left": "left",
+      "border-outside": "outside",
+      "border-inside": "inside",
+      "border-horizontal": "horizontal",
+      "border-vertical": "vertical",
+      "border-none": "none",
     },
     style: {
       0: "none",
@@ -268,20 +774,11 @@ var borderConvert = function (borderType, style = 1, color = "#000") {
       13: "thick",
     },
   };
-  let template = {
+  let border = {};
+  border[luckyToExcel.type[borderType]] = {
     style: luckyToExcel.style[style],
     color: { argb: color.replace("#", "") },
   };
-  let border = {};
-  if (luckyToExcel.type[borderType] === "all") {
-    border["top"] = template;
-    border["right"] = template;
-    border["bottom"] = template;
-    border["left"] = template;
-  } else {
-    border[luckyToExcel.type[borderType]] = template;
-  }
-  // console.log('border', border)
   return border;
 };
 
@@ -344,4 +841,13 @@ function createCellPos(n) {
   return s;
 }
 
+//rgb(255,255,255)转16进制 #ffffff
+function colorRGBtoHex(color) {
+  color = color.replace("rgb", "").replace("(", "").replace(")", "");
+  var rgb = color.split(",");
+  var r = parseInt(rgb[0]);
+  var g = parseInt(rgb[1]);
+  var b = parseInt(rgb[2]);
+  return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
+}
 export { exportExcel };