2 Commity a335aa4832 ... c8f1164e09

Autor SHA1 Wiadomość Data
  sunxuewei c8f1164e09 Merge branch 'sxw-skeleton' of http://101.36.160.140:21044/emergency-report/report-vue into sxw-skeleton 1 rok temu
  sunxuewei e65ee491ef 数据统计添加导出 1 rok temu

Plik diff jest za duży
+ 715 - 45
package-lock.json


+ 3 - 1
package.json

@@ -15,12 +15,14 @@
15 15
     "crypto-js": "^4.2.0",
16 16
     "echarts": "^5.5.0",
17 17
     "element-plus": "^2.6.0",
18
+    "exceljs": "^4.4.0",
18 19
     "js-cookie": "^3.0.5",
19 20
     "nprogress": "^0.2.0",
20 21
     "qs": "^6.11.2",
21 22
     "vue": "^3.2.13",
22 23
     "vue-router": "^4.0.3",
23
-    "vuex": "^4.0.0"
24
+    "vuex": "^4.0.0",
25
+    "xlsx": "^0.18.5"
24 26
   },
25 27
   "devDependencies": {
26 28
     "@types/crypto-js": "^4.2.2",

+ 51 - 0
src/components/export2xlsx/index.ts

@@ -0,0 +1,51 @@
1
+import type { Range } from "xlsx";
2
+import { writeFile, utils } from "xlsx";
3
+
4
+export const exportExcel = (fileData: any[], headerName: any[], headerProp: string[], fileName: string) => {
5
+  // console.log(fileData, headerName, headerProp, fileName);
6
+  const merges: any = {};
7
+  const name: string[][] = [[], [], []];
8
+  const data = fileData.map((obj) => {
9
+    return headerProp.map((prop) => obj[prop]);
10
+  });
11
+  name[0].push("省份", "储备仓库", ...headerName.map((item) => item.matypename2));
12
+  name[1].push("省份", "储备仓库", ...headerName.map((item) => item.matypename3));
13
+  name[2].push("省份", "储备仓库", ...headerName.map((item) => item.matypename4));
14
+  name[0].forEach((item, index) => {
15
+    const itemIndex = name[0].findIndex((ite) => ite === item);
16
+    if (itemIndex !== index) {
17
+      merges[item] = { s: { r: 0, c: itemIndex }, e: { r: 0, c: index } };
18
+    }
19
+  });
20
+  const cols = data.map((item) => item[0]);
21
+  cols.forEach((item, index) => {
22
+    const itemIndex = cols.findIndex((ite) => ite === item);
23
+    if (itemIndex !== index) {
24
+      merges[item] = { s: { r: itemIndex + 3, c: 0 }, e: { r: index + 3, c: 0 } };
25
+    }
26
+  });
27
+  data.unshift(...name);
28
+  const ws = utils.aoa_to_sheet(data);
29
+  const wb = utils.book_new();
30
+  // 设置单元格样式
31
+  const cellRef = utils.encode_cell({ c: 0, r: 0 });
32
+  const cell = ws[cellRef];
33
+  if (!cell.s) cell.s = {};
34
+  cell.s.alignment = {
35
+    horizontal: "center",
36
+    vertical: "center"
37
+  };
38
+  const test: Range[] = [];
39
+  Object.keys(merges).forEach((item) => {
40
+    test.push(merges[item]);
41
+  });
42
+  ws["!merges"] = [
43
+    { s: { r: 0, c: 0 }, e: { r: 2, c: 0 } },
44
+    { s: { r: 0, c: 1 }, e: { r: 2, c: 1 } },
45
+    { s: { r: 3, c: 0 }, e: { r: 3, c: 1 } },
46
+    ...test
47
+  ];
48
+  utils.book_append_sheet(wb, ws, fileName);
49
+  writeFile(wb, `${fileName}.xlsx`);
50
+  // console.log(cellRef, cell);
51
+};

+ 1 - 1
src/views/admin/dept/index.vue

@@ -194,7 +194,7 @@ import uploadFile from "@/components/uploadFile/index.vue";
194 194
 import { nextTick, ref } from "vue";
195 195
 import { ElMessage, ElMessageBox } from "element-plus";
196 196
 import type { FormInstance, FormRules } from "element-plus";
197
-import { Search, EditPen, Plus, Edit, Delete } from "@element-plus/icons-vue";
197
+import { Search, Plus, Edit, Delete } from "@element-plus/icons-vue";
198 198
 
199 199
 import { useDict } from "@/hooks/dict";
200 200
 import { ITablePage } from "@/const/interface_type";

+ 9 - 1
src/views/dataStatistics/droughtResistant/index.vue

@@ -59,6 +59,7 @@
59 59
       </el-row>
60 60
     </el-form>
61 61
 
62
+    <el-button type="primary" :icon="Download" style="margin-bottom: 10px" @click="downloadExcel">导出</el-button>
62 63
     <el-table :data="tableData" stripe border :span-method="arraySpanMethod">
63 64
       <el-table-column type="index" label="序号" header-align="center" align="center" />
64 65
       <el-table-column prop="upidName" label="省份" header-align="center" align="center" />
@@ -83,13 +84,14 @@ import { ref } from "vue";
83 84
 
84 85
 import { handleTree } from "@/utils/util";
85 86
 import { useGetters } from "@/hooks/storeHooks";
87
+import { exportExcel } from "@/components/export2xlsx";
86 88
 import {
87 89
   getDroughtResistantHeader,
88 90
   getDroughtResistantList,
89 91
   getCityList,
90 92
   getSysTreeDict
91 93
 } from "@/api/dataStatistics/index";
92
-import { Search, RefreshRight } from "@element-plus/icons-vue";
94
+import { Search, RefreshRight, Download } from "@element-plus/icons-vue";
93 95
 
94 96
 const headerName: any = ref([]);
95 97
 const headerProps: any = ref([]);
@@ -104,6 +106,7 @@ const mergeObj: any = ref({});
104 106
 const cityList: any = ref([]);
105 107
 const warehouseList: any = ref([]);
106 108
 const suppliesList: any = ref([]);
109
+const exportHeaderName = ref([]); // 导出用表头
107 110
 
108 111
 const { userInfo } = useGetters(["userInfo"]);
109 112
 
@@ -158,6 +161,7 @@ getDroughtResistantHeader({ matype1: ["100", "200"] }).then((res: any) => {
158 161
       .forEach((item: any) => {
159 162
         headerName.value.push(...item);
160 163
       });
164
+    exportHeaderName.value = res.data;
161 165
     headerName.value = handleTree(headerName.value, "dmUpcode");
162 166
     headerProps.value = res.data.map((item: any) => item.matypecode3);
163 167
     headerProps.value.unshift("upidName", "username");
@@ -253,4 +257,8 @@ const arraySpanMethod = ({ column, rowIndex, columnIndex }: any) => {
253 257
     }
254 258
   }
255 259
 };
260
+
261
+const downloadExcel = () => {
262
+  exportExcel(tableData.value, exportHeaderName.value, headerProps.value, "防汛抗旱物资数量价值表");
263
+};
256 264
 </script>

+ 17 - 9
src/views/dataStatistics/reliefMaterial/index.vue

@@ -59,6 +59,7 @@
59 59
       </el-row>
60 60
     </el-form>
61 61
 
62
+    <el-button type="primary" :icon="Download" style="margin-bottom: 10px" @click="downloadExcel">导出</el-button>
62 63
     <el-table :data="tableData" stripe border :span-method="arraySpanMethod">
63 64
       <el-table-column type="index" label="序号" header-align="center" align="center" />
64 65
       <el-table-column prop="upidName" label="省份" header-align="center" align="center" />
@@ -83,22 +84,24 @@ import { ref } from "vue";
83 84
 
84 85
 import { handleTree } from "@/utils/util";
85 86
 import { useGetters } from "@/hooks/storeHooks";
87
+import { exportExcel } from "@/components/export2xlsx";
86 88
 import {
87 89
   getDroughtResistantHeader,
88 90
   getDroughtResistantList,
89 91
   getCityList,
90 92
   getSysTreeDict
91 93
 } from "@/api/dataStatistics/index";
92
-import { Search, RefreshRight } from "@element-plus/icons-vue";
94
+import { Search, RefreshRight, Download } from "@element-plus/icons-vue";
93 95
 
94
-const headerName: any = ref([]);
95
-const headerProps: any = ref([]);
96
-const tableData: any = ref([]);
97
-const searchList: any = ref({});
98
-const mergeObj: any = ref({});
99
-const cityList: any = ref([]);
100
-const warehouseList: any = ref([]);
101
-const suppliesList: any = ref([]);
96
+const headerName: any = ref([]); // 展示用表头
97
+const headerProps: any = ref([]); // 数据对应code
98
+const tableData: any = ref([]); // 列表数据
99
+const searchList: any = ref({}); // 搜索数据
100
+const mergeObj: any = ref({}); // 处理合并单元格数据
101
+const cityList: any = ref([]); // 省份信息
102
+const warehouseList: any = ref([]); // 储备仓库
103
+const suppliesList: any = ref([]); // 物资类别
104
+const exportHeaderName = ref([]); // 导出用表头
102 105
 
103 106
 const { userInfo } = useGetters(["userInfo"]);
104 107
 
@@ -153,6 +156,7 @@ getDroughtResistantHeader({ matype1: ["300"] }).then((res: any) => {
153 156
       .forEach((item: any) => {
154 157
         headerName.value.push(...item);
155 158
       });
159
+    exportHeaderName.value = res.data;
156 160
     headerName.value = handleTree(headerName.value, "dmUpcode");
157 161
     headerProps.value = res.data.map((item: any) => item.matypecode3);
158 162
     headerProps.value.unshift("upidName", "username");
@@ -248,4 +252,8 @@ const arraySpanMethod = ({ column, rowIndex, columnIndex }: any) => {
248 252
     }
249 253
   }
250 254
 };
255
+
256
+const downloadExcel = () => {
257
+  exportExcel(tableData.value, exportHeaderName.value, headerProps.value, "救灾物资数量价值表");
258
+};
251 259
 </script>

+ 2 - 21
src/views/home/index.vue

@@ -1,35 +1,16 @@
1 1
 <template>
2 2
   <basic-container>
3
-    <Kq v-if="deptType == '3'"></Kq>
4
-    <Gjj v-if="deptType == '1' || deptType == '2'"></Gjj>
3
+    <Kq v-if="userInfo.deptType === '3'"></Kq>
4
+    <Gjj v-if="userInfo.deptType === '1' || userInfo.deptType === '2'"></Gjj>
5 5
   </basic-container>
6 6
 </template>
7 7
 
8 8
 <script setup lang="ts">
9
-import { ref, reactive, toRefs, onMounted, watch } from "vue";
10 9
 import Kq from "@/views/home/components/kq.vue";
11 10
 import Gjj from "@/views/home/components/gjj.vue";
12 11
 import { useGetters } from "@/hooks/storeHooks";
13
-import { useStore } from "vuex";
14
-import store from "@/store";
15 12
 
16 13
 const { userInfo } = useGetters(["userInfo"]);
17
-const data = reactive({
18
-  deptType: ""
19
-});
20
-
21
-let { deptType } = toRefs(data);
22
-
23
-watch(
24
-  userInfo,
25
-  () => {
26
-    console.log(userInfo.value.deptType, "watch");
27
-  },
28
-  { deep: true, immediate: true }
29
-);
30
-onMounted(() => {
31
-  deptType = userInfo.value.deptType ? userInfo.value.deptType : "";
32
-});
33 14
 </script>
34 15
 
35 16
 <style lang="scss" scoped></style>