Browse Source

增加环路分析 ,换热站失水分析的数据导出功能,前端根据数据生成excel文件供下载

yanglzh 2 years ago
parent
commit
6a1edf9605

+ 2 - 1
package.json

@@ -48,7 +48,8 @@
     "vue3-cron": "^1.1.8",
     "vue3-json-viewer": "^2.2.2",
     "vuex": "^4.0.2",
-    "wangeditor": "^4.7.12"
+    "wangeditor": "^4.7.12",
+    "xlsx-with-styles": "^0.17.2"
   },
   "devDependencies": {
     "@types/node": "^17.0.21",

+ 89 - 0
src/utils/xlsx.ts

@@ -0,0 +1,89 @@
+// import * as XLSX from "xlsx";
+import * as XLSX from "xlsx-with-styles";
+
+export const get_excel_to_json = (file: any) => {
+  return new Promise((resove) => {
+    const reader = new FileReader();
+    reader.readAsBinaryString(file);
+    reader.onload = function (e: any) {
+      const wb = XLSX.read(e.target.result, { type: "binary", cellStyles: true });
+      const json = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
+      resove(json);
+    };
+  });
+};
+
+export const export_json_to_excel = ({
+  header = {},
+  list = [],
+  sheetName = 'sheetName',
+  fileName = 'filename',
+  autoWidth = true,
+}) => {
+  const book = XLSX.utils.book_new();
+  let sheetItem = XLSX.utils.json_to_sheet([header, ...list], {
+    // header: Object.keys(header),
+    cellDates: true,
+    skipHeader: true,
+  });
+
+  // const style = {
+  //   fill: {
+  //     fgColor: { rgb: "FF9bc2e6" },
+  //     bgColor: { rgb: "FF9bc2e6" },
+  //   },
+  // }
+
+  // const range = sheetItem['!ref']
+
+  // const start = '1'
+  // const end = range?.split(':')[1].slice(1)
+
+  // Object.keys(sheetItem).forEach(key => {
+  //   if ((key.length === 2 && key.endsWith(start)) || key.endsWith(end!)) {
+  //     sheetItem[key].s = style
+  //   }
+  // })
+
+  autoWidth && auto_width(sheetItem, json_to_array(Object.keys(header), list));
+  XLSX.utils.book_append_sheet(book, sheetItem, sheetName);
+  XLSX.writeFile(book, fileName + ".xlsx");
+};
+
+const auto_width = (sheetItem: any, data: any[]) => {
+  const maxWidth = 50;
+  /*set worksheet max width per col*/
+  const colWidth = data.map((row: string[]) =>
+    row.map((val) => {
+      let width = 0;
+      /*if null/undefined*/
+      if (val !== null && val !== undefined) {
+        if (val.toString().charCodeAt(0) > 255) {
+          width = val.toString().length * 2;
+        } else {
+          width = val.toString().length;
+        }
+      } else {
+        width = 10;
+      }
+      return {
+        wch: width > maxWidth ? maxWidth : width,
+      };
+    })
+  );
+  /*start in the first row*/
+  const result = colWidth[0];
+  for (let i = 1; i < colWidth.length; i++) {
+    for (let j = 0; j < colWidth[i].length; j++) {
+      if (result[j].wch < colWidth[i][j].wch) {
+        result[j].wch = colWidth[i][j].wch;
+      }
+    }
+  }
+  sheetItem["!cols"] = result;
+};
+
+const json_to_array = (key: string[], jsonData: any[]) => {
+  const data = jsonData.map((v) => key.map((j) => v[j] + "站位"));
+  return data;
+};

+ 42 - 2
src/views/heating/energyAnalysis/analysisReport/index.vue

@@ -46,9 +46,9 @@
           </el-tabs>
 
           <div class="chart" style="height: 400px" v-loading="state.tableData.loading" ref="lineChartRef"></div>
-          <div class="title" style="margin-top:20px">数据列表</div>
+          <div class="title flex-row" style="margin-top:20px">数据列表 <el-button @click="exportExcel">数据导出</el-button>
+          </div>
           <el-table :data="tableData" v-loading="loading" style="width: 100%">
-            <el-table-column label="ID" align="center" prop="id" width="60" />
             <el-table-column label="环路编号" prop="huanLuNo" :show-overflow-tooltip="true" />
             <el-table-column label="环路名称" prop="huanLuName" :show-overflow-tooltip="true" />
             <el-table-column label="一网供水温度" prop="inTemperature1" :show-overflow-tooltip="true" />
@@ -80,6 +80,7 @@ import heatApi from '/@/api/heatStation';
 import energyApi from '/@/api/energyAnalysis';
 import { formatDate } from '/@/utils/formatTime'
 import { useSearch } from '/@/hooks/useCommon';
+import { export_json_to_excel } from '/@/utils/xlsx';
 
 const { params, tableData, getList, loading } = useSearch<any[]>(energyApi.getEnergyLoopdataPage, 'list', {
   loopCode: '',
@@ -89,6 +90,8 @@ const { params, tableData, getList, loading } = useSearch<any[]>(energyApi.getEn
   ]
 })
 
+let nodeName = ''
+
 let global: any = {
   lineChart: null,
   dispose: [null, '', undefined],
@@ -145,6 +148,40 @@ const filterNode = (value: string, data: any) => {
   return data.name.includes(value)
 }
 
+const exportExcel = () => {
+
+  const header = {
+    huanLuNo: '环路编号',
+    inTemperature1: '一网供水温度',
+    outTemperature1: '一网回水温度',
+    inTemperature2: '二网供水温度',
+    outTemperature2: '二网回水温度',
+    inPressure1: '一网供水压力',
+    outPressure1: '一网回水压力',
+    inPressure2: '二网供水压力',
+    outPressure2: '二网回水压力',
+    supplyWaterFlow: '供水流量',
+    returnWaterFlow: '回水流量',
+    supplyWaterFlow2: '二网供水流量',
+    supplyValve: '阀门开度',
+  };
+
+  // 主体数据
+  const list = state.tableData.data.map((item: any) => {
+    const newItem: any = {}
+    Object.keys(header).forEach((key: string) => {
+      newItem[key] = item[key]
+    })
+    return newItem
+  });
+
+  export_json_to_excel({
+    header,
+    list,
+    fileName: nodeName + '-环路分析数据导出',
+  });
+}
+
 const queryTree = () => {
   heatApi.heatStation.getAllStaAndLoop({})
     .then((res: any) => {
@@ -152,6 +189,7 @@ const queryTree = () => {
       if (state.heatList.length) {
         curNode.value = state.heatList[0].code
         params.loopCode = state.heatList[0].code
+        nodeName = state.heatList[0].name
       }
       getChartData()
     });
@@ -205,6 +243,8 @@ const getChartData = () => {
   })
 }
 const onNodeClick = (data: any) => {
+  nodeName = data.name
+  // nodeName = data.code
   curNode.value = data.code
   params.loopCode = data.code
   getChartData()

+ 28 - 1
src/views/heating/energyAnalysis/heatStationWaterAnalysis/index.vue

@@ -22,7 +22,8 @@
           <div style="height: 300px" v-loading="state.tableData.loading" ref="barChartRef"></div>
           <div class="title mt-2">失水量曲线</div>
           <div style="height: 300px" v-loading="state.tableData.loading" ref="lineChartRef"></div>
-          <div class="title mt-2">数据列表</div>
+          <div class="title mt-2 flex-row" style="margin-top:20px">数据列表 <el-button @click="exportExcel">数据导出</el-button>
+          </div>
 
           <el-table :data="tableData" style="width: 100%" v-loading="loading">
             <el-table-column type="index" width="55" label="序号" align="center" />
@@ -47,9 +48,12 @@ import api from '/@/api/energyAnalysis';
 import heatApi from '/@/api/heatStation';
 import { formatDate } from '/@/utils/formatTime';
 import { useSearch } from '/@/hooks/useCommon';
+import { export_json_to_excel } from '/@/utils/xlsx';
 
 const { params, tableData, getList, loading } = useSearch<any[]>(api.getEnergyHuanluWaterLossLineChartPage, 'list', { loopCode: '' });
 
+let nodeName = ''
+
 let global: any = {
   barChart: null,
   lineChart: null,
@@ -97,11 +101,33 @@ const filterNode = (value: string, data: any) => {
 }
 
 const onNodeClick = (data: any) => {
+  nodeName = data.name
   curNode.value = data.code
   params.loopCode = data.code
   queryLineChart()
 }
 
+
+const exportExcel = () => {
+
+  const header = {
+    datetime: '日期',
+    huanLuNo: '环路编码',
+    huanLuName: '环路名称',
+    supplyWater: '供水流量',
+    returnWater: '回水流量',
+    waterLoss: '失水量',
+  };
+
+  const list = state.tableData.data
+
+  export_json_to_excel({
+    header,
+    list,
+    fileName: nodeName + '-换热站失水分析数据导出',
+  });
+}
+
 const queryTree = () => {
   heatApi.heatStation.getAllStaAndLoop({})
     .then((res: any) => {
@@ -109,6 +135,7 @@ const queryTree = () => {
       if (state.heatList.length) {
         curNode.value = state.heatList[0].code
         params.loopCode = state.heatList[0].code
+        nodeName = state.heatList[0].name
       }
       queryLineChart()
     });