基于jeecg-boot集成luckysheet记录

news2024/11/28 11:32:16

1、放在public下面,开始用下面的,会报错,找不到相应的js文件,

<!-- luckysheet for bigscreen -->
  <link rel='stylesheet' href='./luckysheet/plugins/css/pluginsCss.css' />
  <link rel='stylesheet' href='./luckysheet/plugins/plugins.css' />
  <link rel='stylesheet' href='./luckysheet/css/luckysheet.css' />
  <script src="./luckysheet/plugins/js/plugin.js"></script>
  <script src="./luckysheet/luckysheet.umd.js"></script>

2、后来修改如下:

<!-- luckysheet for bigscreen -->
  <link rel='stylesheet' href='<%= BASE_URL %>luckysheet/plugins/css/pluginsCss.css' />
  <link rel='stylesheet' href='<%= BASE_URL %>luckysheet/plugins/plugins.css' />
  <link rel='stylesheet' href='<%= BASE_URL %>luckysheet/css/luckysheet.css' />
  <script src="<%= BASE_URL %>luckysheet/plugins/js/plugin.js"></script>
  <script src="<%= BASE_URL %>luckysheet/luckysheet.umd.js"></script>

3、上面好了后,出现下面问题

4、需要在luckysheet.umd.js  这个文件的引入chartmix进行修改,以后发布生产也要修改了,这个就比较麻烦了,以后生成还要修改成生产的,以后考虑从luckysheet源代码生成修改吧。

5、这样就正常了,可以进行图表的展示了,如下:

6、后来发现上面的保存与预览的图标没有显示,这个是iconfont方式,应该是没有引入对,后来检查了 检查了designer的index文件,正确引入下面文件就正常了

<style src="@/assets/bs/iconfont/iconfont.css" />

7、编辑连接数据集,如下图,不过有问题浏览器兼容性还没做好,我用qq浏览器就不行,不能拖拉进去,用谷歌与edge是都可以。

8、预览如下:

9、报表设计页面代码

<!--
 * @Author: lide1202@hotmail.com
 * @Date: 2021-3-13 11:04:24
 * @Last Modified by:   nbacheng
 * @Last Modified time: 2023-09-09
 !-->
<template>
  <div class="layout">
    <div class="layout-left">
      <div class="add-collection">
        数据集管理
        <el-button
          type="text"
          icon="el-icon-circle-plus-outline"
          @click="queryAllDataSet()"
        />
      </div>
      <div>
        <el-collapse
          v-for="(item, indexs) in dataSet"
          :key="indexs"
          v-model="activeNames"
          @change="handleChange"
        >
          <el-collapse-item :title="item.setName" :name="item.id">
            <el-popconfirm
              :title="'确定删除' + item.setName + '吗?'"
              @confirm="del(item)"
            >
              <el-button
                slot="reference"
                type="text"
                icon="el-icon-close"
                class="delect-all"
              />
            </el-popconfirm>
            <draggable
              v-model="item.setParamList"
              :sort="false"
              group="people"
              style="margin-left: 10px"
              @start="onStart(item.setCode, $event)"
            >
              <!-- <transition-group> -->
              <div
                v-for="(i, index) in item.setParamList"
                :key="index"
                class="field-container"
              >
                <div class="aRow">
                  <span>{{ i }}</span>
                </div>
              </div>
              <!-- </transition-group> -->
            </draggable>
          </el-collapse-item>
        </el-collapse>
      </div>
    </div>
    <div class="layout-middle">
      <div class="push_btn">
        <el-tooltip
          class="item"
          effect="dark"
          content="预览"
          placement="bottom-start"
        >
          <el-button type="text" @click="preview()">
            <i class="iconfont iconfuzhi"></i>
          </el-button>
        </el-tooltip>
        <el-tooltip
          class="item"
          effect="dark"
          content="保存"
          placement="bottom-start"
        >
          <el-button type="text" @click="save()">
            <i class="iconfont iconsave"></i>
          </el-button>
        </el-tooltip>
      </div>
      <div
        id="luckysheet"
        style="margin:0px;padding:0px;position:absolute;width:100%;height:95vh;left: 0px;top: 30px;bottom:0px;"
      />
      <div id="qrCode" ref="qrCodeDiv" />
      <img id="barCode" />
    </div>

    <div class="layout-right">
      <el-tabs v-model="activeName" @tab-click="handleClick">
        <el-tab-pane label="基础配置" name="first">
          <el-form ref="rightForm" :model="rightForm" label-width="70px">
            <el-form-item label="坐标">
              <el-input v-model="rightForm.coordinate" />
            </el-form-item>
            <el-form-item label="值">
              <el-input v-model="rightForm.value" />
            </el-form-item>
            <el-form-item label="自动扩展" v-if="rightForm.autoIsShow">
              <el-col :span="12">
                <el-switch
                v-model="rightForm.auto"
                @change="autoChangeFunc($event)" />
              </el-col>
              <el-col :span="12">
                <el-tooltip class="item" effect="dark" content="只针对静态数据的单元格,具体参考文档" placement="top">
                <i class="el-icon-question"> </i>
                </el-tooltip>
              </el-col>
            </el-form-item>
          </el-form>
        </el-tab-pane>
      </el-tabs>
    </div>

    <el-dialog title="数据集管理" :visible.sync="outerVisible">
      <el-table
        ref="multipleTable"
        :data="dataSetData"
        tooltip-effect="dark"
        style="width: 100%;height: 60vh;overflow-y: scroll;"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column label="数据集名称" width="120" prop="setName" />
        <el-table-column prop="setDesc" label="数据集描述" width="180" />
        <el-table-column
          prop="setCode"
          label="数据集编码"
          show-overflow-tooltip
        />
      </el-table>

      <div slot="footer" class="dialog-footer">
        <el-button @click="outerVisible = false">取 消</el-button>
        <el-button type="primary" @click="checkDataSet()">确定 </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import draggable from "vuedraggable";
import { queryAllDataSet, detail, detailByReportCode } from "@/api/bigscreen/excelreport";
import { addReportExcel, editReportExcel } from "@/api/bigscreen/excelreport";
import ColorPicker from "../components/colorPicker.vue";
// import QRCode from 'qrcodejs2'
// import JsBarcode from 'jsbarcode'
export default {
  name: "Excels",
  components: {
    draggable,
    ColorPicker
  },
  data() {
    return {
      activeName: "first",
      activeNames: ["1"],
      reportId: null,
      accessKey: null,
      reportCode: "",
      options: [],
      sheet: {},
      sheetData: [],
      dataSetData: [],
      reportExcelDto: {
        id: null,
        jsonStr: "",
        setCodes: "",
        setParam: "",
        reportCode: ""
      },
      multipleSelection: [],
      rightForm: {
        coordinate: "",
        value: "",
        r: "",
        c: "",
        auto: false,
        autoIsShow: false
      },
      qrCodeForm: {
        type: "QRCode",
        content: "https://www.baidu.com",
        width: 125,
        height: 125,
        colorDark: "#333333", // 二维码颜色
        colorLight: "#ffffff", // 二维码背景色
        // correctLevel: QRCode.CorrectLevel.L, // 容错率,L/M/H
        ri: 0,
        ci: 0,
        currentSrc: ""
      },
      barCodeForm: {
        type: "BarCode",
        format: "CODE39",
        displayValue: true,
        content: "99999999999",
        lineColor: "#000",
        background: "#fff",
        width: 100,
        height: 40,
        ri: 0,
        ci: 0,
        currentSrc: ""
      },
      formPrintSetting: {
        size: "",
        pixel1: "",
        pixel2: ""
      },
      pixelList: [
        { paper: "A4", width: 210, height: 297 },
        { paper: "A3", width: 297, height: 420 },
        { paper: "Letter", width: 216, height: 279 },
        { paper: "Legal", width: 216, height: 355 },
        { paper: "Executive", width: 184, height: 266 }
      ],
      dataSet: [],
      outerVisible: false,
      printVisible: false,
      pop: false,
      setCode: null,
      draggableFieldLabel: null,
      dialogVisible: false,
      dialogBarCode: false,
      paperList: [],
      // 纸张标识
      paper: "",
      // 纸张宽高
      width: "",
      height: "",
      // 清晰度
      definition: "",
      // 是否套打
      isBackend: "",
      dpi: "",
      pxWidth: "",
      pxHeight: "",
      show: false,
      config: "",
      settings: {},
      qrCodeList: [],
      moveDataelse: {
        x: null,
        y: null
      }
    };
  },
  mounted() {},
  created() {
    this.reportCode = this.$route.query.reportCode;
    this.accessKey = this.$route.query.accessKey;
    this.loadDataSet();
    this.design();
  },
  methods: {
    handleClose() {
      this.printVisible = false;
    },
    handleChange(val) {},
    // 右侧信息配置tabs
    handleClick(tab, event) {},
    async design() {
      // 根据reportCode获取单条报表
      const { code, result } = await detailByReportCode(this.reportCode);
      if (result != null) {
        this.reportId = result.id;
      }
      console.log("result=",result);
      console.log("this.sheetData=",this.sheetData);
      this.sheetData = result == null ? [{}] : JSON.parse(result.jsonStr);
      console.log("this.sheetData=",this.sheetData);
      this.createSheet();
      if (result != null) {
        if (result.setCodes != null && result.setCodes !== "") {
          let dataSetList = result.setCodes.split("|");
          dataSetList.forEach(code => {
            this.dataSetData.forEach(setData => {
              if (code === setData.setCode) {
                this.detail(setData.id);
              }
            });
          });
        }
      }
    },
    //初始化表格
    createSheet() {
      //将vue对象传入
      const that = this;
      const options = {
        container: "luckysheet", // 设定DOM容器的id
        title: "", // 设定表格名称
        lang: "zh", // 设定表格语言
        plugins: ["chart"],
        hook: {
          cellDragStop: function(cell, postion, sheetFile, ctx, event) {
            // console.info("cellDragStop-cell",cell);
            // console.info("cellDragStop-postion", postion);
            // console.info("cellDragStop-sheetFile", sheetFile);
            // console.info("cellDragStop-ctx",ctx);
            // console.info("cellDragStop-event", event);
            // console.log("cellDragStop-draggableFieldLabel", that);
            luckysheet.setCellValue(
              postion.r,
              postion.c,
              that.draggableFieldLabel
            );
          },
          cellMousedown: function(cell, postion, sheetFile, ctx) {

            //单元格点击事件
            that.rightForm.coordinate = postion.r + "," + postion.c;
            that.rightForm.r = postion.r;
            that.rightForm.c = postion.c;
            that.rightForm.value = cell == null ? "" : cell.v;
            that.rightForm.autoIsShow = true
            //判断单元格是否是静态数据并且是合并单元格
            if(cell != null && ( cell.v == undefined || cell.v.indexOf('#{') === -1)){
                that.rightForm.autoIsShow = true
                if(cell.auto != null && cell.auto == '1'){
                  that.rightForm.auto = true
                }else{
                  that.rightForm.auto = false
                }
            }else{
              that.rightForm.auto = false
            }
          }
        },
        data: [
          {
            name: "report", //工作表名称
            color: "", //工作表颜色
            index: 0, //工作表索引
            status: 1, //激活状态
            order: 0, //工作表的下标
            hide: 0, //是否隐藏
            row: 36, //行数
            column: 18, //列数
            defaultRowHeight: 19, //自定义行高
            defaultColWidth: 73, //自定义列宽
            celldata: [], //初始化使用的单元格数据
            config: {
              merge: {}, //合并单元格
              rowlen: {}, //表格行高
              columnlen: {}, //表格列宽
              rowhidden: {}, //隐藏行
              colhidden: {}, //隐藏列
              borderInfo: {}, //边框
              authority: {} //工作表保护
            },
            scrollLeft: 0, //左右滚动条位置
            scrollTop: 315, //上下滚动条位置
            luckysheet_select_save: [], //选中的区域
            calcChain: [], //公式链
            isPivotTable: false, //是否数据透视表
            pivotTable: {}, //数据透视表设置
            filter_select: {}, //筛选范围
            filter: null, //筛选配置
            luckysheet_alternateformat_save: [], //交替颜色
            luckysheet_alternateformat_save_modelCustom: [], //自定义交替颜色
            luckysheet_conditionformat_save: {}, //条件格式
            frozen: {}, //冻结行列配置
            chart: [], //图表配置
            zoomRatio: 1, // 缩放比例
            image: [], //图片
            showGridLines: 1, //是否显示网格线
            dataVerification: {} //数据验证配置
          }
        ]
      };
      options.data = this.sheetData;

      $(function() {
        luckysheet.create(options);
      });
    },
    onStart(setCode, evt) {
      this.setCode = setCode;
      let fieldLabel = evt.item.innerText; // 列名称
      this.draggableFieldLabel = "#{" + this.setCode + "." + fieldLabel + "}";
      console.log("evt", evt);
      console.log("draggableFieldLabel", this.draggableFieldLabel);
    },
    async loadDataSet() {
      const { code, result } = await queryAllDataSet();
      this.dataSetData = result;
      if (code != "200") return;
    },
    doCancel() {
      this.pop = false;
    },
    async save() {
      // console.log(luckysheet.toJson())
      // console.log(luckysheet.getAllSheets())
      // console.log(luckysheet.getSheetData(0))
      const jsonData = luckysheet.getAllSheets();
      for (let i = 0; i < jsonData.length; i++) {
        //清空data数据,以celldata数据为主
        jsonData[i]["data"] = [];
      }

      this.reportExcelDto.jsonStr = JSON.stringify(luckysheet.getAllSheets());
      let setCodeList = [];
      let setParams = {};
      this.dataSet.forEach(code => {
        setCodeList.push(code.setCode);
        if (
          code.dataSetParamDtoList != null &&
          code.dataSetParamDtoList.length > 0
        ) {
          let dataSetParam = {};
          code.dataSetParamDtoList.forEach(value => {
            dataSetParam[value.paramName] = value.sampleItem;
          });
          setParams[code.setCode] = dataSetParam;
        }
      });

      this.reportExcelDto.setParam = JSON.stringify(setParams);
      this.reportExcelDto.setCodes = setCodeList.join("|");
      this.reportExcelDto.reportCode = this.reportCode;
      if (this.reportId == null) {
        const { code } = await addReportExcel(this.reportExcelDto);
        if (code != "200") return;
        this.$message.success("保存成功");
      } else {
        this.reportExcelDto.id = this.reportId;
        const { code } = await editReportExcel(this.reportExcelDto);
        if (code != "200") return;
        this.$message.success("更新成功");
      }
    },

    async detailByReportCode(reportCode) {
      const { code, result } = await detailByReportCode(reportCode);
      if (result != null) {
        this.reportId = result.id;
      }
    },
    async preview() {
      let routeUrl = this.$router.resolve({
        path: "/excelreport/viewer",
        query: { reportCode: this.reportCode }
      });
      window.open(routeUrl.href, "_blank");
    },
    async queryAllDataSet() {
      this.outerVisible = true;
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    checkDataSet() {
      this.outerVisible = false;
      if (this.multipleSelection.length > 1) {
        this.$message({
          message: "一次最多勾选一个数据集",
          type: "warning"
        });
        this.outerVisible = true;
      } else {
        this.detail(this.multipleSelection[0].id);
      }
    },
    async detail(id) {
      const { code, result } = await detail(id);
      if (code != 200) return;
      let flag = true;
      this.dataSet.forEach(value => {
        if (value.setCode === result.setCode) {
          flag = false;
        }
      });
      if (flag) {
        this.dataSet.push(result);
      }
    },
    del(val) {
      for (let i = 0; i < this.dataSet.length; i++) {
        if (this.dataSet[i].setCode === val.setCode) {
          this.dataSet.splice(i, 1);
        }
      }
    },
    autoChangeFunc(auto){
      if(auto){
        luckysheet.setCellValue(this.rightForm.r, this.rightForm.c, { auto: "1"})
      }else{
        luckysheet.setCellValue(this.rightForm.r, this.rightForm.c, { auto: "0"})
      }
    }
  }
};
</script>

<style src="@/assets/bs/iconfont/iconfont.css" />
<style scoped lang="scss">
.position {
  position: absolute;
  z-index: 100;
}

#qrCode,
#barCode {
  display: none;
}

.yulancopy {
  font-size: 16px;
}

.baocun {
  font-size: 17px;
}

.el-collapse {
  position: relative;
  border-top: 0 solid #e6ebf5;
  border-bottom: 0 solid #e6ebf5;
}

.el-collapse-item__header {
  border-bottom: 0 solid #e6ebf5 !important;
}

.delect-all {
  position: absolute;
  top: 10px;
  right: 30px;
  color: #333;
}

.push_btn {
  position: absolute;
  z-index: 100;
  top: 5px;
  left: 3px;

  .iconfont {
    color: black;
  }
}

.add-collection {
  line-height: 30px;

  .el-button {
    font-size: 16px !important;
    vertical-align: middle;
    margin-left: 20px;
  }
}

.layout {
  display: block;
  position: relative;
  margin: 0;
  padding: 0;
  border: 1px solid #d7dde4;
}

.layout-left {
  display: block;
  position: absolute;
  padding: 20px;
  width: 230px;
  min-height: 99.98vh;
  border-right: 1px solid #eee;
  border-color: #e8eaec;
  background: #fff;
  border-radius: 4px;
  font-size: 14px;
  -webkit-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
  top: 0;
  left: 0;

  .field-container {
    display: block;
    position: relative;
    width: 100%;
    margin: 0;
    cursor: pointer;
    line-height: 30px;

    .aRow {
      padding: 0 10px;

      .operation {
        float: right;
        display: none;

        .el-button--text {
          color: #333 !important;
        }
      }

      &:hover {
        .operation {
          display: block;
        }

        background: #f7fafd;
      }
    }
  }
}

.layout-middle {
  display: block;
  position: absolute;
  left: 230px;
  right: 230px;
  width: calc(100% - 460px);
  margin: 0;
  padding: 0;

  .excel-designer {
    display: block;
    position: relative;
    margin: 0;
    padding: 0;
  }
}

.layout-right {
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  padding: 20px;
  width: 230px;
  min-height: 99.98vh;
  border-left: 1px solid #dcdee2;
  border-color: #e8eaec;
  background: #fff;
  border-radius: 4px;
  font-size: 14px;
  -webkit-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
}
</style>

10、viewer代码如下:

<!--
 * @Author: lide1202@hotmail.com
 * @Date: 2021-3-13 11:04:24
 * @Last Modified by:   nbacheng
 * @Last Modified time: 2023-09-09
 !-->
<template>
  <div class="layout">
    <div class="layout-right">
      <div class="block">
        <div class="download">
          <a v-if="reportCode != null" download="xxx.xlsx">
            <el-button type="text" @click="download('gaea_template_excel')">
              <i class="iconfont iconexcel"></i>导出excel
            </el-button>
          </a>
          <a v-if="reportCode != null" download="xxx.pdf">
            <el-button type="text" @click="download('gaea_template_pdf')">
              <i class="iconfont iconpdf"></i>导出pdf
            </el-button>
          </a>
        </div>
        <el-form class="">
          <h2>表格查询</h2>
          <div v-for="(item, num) in tableData2" :key="num + 'excel'">
            <h4>{{ item.name }}</h4>
            <div
              v-for="(son, y) in item.children"
              :key="y + 'excel2'"
              class="search_input"
            >
              <label>{{ son.name }}:</label>
              <el-input v-model="son.value" />
            </div>
          </div>
          <el-button style="width: 100%" @click="searchPreview">查询</el-button>
        </el-form>
        <!--<el-pagination :current-page="currentPage4" :page-sizes="[100, 200, 300, 400]" :page-size="100" layout="total, sizes, prev, pager, next, jumper" :total="400" @size-change="handleSizeChange" @current-change="handleCurrentChange" />-->
      </div>
    </div>
    <div class="layout-middle">
      <div
        id="luckysheet"
        style="margin:0px;padding:0px;position:absolute;width:100%;height:95vh;left: 0px;top: 30px;bottom:0px;"
      />
    </div>
  </div>
