LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

【JavaScript】封装 x-spreadsheet 带样式导入导出

admin
2024年6月12日 12:13 本文热度 1333

vue 下使用 exceljs + x-spreadsheet 带样式导入Excel

vue 下使用 exceljs + x-spreadsheet 带样式导出Excel

下面封装好一个组件:

<template>

  <div ref="sheetContainer" v-bind:id="sheetContainerId" class="grid"></div>

</template>


<script>

import Spreadsheet from "x-data-spreadsheet";

import zhCN from "x-data-spreadsheet/src/locale/zh-cn";

import _ from "lodash";

import * as Excel from "exceljs/dist/exceljs";

import * as tinycolor from "tinycolor2";

import { Guid } from "js-guid";

export default {

  name: "xspreadsheet",

  props: {

    ColumnCount: {

      type: Number,

      default: () => 50,

    },

    ColumnWidth: {

      type: Number,

      default: () => 100,

    },

    RowCount: {

      type: Number,

      default: () => 9999,

    },

    SheetName: {

      type: String,

      default: () => [],

    },

    Headers: {

      type: Array,

      default: () => [],

    },

    Records: {

      type: Array,

      default: () => [],

    },

    /*表头样式*/

    HeaderStyle: {

      type: Object,

      default: () => {

        return {

          //bgcolor: "#f4f5f8",

          textwrap: true,

          color: "#900b09",

          align: "center",

          valign: "middle",

          border: {

            top: ["thin", "#1E1E1E"],

            bottom: ["thin", "#1E1E1E"],

            right: ["thin", "#1E1E1E"],

            left: ["thin", "#1E1E1E"],

          },

          font: {

            bold: true,

          },

        };

      },

    },

    /*表体样式*/

    RecordStyle: {

      type: Object,

      default: () => {

        return {

          //bgcolor: "#f4f5f8",

          textwrap: true,

          color: "#900b09",

          align: "left",

          valign: "middle",

          border: {

            top: ["thin", "#1E1E1E"],

            bottom: ["thin", "#1E1E1E"],

            right: ["thin", "#1E1E1E"],

            left: ["thin", "#1E1E1E"],

          },

          font: {

            bold: false,

          },

        };

      },

    },

    File: {

      type: null,

      default: () => null,

    },

    ExportJsonProperties: {

      type: Array,

      default: () => [],

    },

  },

  data() {

    return {

      xs: null,

      sheetContainerId: Guid.newGuid().toString(),

      DataSource: []

    };

  },

  mounted() {

    this.$nextTick(() => {

      this.init();

    });

  },

  watch: {

    File: {

      handler(newV, oldV) {

        this.$nextTick(() => {

          this.loadExcelFile(newV);

        });

      },

    },

    Headers: {

      deep: true,

      handler(newV) {

        let result = [];

        if (Array.isArray(newV) && newV.length > 0) {

          let headerRow = { cells: [] };

          for (let i = 0; i < newV.length; i++) {

            headerRow.cells.push({

              text: newV[i],

              editable: false,

              style: 0,

            });

          }

          result.push(headerRow);

        }

        if (Array.isArray(this.Records) && this.Records.length > 0) {

          for (let i = 0; i < this.Records.length; i++) {

            let recordRow = { cells: [] };

            if (JSON.stringify(this.Records[i]) != "{}") {

              for(let k=0; k < this.ExportJsonProperties.length; k++) {

                recordRow.cells.push({

                  text: this.Records[i][this.ExportJsonProperties[k]] + "",

                  editable: true,

                  style: 1,

                });

              }

            } else {

              for (let i = 0; i < this.ColumnCount; i++) {

                recordRow.cells.push({

                  text: "",

                  editable: true,

                  style: 1,

                });

              }

            }

            result.push(recordRow);

          }

        }

        this.DataSource = result;

      },

    },

    Records: {

      deep: true,

      handler(newV) {

        let result = [];

        if (Array.isArray(this.Headers) && this.Headers.length > 0) {

          let headerRow = { cells: [] };

          for (let i = 0; i < this.Headers.length; i++) {

            headerRow.cells.push({

              text: this.Headers[i],

              editable: false,

              style: 0,

            });

          }

          result.push(headerRow);

        }

        if (Array.isArray(newV) && newV.length > 0) {

          for (let i = 0; i < newV.length; i++) {

            let recordRow = { cells: [] };

            if (JSON.stringify(newV[i]) != "{}") {

              for(let k=0; k < this.ExportJsonProperties.length; k++) {

                recordRow.cells.push({

                  text: newV[i][this.ExportJsonProperties[k]] + "",

                  editable: true,

                  style: 1,

                });

              }

            } else {

              for (let i = 0; i < this.ColumnCount; i++) {

                recordRow.cells.push({

                  text: "",

                  editable: true,

                  style: 1,

                });

              }

            }

            result.push(recordRow);

          }

        }

        this.DataSource = result;

      }

    },

    DataSource : {

      deep : true,

      handler(newW) {

        if (this.xs) {

          console.log(newW)

          this.xs.loadData([

            {

              name: this.SheetName,

              styles: [this.HeaderStyle, this.RecordStyle],

              rows: newW,

            },

          ]);

        }

      }

    }

  },

  methods: {

    // 初始化表格

    init() {

      if (

        this.$refs.sheetContainer &&

        this.$refs.sheetContainer.offsetHeight &&

        this.$refs.sheetContainer.offsetWidth

      ) {

        //设置中文

        Spreadsheet.locale("zh-cn", zhCN);

        this.xs = new Spreadsheet(

          document.getElementById(this.sheetContainerId),

          {

            mode: "edit",

            showToolbar: true,

            showGrid: true,

            showContextmenu: true,

            showBottomBar: true,

            view: {

              height: () =>

                this.$refs.sheetContainer &&

                this.$refs.sheetContainer.offsetHeight &&

                _.isNumber(this.$refs.sheetContainer.offsetHeight)

                  ? this.$refs.sheetContainer.offsetHeight

                  : 0,

              width: () =>

                this.$refs.sheetContainer &&

                this.$refs.sheetContainer.offsetWidth &&

                _.isNumber(this.$refs.sheetContainer.offsetWidth)

                  ? this.$refs.sheetContainer.offsetWidth

                  : 0,

            },

            formats: [],

            fonts: [],

            formula: [],

            row: {

              len: this.RowCount,

              height: 25,

            },

            col: {

              len: this.ColumnCount,

              width: this.ColumnWidth,

              indexWidth: 60,

              minWidth: 60,

            },

          }

        );

        this.loadData();

      }

    },

    loadData() {

      if (this.xs) {

        this.xs.loadData([

          {

            name: this.SheetName,

            styles: [this.HeaderStyle, this.RecordStyle],

            rows: this.DataSource,

          },

        ]);

      }

    },

    // 导入excel

    loadExcelFile(file) {

      if (file) {

        const wb = new Excel.Workbook();

        const reader = new FileReader();

        reader.readAsArrayBuffer(file);

        reader.onload = () => {

          const buffer = reader.result;

          // 微软的 Excel ColorIndex 一个索引数字对应一个颜色

          const indexedColors = [

            "000000",

            "FFFFFF",

            "FF0000",

            "00FF00",

            "0000FF",

            "FFFF00",

            "FF00FF",

            "00FFFF",

            "000000",

            "FFFFFF",

            "FF0000",

            "00FF00",

            "0000FF",

            "FFFF00",

            "FF00FF",

            "00FFFF",

            "800000",

            "008000",

            "000080",

            "808000",

            "800080",

            "008080",

            "C0C0C0",

            "808080",

            "9999FF",

            "993366",

            "FFFFCC",

            "CCFFFF",

            "660066",

            "FF8080",

            "0066CC",

            "CCCCFF",

            "000080",

            "FF00FF",

            "FFFF00",

            "00FFFF",

            "800080",

            "800000",

            "008080",

            "0000FF",

            "00CCFF",

            "CCFFFF",

            "CCFFCC",

            "FFFF99",

            "99CCFF",

            "FF99CC",

            "CC99FF",

            "FFCC99",

            "3366FF",

            "33CCCC",

            "99CC00",

            "FFCC00",

            "FF9900",

            "FF6600",

            "666699",

            "969696",

            "003366",

            "339966",

            "003300",

            "333300",

            "993300",

            "993366",

            "333399",

            "333333",

          ];

          wb.xlsx.load(buffer).then((workbook) => {

            let workbookData = [];

            workbook.eachSheet((sheet, sheetIndex) => {

              // 构造x-data-spreadsheet 的 sheet 数据源结构

              let sheetData = {

                name: sheet.name,

                styles: [],

                rows: {},

                merges: [],

              };

              // 收集合并单元格信息

              let mergeAddressData = [];

              for (let mergeRange in sheet._merges) {

                sheetData.merges.push(sheet._merges[mergeRange].shortRange);

                let mergeAddress = {};

                // 合并单元格起始地址

                mergeAddress.startAddress = sheet._merges[mergeRange].tl;

                // 合并单元格终止地址

                mergeAddress.endAddress = sheet._merges[mergeRange].br;

                // Y轴方向跨度

                mergeAddress.YRange =

                  sheet._merges[mergeRange].model.bottom -

                  sheet._merges[mergeRange].model.top;

                // X轴方向跨度

                mergeAddress.XRange =

                  sheet._merges[mergeRange].model.right -

                  sheet._merges[mergeRange].model.left;

                mergeAddressData.push(mergeAddress);

              }

              sheetData.cols = {};

              for (let i = 0; i < sheet.columns.length; i++) {

                sheetData.cols[i.toString()] = {};

                if (sheet.columns[i].width) {

                  // 不知道为什么从 exceljs 读取的宽度显示到 x-data-spreadsheet 特别小, 这里乘以8

                  sheetData.cols[i.toString()].width =

                    sheet.columns[i].width * 8;

                } else {

                  // 默认列宽

                  sheetData.cols[i.toString()].width = 100;

                }

              }

 

              // 遍历行

              sheet.eachRow((row, rowIndex) => {

                sheetData.rows[(rowIndex - 1).toString()] = { cells: {} };

                //includeEmpty = false 不包含空白单元格

                row.eachCell(

                  { includeEmpty: true },

                  function (cell, colNumber) {

                    let cellText = "";

                    if (cell.value && cell.value.result) {

                      // Excel 单元格有公式

                      cellText = cell.value.result;

                    } else if (cell.value && cell.value.richText) {

                      // Excel 单元格是多行文本

                      for (let text in cell.value.richText) {

                        // 多行文本做累加

                        cellText += cell.value.richText[text].text;

                      }

                    } else {

                      // Excel 单元格无公式

                      cellText = cell.value;

                    }

 

                    //解析单元格,包含样式

                    //*********************单元格存在背景色******************************

                    // 单元格存在背景色

                    let backGroundColor = null;

                    if (

                      cell.style.fill &&

                      cell.style.fill.fgColor &&

                      cell.style.fill.fgColor.argb

                    ) {

                      // 8位字符颜色先转rgb再转16进制颜色

                      backGroundColor = ((val) => {

                        val = val.trim().toLowerCase(); //去掉前后空格

                        let color = {};

                        try {

                          let argb =

                            /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(

                              val

                            );

                          color.r = parseInt(argb[2], 16);

                          color.g = parseInt(argb[3], 16);

                          color.b = parseInt(argb[4], 16);

                          color.a = parseInt(argb[1], 16) / 255;

                          return tinycolor(

                            `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`

                          ).toHexString();

                        } catch (e) {

                          console.log(e);

                        }

                      })(cell.style.fill.fgColor.argb);

                    }

 

                    if (backGroundColor) {

                      cell.style.bgcolor = backGroundColor;

                    }

                    //*************************************************************************** */

 

                    //*********************字体存在背景色******************************

                    // 字体颜色

                    let fontColor = null;

                    if (

                      cell.style.font &&

                      cell.style.font.color &&

                      cell.style.font.color.argb

                    ) {

                      // 8位字符颜色先转rgb再转16进制颜色

                      fontColor = ((val) => {

                        val = val.trim().toLowerCase(); //去掉前后空格

                        let color = {};

                        try {

                          let argb =

                            /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(

                              val

                            );

                          color.r = parseInt(argb[2], 16);

                          color.g = parseInt(argb[3], 16);

                          color.b = parseInt(argb[4], 16);

                          color.a = parseInt(argb[1], 16) / 255;

                          return tinycolor(

                            `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`

                          ).toHexString();

                        } catch (e) {

                          console.log(e);

                        }

                      })(cell.style.font.color.argb);

                    }

                    if (fontColor) {

                      //console.log(fontColor)

                      cell.style.color = fontColor;

                    }

                    //************************************************************************ */

 

                    // exceljs 对齐的格式转成 x-date-spreedsheet 能识别的对齐格式

                    if (

                      cell.style.alignment &&

                      cell.style.alignment.horizontal

                    ) {

                      cell.style.align = cell.style.alignment.horizontal;

                      cell.style.valign = cell.style.alignment.vertical;

                    }

 

                    //处理合并单元格

                    let mergeAddress = _.find(mergeAddressData, function (o) {

                      return o.startAddress == cell._address;

                    });

                    if (mergeAddress) {

                      // 遍历的单元格属于合并单元格

                      if (cell.master.address != mergeAddress.startAddress) {

                        // 不是合并单元格中的第一个单元格不需要计入数据源

                        return;

                      }

                      // 说明是合并单元格区域的起始单元格

                      sheetData.rows[(rowIndex - 1).toString()].cells[

                        (colNumber - 1).toString()

                      ] = {

                        text: cellText,

                        style: 0,

                        merge: [mergeAddress.YRange, mergeAddress.XRange],

                      };

 

                      //解析单元格,包含样式

                      let xsCellStyle = _.cloneDeep(cell.style);

                      xsCellStyle.border = {};

                      // 边框线

                      if (

                        cell.style.border &&

                        JSON.stringify(cell.style.border) != "{}"

                      ) {

                        let coloneStyle = cell.style.border;

                        xsCellStyle.border = {};

                        if (coloneStyle.bottom) {

                          xsCellStyle.border.bottom = [];

                          xsCellStyle.border.bottom[0] =

                            coloneStyle.bottom.style;

                          if (_.isString(coloneStyle.bottom.color)) {

                            xsCellStyle.border.bottom[1] =

                              coloneStyle.bottom.color;

                          } else {

                            xsCellStyle.border.bottom[1] = "#000000";

                          }

                        }

                        if (coloneStyle.right) {

                          xsCellStyle.border.right = [];

                          xsCellStyle.border.right[0] = coloneStyle.right.style;

                          if (_.isString(coloneStyle.right.color)) {

                            xsCellStyle.border.right[1] =

                              coloneStyle.right.color;

                          } else {

                            xsCellStyle.border.right[1] = "#000000";

                          }

                        }

                        if (coloneStyle.left) {

                          xsCellStyle.border.left = [];

                          xsCellStyle.border.left[0] = coloneStyle.left.style;

                          if (_.isString(coloneStyle.left.color)) {

                            xsCellStyle.border.left[1] = coloneStyle.left.color;

                          } else {

                            xsCellStyle.border.left[1] = "#000000";

                          }

                        }

                        if (coloneStyle.top) {

                          xsCellStyle.border.top = [];

                          xsCellStyle.border.top[0] = coloneStyle.top.style;

                          if (_.isString(coloneStyle.top.color)) {

                            xsCellStyle.border.top[1] = coloneStyle.top.color;

                          } else {

                            xsCellStyle.border.top[1] = "#000000";

                          }

                        }

                      }

 

                      sheetData.styles.push(xsCellStyle);

                      //对应的style存放序号

                      sheetData.rows[(rowIndex - 1).toString()].cells[

                        (colNumber - 1).toString()

                      ].style = sheetData.styles.length - 1;

                    } else {

                      // 非合并单元格

                      sheetData.rows[(rowIndex - 1).toString()].cells[

                        (colNumber - 1).toString()

                      ] = { text: cellText, style: 0 };

                      //解析单元格,包含样式

                      let xsCellStyle = _.cloneDeep(cell.style);

                      xsCellStyle.border = {};

 

                      // 边框线

                      if (

                        cell.style.border &&

                        JSON.stringify(cell.style.border) != "{}"

                      ) {

                        let coloneStyle = cell.style.border;

                        xsCellStyle.border = {};

                        if (coloneStyle.bottom) {

                          xsCellStyle.border.bottom = [];

                          xsCellStyle.border.bottom[0] =

                            coloneStyle.bottom.style;

                          if (_.isString(coloneStyle.bottom.color)) {

                            xsCellStyle.border.bottom[1] =

                              coloneStyle.bottom.color;

                          } else {

                            xsCellStyle.border.bottom[1] = "#000000";

                          }

                        }

                        if (coloneStyle.right) {

                          xsCellStyle.border.right = [];

                          xsCellStyle.border.right[0] = coloneStyle.right.style;

                          if (_.isString(coloneStyle.right.color)) {

                            xsCellStyle.border.right[1] =

                              coloneStyle.right.color;

                          } else {

                            xsCellStyle.border.right[1] = "#000000";

                          }

                        }

                        if (coloneStyle.left) {

                          xsCellStyle.border.left = [];

                          xsCellStyle.border.left[0] = coloneStyle.left.style;

                          if (_.isString(coloneStyle.left.color)) {

                            xsCellStyle.border.left[1] = coloneStyle.left.color;

                          } else {

                            xsCellStyle.border.left[1] = "#000000";

                          }

                        }

                        if (coloneStyle.top) {

                          xsCellStyle.border.top = [];

                          xsCellStyle.border.top[0] = coloneStyle.top.style;

                          if (_.isString(coloneStyle.top.color)) {

                            xsCellStyle.border.top[1] = coloneStyle.top.color;

                          } else {

                            xsCellStyle.border.top[1] = "#000000";

                          }

                        }

                      }

 

                      sheetData.styles.push(xsCellStyle);

                      //对应的style存放序号

                      sheetData.rows[(rowIndex - 1).toString()].cells[

                        (colNumber - 1).toString()

                      ].style = sheetData.styles.length - 1;

                    }

                  }

                );

              });

              workbookData.push(sheetData);

            });

            this.xs.loadData(workbookData);

          });

        };

      }

    },

    // 导出excel

    exportExcel(fileName) {

      const exceljsWorkbook = new Excel.Workbook();

      exceljsWorkbook.modified = new Date();

      this.xs.getData().forEach(function (xws) {

        let rowobj = xws.rows;

        // 构造exceljs文档结构

        const exceljsSheet = exceljsWorkbook.addWorksheet(xws.name);

        // 读取列宽

        let sheetColumns = [];

        let colIndex = 0;

        for (let col in xws.cols) {

          if (xws.cols[col].width) {

            sheetColumns.push({

              header: colIndex + "",

              key: colIndex + "",

              width: xws.cols[col].width / 8,

            });

          }

          colIndex++;

        }

        exceljsSheet.columns = sheetColumns;

        for (let ri = 0; ri < rowobj.len; ++ri) {

          let row = rowobj[ri];

          if (!row) continue;

          // 构造exceljs的行(如果尚不存在,则将返回一个新的空对象)

          const exceljsRow = exceljsSheet.getRow(ri + 1);

          Object.keys(row.cells).forEach(function (k) {

            let idx = +k;

            if (isNaN(idx)) return;

            const exceljsCell = exceljsRow.getCell(Number(k) + 1);

            exceljsCell.value = row.cells[k].text;

            

            if (

              xws.styles[row.cells[k].style]

            ) {

              // 垂直对齐方式

              if (xws.styles[row.cells[k].style].valign) {

                if (

                  exceljsCell.alignment == undefined ||

                  exceljsCell.alignment == null

                ) {

                  exceljsCell.alignment = {};

                }

                exceljsCell.alignment.vertical = 

                  xws.styles[row.cells[k].style].valign;

              }

              // 水平对齐方式

              if (xws.styles[row.cells[k].style].align) {

                if (

                  exceljsCell.alignment == undefined ||

                  exceljsCell.alignment == null

                ) {

                  exceljsCell.alignment = {};

                }

                exceljsCell.alignment.horizontal =

                  xws.styles[row.cells[k].style].align;

                }

              // exceljsSheet.getCell(exceljsCell._address).alignment = { vertical: xws.styles[row.cells[k].style].valign, horizontal: xws.styles[row.cells[k].style].align }

            }

 

            // 边框

            if (

              JSON.stringify(xws.styles[row.cells[k].style]) != "{}" &&

              JSON.stringify(xws.styles[row.cells[k].style].border) != "{}"

            ) {

              //exceljsCell.border = xws.styles[row.cells[k].style].border;

              exceljsCell.border = {};

              // bottom

              if (

                xws.styles[row.cells[k].style].border.bottom &&

                Array.isArray(xws.styles[row.cells[k].style].border.bottom) &&

                xws.styles[row.cells[k].style].border.bottom.length == 2

              ) {

                exceljsCell.border.bottom = {};

                exceljsCell.border.bottom.style =

                  xws.styles[row.cells[k].style].border.bottom[0];

                exceljsCell.border.bottom.color = {};

                //exceljsCell.border.bottom.color.indexed = 64

                exceljsCell.border.bottom.color =

                  xws.styles[row.cells[k].style].border.bottom[1];

              }

              // left

              if (

                xws.styles[row.cells[k].style].border.left &&

                Array.isArray(xws.styles[row.cells[k].style].border.left) &&

                xws.styles[row.cells[k].style].border.left.length == 2

              ) {

                exceljsCell.border.left = {};

                exceljsCell.border.left.style =

                  xws.styles[row.cells[k].style].border.left[0];

                exceljsCell.border.left.color = {};

                //exceljsCell.border.left.color.indexed = 64

                exceljsCell.border.left.color =

                  xws.styles[row.cells[k].style].border.left[1];

              }

              // right

              if (

                xws.styles[row.cells[k].style].border.right &&

                Array.isArray(xws.styles[row.cells[k].style].border.right) &&

                xws.styles[row.cells[k].style].border.right.length == 2

              ) {

                exceljsCell.border.right = {};

                exceljsCell.border.right.style =

                  xws.styles[row.cells[k].style].border.right[0];

                exceljsCell.border.right.color = {};

                //exceljsCell.border.right.color.indexed = 64

                exceljsCell.border.right.color =

                  xws.styles[row.cells[k].style].border.right[1];

              }

              // top

              if (

                xws.styles[row.cells[k].style].border.top &&

                Array.isArray(xws.styles[row.cells[k].style].border.top) &&

                xws.styles[row.cells[k].style].border.top.length == 2

              ) {

                exceljsCell.border.top = {};

                exceljsCell.border.top.style =

                  xws.styles[row.cells[k].style].border.top[0];

                exceljsCell.border.top.color = {};

                //exceljsCell.border.right.color.indexed = 64

                exceljsCell.border.top.color =

                  xws.styles[row.cells[k].style].border.top[1];

              }

            }

 

            // 背景色

            if (xws.styles[row.cells[k].style].bgcolor) {

              let rgb = tinycolor(

                xws.styles[row.cells[k].style].bgcolor

              ).toRgb();

              let rHex = parseInt(rgb.r).toString(16).padStart(2, "0");

              let gHex = parseInt(rgb.g).toString(16).padStart(2, "0");

              let bHex = parseInt(rgb.b).toString(16).padStart(2, "0");

              let aHex = parseInt(rgb.a).toString(16).padStart(2, "0");

              let _bgColor = aHex + rHex + gHex + bHex;

              // 设置exceljs背景色

              exceljsCell.fill = {

                type: "pattern",

                pattern: "solid",

                fgColor: { argb: _bgColor },

              };

            }

            // 字体

            exceljsCell.font = xws.styles[row.cells[k].style].font;

            // 字体颜色

            if (xws.styles[row.cells[k].style].color) {

              let rgb = tinycolor(xws.styles[row.cells[k].style].color).toRgb();

              let rHex = parseInt(rgb.r).toString(16).padStart(2, "0");

              let gHex = parseInt(rgb.g).toString(16).padStart(2, "0");

              let bHex = parseInt(rgb.b).toString(16).padStart(2, "0");

              let aHex = parseInt(rgb.a).toString(16).padStart(2, "0");

              let _fontColor = aHex + rHex + gHex + bHex;

              exceljsCell.font.color = { argb: _fontColor };

            }

            // 合并单元格

            if (row.cells[k].merge) {

              // 开始行

              let startRow = ri + 1;

              // 结束行,加上Y轴跨度

              let endRow = startRow + row.cells[k].merge[0];

              // 开始列

              let startColumn = Number(k) + 1;

              // 结束列,加上X轴跨度

              let endColumn = startColumn + row.cells[k].merge[1];

              // 按开始行,开始列,结束行,结束列合并

              exceljsSheet.mergeCells(startRow, startColumn, endRow, endColumn);

            }

          });

        }

      });

      // writeBuffer 把写好的excel 转换成 ArrayBuffer 类型

      exceljsWorkbook.xlsx.writeBuffer().then((data) => {

        const link = document.createElement("a");

        // Blob 实现下载excel

        const blob = new Blob([data], {

          type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8",

        });

        link.href = window.URL.createObjectURL(blob);

        link.download = `${fileName}.xlsx`;

        link.click();

      });

    },

    // 导出json

    exportJson() {

      let sheetsData = this.xs.getData();

      let rows = Object.entries(sheetsData[0].rows);

      let jsonData = [];

      if (Array.isArray(this.ExportJsonProperties) && this.ExportJsonProperties.length > 0) {

        // 遍历数据,跳过第一行表头

        for (let i = 1; i < rows.length; i++) {

          if (rows[i] && rows[i][1] && rows[i][1].cells) {

            let row = Object.entries(rows[i][1].cells);

            // 构造行对象

            let JsonRow = {};

            for (let k = 0; k < row.length; k++) {

              let cells = row[k];

              JsonRow[this.ExportJsonProperties[k]] = cells[1].text;

            }

            jsonData.push(JsonRow);

          }

        }

      }

      return jsonData;

    },

  },

  destroyed() {},

};