</template>

<script>
import { preview, exportExcel } from "@/api/bigscreen/excelreport";

export default {
  name: "Login",
  components: {},
  data() {
    return {
      options: {},
      sheet: {},
      reportId: null,
      reportCode: null,
      reportName: null,
      dataSet: null,
      tableData2: [],
      excelData: {},
      params: {
        reportCode: "",
        setParam: ""
      }
    };
  },
  mounted() {
    this.preview();
  },
  created() {
    this.reportCode = this.$route.query.reportCode;
  },
  methods: {
    async searchPreview() {
      const arr = this.toObject(this.tableData2);
      this.params.setParam = JSON.stringify(arr);
      //每次都重新加载需要改成刷新
      this.preview();
    },
    async preview() {
      this.excelData = {};
      this.params.reportCode = this.reportCode;
      const { code, result } = await preview(this.params);
      if (code != 200) return;
      this.reportName = JSON.parse(result.jsonStr).name;
      // 渲染查询表单
      this.params.setParam = JSON.parse(result.setParam);
      const extendArry = [];
      const extendObj = this.params.setParam;
      for (const i in extendObj) {
        const children = [];
        for (const y in extendObj[i]) {
          children.push({ name: y, value: extendObj[i][y] });
        }
        extendArry.push({ name: i, children: children });
      }
      this.tableData2 = extendArry;

      this.excelData = result.jsonStr;
      this.sheetData = result == null ? [{}] : JSON.parse(result.jsonStr);
      // console.log(this.excelData)
      // console.log(this.sheetData)
      this.createSheet();
    },
    async download(val) {
      if (val == "gaea_template_pdf") {
        this.$message("暂不支持pdf");
        return;
      }
      const result = {};
      result["reportCode"] = this.reportCode;
      result["setParam"] = JSON.stringify(this.params.setParam);
      if (val != "") {
        result["exportType"] = val;
      }
      const { code, message } = await exportExcel(result);
      if (code != 200) return;
      this.$message.success(message);
    },
    // 表单封装json
    toObject(val) {
      const objfirst = {};
      const objSecond = {};
      val.forEach(el => {
        el.name ? (objfirst[el.name] = el.children) : "";
      });
      for (const key in objfirst) {
        const newObj = {};
        objfirst[key].map(ev => {
          Object.assign(newObj, { [ev.name]: ev.value });
        });
        objSecond[key] = newObj;
      }
      return objSecond;
    },
    //初始化表格
    createSheet() {
      const options = {
        container: "luckysheet", // 设定DOM容器的id
        title: "", // 设定表格名称
        lang: "zh", // 设定表格语言
        plugins: ["chart"],
        data: [
          {
            name: "report", //工作表名称
            color: "", //工作表颜色
            index: 0, //工作表索引
            status: 1, //激活状态
            order: 0, //工作表的下标
            hide: 0, //是否隐藏
            row: 36, //行数
            column: 18, //列数
            defaultRowHeight: 19, //自定义行高
            defaultColWidth: 73, //自定义列宽
            celldata: [], //初始化使用的单元格数据
            config: {
              merge: {}, //合并单元格
              rowlen: {}, //表格行高
              columnlen: {}, //表格列宽
              rowhidden: {}, //隐藏行
              colhidden: {}, //隐藏列
              borderInfo: {}, //边框
              authority: {} //工作表保护
            },
            scrollLeft: 0, //左右滚动条位置
            scrollTop: 315, //上下滚动条位置
            luckysheet_select_save: [], //选中的区域
            calcChain: [], //公式链
            isPivotTable: false, //是否数据透视表
            pivotTable: {}, //数据透视表设置
            filter_select: {}, //筛选范围
            filter: null, //筛选配置
            luckysheet_alternateformat_save: [], //交替颜色
            luckysheet_alternateformat_save_modelCustom: [], //自定义交替颜色
            luckysheet_conditionformat_save: {}, //条件格式
            frozen: {}, //冻结行列配置
            chart: [], //图表配置
            zoomRatio: 1, // 缩放比例
            image: [], //图片
            showGridLines: 1, //是否显示网格线
            dataVerification: {} //数据验证配置
          }
        ]
      };
      options.data = this.sheetData;
      // console.log(this.sheetData)
      $(function() {
        luckysheet.create(options);
      });
    }
  }
};
</script>

<style src="@/assets/bs/iconfont/iconfont.css" />
<style scoped lang="scss">
.download {
  width: 100%;
  float: left;
  button {
    color: #444;
    width: 90px;
    text-align: left;
    .svg-icon {
      font-size: 16px;
      margin-right: 10px;
    }
  }
}
.block {
  position: relative;
  z-index: 10000;
  top: 0;
  background: #fff;
  width: 100%;
  h2 {
    font-size: 14px;
    line-height: 30px;
  }
  h4 {
    font-size: 12px;
  }
  .search_input {
    font-size: 12px;
    margin-bottom: 10px;
    label {
      line-height: 20px;
    }
  }
}
.layout {
  display: block;
  position: relative;
  margin: 0;
  padding: 0;
}
.layout-middle {
  display: block;
  position: absolute;
  left: 200px;
  right: 0;
  width: calc(100% - 200px);
  margin: 0;
  padding: 0;

  .excel-designer {
    display: block;
    position: relative;
    margin: 0;
    padding: 0;
  }
}
.layout-right {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  padding: 20px;
  width: 200px;
  min-height: 99.98vh;
  border-left: 1px solid #dcdee2;
  border-color: #e8eaec;
  background: #fff;
  border-radius: 4px;
  font-size: 14px;
  -webkit-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/992206.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

echarts根据x轴数据长度判断是否倾斜展示/柱状图上方显示数字

showChart1() { // 通过id初始化let chart1 echarts.init(document.getElementById(this.idName))var option {// 到容器的距离grid: {top: 18,left: 0,right: 4,bottom: 0,},xAxis: [{type: category,data: this.xData,axisLine: {lineStyle: {color: rgba(255, 255, 255, .…

vscode编辑器一些设置项

vscode编辑器一些设置项 1、工具栏放置位置&#xff08;左侧/右侧&#xff09; 1、工具栏放置位置&#xff08;左侧/右侧&#xff09; 如果这个配置为“hidden”&#xff0c;那么就是隐藏了左侧工具栏&#xff0c;需要将其改为“left”或者“right”即可。 那么在哪里设置呢&am…

运动跑步耳机哪个牌子好、值得推荐的运动耳机

作为一位热衷于运动的爱好者&#xff0c;对于运动装备的要求十分严格。家里有很多手环和跑鞋&#xff0c;但在跑步时最喜欢的是听歌。一首好曲子能够改善跑步体验&#xff0c;延缓疲劳感。当然&#xff0c;并非所有的耳机都适合运动使用&#xff0c;选择运动耳机时需要考虑到运…

【PythonGIS】矢量数据投影转换(坐标转换)

之前跟大家分享过面矢量数据投影转换和点矢量数据投影转换&#xff0c;但博主在日常工作的过程中发现之前分享的面矢量数据投影转换有时候会出现错误&#xff0c;或者转换后的效果不好。再一次偶然的过程中发现了新的坐标转换&#xff08;投影转换&#xff09;函数&#xff0c;…

【linux】进程优先级,进程切换

进程 1.进程优先级&#xff08;了解&#xff09;2.进程切换 1.进程优先级&#xff08;了解&#xff09; 1.什么叫做进程优先级&#xff1f; 我们知道权限是能还是不能做的问题&#xff0c;那对应的优先级就是能做&#xff0c;但是是先做还是后做的问题。 2.为什么存在优先级…

vite项目启动use `--host` to expose

Vite 启动项目后&#xff0c;发现只有localhost 端口 服务&#xff0c;没有 IP 端口服务。 运行npm run serve&#xff0c;终端提示Vite启动后提示Network: use ‘–host’ to expose。 在vite.config.js中配置server import {defineConfig } from vite import vue from vi…

MySQL学习5:事务、存储引擎

事务 简介 事务是一组数据库操作的执行单元&#xff0c;它要么完全执行&#xff0c;要么完全不执行。事务是确保数据库中的数据一致性和完整性的重要机制之一。 事务具有以下四个特性&#xff08;称为ACID特性&#xff09;&#xff1a; 原子性&#xff08;Atomicity&#xf…

Discourse 能支持多少数量的主题

支持主题的数量和 ID 使用的数据类型有关。 根据我们从 Discourse 上 dump 出来的 SQL&#xff0c;我们看到 Discourse 的官方使用 Integer 作为 ID 的数据类型。 随后&#xff0c;我们查看了 pgsql 的官方文档&#xff0c;integer 是 4 字节的&#xff0c;能够存储的最大值为…

智能合约安全分析,假充值攻击如何突破交易所的防御?

智能合约安全分析&#xff0c;假充值攻击如何突破交易所的防御&#xff1f; 引言 假充值攻击&#xff0c;是指攻击者通过利用交易所在处理充值过程中的漏洞或系统错误&#xff0c;发送伪造的交易信息到交易所钱包地址&#xff0c;这些伪造的交易信息被交易所误认为是真实的充值…

系统架构设计师(第二版)学习笔记----计算机网络

【原文链接】系统架构设计师&#xff08;第二版&#xff09;学习笔记----计算机网络 文章目录 一、计算机网络的基本概念1.1 计算机网络的发展阶段1.2 计算机网络的功能1.3 计算机网络的性能指标1.4 计算机网络的非性能指标 二、通信技术2.1 发信机的信号处理流程2.2 收信机的信…

运维经验记录 在CentOS上挂载Windows共享磁盘

1、需求&#xff1a; 非root用户&#xff08;普通用户&#xff09;能够读写windows共享目录&#xff0c;比如查看文件、创建文件、修改文件、删除文件 # 让普通用户也可以正常读写 uidvalue and gidvalue Set the owner and group of the root of the file system (default: …

再谈内存分配器的优缺点

结论 在频繁申请、释放内存的工作场景&#xff0c;建议需要考虑定制化的内存分配器Allocator 优点 那么用内存分配器有那些好处呢&#xff1f;在近段研究和积累看来&#xff0c;主要有以下几点&#xff1a; 拥有连续内存的访问优势较浅的申请、释放栈访问深度&#xff1b;甚…

攻防世界-WEB-upload1

打开靶机上传文件 必须上传图片&#xff0c;F12审计一下代码 发现校验代码 一句话木马&#xff0c;使用菜刀连接 通过bp修改文件类型 get成功&#xff0c;证明文件已经上传 修改POST请求 得到上传成功的文件&#xff0c;请求文件名 得到flag cyberpeace{5a97279c34e62…

The timestamp difference between admin and executor exceeds the limit.解决办法

前言&#xff1a; 使用xxjob报错了&#xff0c;图文如下&#xff1a; 2023-09-09 10:28:54 [com.xxl.job.core.thread.JobThread#run]-[127]-[Thread-191] ----------- xxl-job job execute start ----------- ----------- Param: 2023-09-09 10:28:54 [com.xxl.job.core.thre…

企业架构LNMP学习笔记27

Keepalived的配置补充&#xff1a; 脑裂&#xff08;裂脑&#xff09;&#xff1a;vip出现在了多台机器上。网络不通畅&#xff0c;禁用了数据包&#xff0c;主备服务器没法通讯&#xff0c;造成备服务器认为主服务器不可用&#xff0c;绑定VIP&#xff0c;主服务器VIP不会释放…

安卓如何设置开机启动某个程序?init.rc给你搞定

一、如何设置开机启动某个程序&#xff1f; 1.需求描述 最近有个项目需要在Android开机启动之后&#xff0c;自动执行一个C语言编写的程序&#xff1a;pengd 该程序运行时需要修改网络ip地址及其他网络操作&#xff0c;所以需要root权限 根据需求描述&#xff0c;我们需要做…

算法-88.合并两个有序数组-简单

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&#xff0c;合并后数组…

【Idea】IntelliJ IDEA 2023版本,.java文件报 no scalac found to compile scala sources问题

maven install没问题&#xff0c;新版本idea中编译则报错。 原因应该是新旧版本对Scala Compiler的调用逻辑有差异。造成的&#xff0c;因为同样的工程&#xff0c;在旧版本里可以正常编译。 解决方法 Settings > Build, Execution, Deployment > Compiler > Scala…

【区块链】DeFi是什么?大白话科普文

对于一些没有玩过区块链、或者说没有真金白银的体验过这个虚拟世界的小伙伴来说,这篇文章可以帮你了解 DeFi。致力于帮你在这个线上走出这一步。 当然这不是理财建议。 文章目录 前言什么是去中心化金融?有哪些 DeFi 项目DeFi由哪几部分构成?热门DeFi项目有哪些?前言 Def…

【C++】封装map和set(红黑树实现)

前言&#xff1a; 前面&#xff0c;我们学习了set和map的用法&#xff0c;这两个容器可以完成查找&#xff0c;排序等操作&#xff0c;后来我们在学习过二叉搜索树的基础上又学习了两种特殊的二叉搜索树——AVL树和红黑树&#xff0c;他们俩可以是效率进一步提高&#xff0c;其…