</script>

<style>

</style>

调用组件的页面:

<template>

  <div>

    <div>

      <input

        type="file"

       

        @change="loadExcelFile"

        accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"

      />

      <el-button @click="exportJson">导出JSON</el-button>

      <el-button @click="exportExcel">导出xlsx</el-button>

    </div>

    <Sheet ref="Sheet" SheetName="调配订单变量" :ExportJsonProperties="JsonProperties" :File="file" :Headers="headers" :ColumnCount="headers.length" :ColumnWidth="300" :RowCount="records.length + 1" :Records="records"></Sheet>

  </div>

</template>

 

<script>

import Sheet from "@/components/SpreadSheet.vue";

export default {

  components: { Sheet },

  data() {

    return {

      file : null,

      headers : ['序号','订单号','产品名称','订单状态','计划生产数量','实际生产数量','单位','计划开始时间','计划结束时间','调配罐',

      'TK101出油比率','TK101出油数量',

      'TK102出油比率','TK102出油数量',

      'TK103出油比率','TK103出油数量',

      'TK104出油比率','TK104出油数量',

      'TK108出油比率','TK108出油数量',

      'TK109出油比率','TK109出油数量',

      '添加剂1','添加剂2'],

      records: [{},{},{},{},{},{},{},{},{},{},],

      // 定义导出的Json结构

      JsonProperties: [

        'Index',

        'OrderNo',

        'ProductName',

        'ProductStatus',

        'PlanQuantity',

        'RealQuantity',

        'Unit',

        'StartDate',

        'EndDate',

        'MixTank',

        'TK101Rate',

        'TK101Quantity',

        'TK102Rate',

        'TK102Quantity',

        'TK103Rate',

        'TK103Quantity',

        'TK104Rate',

        'TK104Quantity',

        'TK108Rate',

        'TK108Quantity',

        'TK109Rate',

        'TK109Quantity',

        'Additive1',

        'Additive2'

      ]

    }

  },

  mounted() {},

  methods: {

    loadExcelFile(e) {

      this.file = e.target.files[0]

    },

    exportJson() {

      let json = this.$refs.Sheet.exportJson()

      console.log(json)

    },

    exportExcel() {

      this.$refs.Sheet.exportExcel('调配订单变量')

    },

  },

};

</script>

<style scoped>

.container {

  width: 100%;

  height: 100%;

  display: flex;

  flex-direction: column;

  .toolbar {

    width: 100%;

    height: 50px;

  }

  .grid {

    width: 100%;

    height: calc(100% - 80px);

  }

  /deep/ .x-spreadsheet-toolbar {

    padding: 0px;

    width: calc(100% - 2px) !important;

  }

}

.choose::-webkit-file-upload-button {

  color: white;

  display: inline-block;

  background: #409EFF;

  border: none;

  padding: 14px 20px;

  width: 100px;

  height: 40px;

  border-radius: 3px;

  white-space: nowrap;

  cursor: pointer;

 

}

</style>


该文章在 2024/6/12 12:17:48 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved