Explorar o código

计算差旅天数OK

shaogen1995 hai 1 ano
pai
achega
2217e57aa0

+ 1 - 0
package.json

@@ -19,6 +19,7 @@
     "dayjs": "^1.11.10",
     "echarts": "^5.5.0",
     "js-base64": "^3.7.3",
+    "js-export-excel": "^1.1.4",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
     "react-redux": "^8.0.4",

+ 14 - 9
src/pages/A1xlsx/index.module.scss

@@ -1,12 +1,17 @@
-.A1xlsx{
-  :global{
-    .A1row{
-      display: flex;
-      &>div{
-        width: 200px;
-        text-align: center;
-        margin-bottom: 5px;
-      }
+.A1xlsx {
+  :global {
+    .A1top {
+      margin-bottom: 15px;
+      text-align: right;
+    }
+    .tableBox{
+      width: 100%;
+      height: calc(100% - 47px);
+      background-color: #fff;
+      border-radius: 10px;
+      // .ant-table-cell{
+      //   padding: 4 !important;
+      // }
     }
   }
 }

+ 120 - 53
src/pages/A1xlsx/index.tsx

@@ -1,89 +1,156 @@
-import React, { useEffect, useState } from "react";
+import React, { useCallback, useRef, useState } from "react";
 import styles from "./index.module.scss";
 import dayjs from "dayjs";
-
-const listTemp = [
-  { time1: "2024-05-27 11:50:00", time2: "2024-05-31 14:15:00" },
-  { time1: "2024-05-13 08:22:00", time2: "2024-05-14 16:43:00" },
-  { time1: "2024-05-20 13:39:00", time2: "2024-05-22 15:03:00" },
-  { time1: "2024-05-13 12:17:00", time2: "2024-05-14 17:57:00" },
-  { time1: "2024-05-27 12:17:00", time2: "2024-05-31 16:36:00" },
-  { time1: "2024-05-20 10:50:00", time2: "2024-05-23 20:05:00" },
-  { time1: "2024-05-18 07:55:00", time2: "2024-05-18 22:45:00" },
-  { time1: "2024-05-29 07:30:00", time2: "2024-05-31 19:25:00" },
-  { time1: "2024-05-06 15:00:00", time2: "2024-05-11 16:27:00" },
-  { time1: "2024-05-13 17:30:00", time2: "2024-05-23 14:50:00" },
-  { time1: "2024-05-28 07:10:00", time2: "2024-05-31 21:00:00" },
-  { time1: "2024-05-15 18:54:00", time2: "2024-05-17 20:36:00" },
-  { time1: "2024-05-28 09:17:00", time2: "2024-05-31 18:55:00" },
-  { time1: "2024-05-06 18:00:00", time2: "2024-05-08 14:51:00" },
-  { time1: "2024-05-22 18:36:00", time2: "2024-05-24 13:12:00" },
-  { time1: "2024-05-25 11:05:00", time2: "2024-05-28 12:10:00" },
-  { time1: "2024-05-08 18:40:00", time2: "2024-05-14 19:55:00" },
-  { time1: "2024-05-29 07:50:00", time2: "2024-05-31 13:35:00" },
-  { time1: "2024-05-08 08:37:00", time2: "2024-05-10 15:01:00" },
-  { time1: "2024-05-15 21:15:00", time2: "2024-05-18 15:47:00" },
-  { time1: "2024-05-22 08:30:00", time2: "2024-05-23 15:25:00" },
-  { time1: "2024-05-28 10:15:00", time2: "2024-05-31 17:04:00" },
-  { time1: "2024-05-14 10:50:00", time2: "2024-05-17 16:00:00" },
-  { time1: "2024-05-09 13:00:00", time2: "2024-05-18 14:25:00" },
-  { time1: "2024-05-09 13:00:00", time2: "2024-05-23 20:05:00" },
-  { time1: "2024-05-14 10:50:00", time2: "2024-05-17 16:00:00" },
-  { time1: "2024-05-20 10:50:00", time2: "2024-05-23 20:05:00" },
-  { time1: "2024-05-29 12:17:00", time2: "2024-05-30 14:18:00" },
-  { time1: "2024-05-23 07:30:00", time2: "2024-05-24 11:50:00" },
-  { time1: "2024-05-27 17:22:00", time2: "2024-05-31 13:35:00" },
-];
+import { Button } from "antd";
+import { API_upFile } from "@/store/action/layout";
+import { MessageFu } from "@/utils/message";
+import { fileDomInitialFu } from "@/utils/domShow";
+import MyTable from "@/components/MyTable";
+import { A1tableC } from "@/utils/tableData";
+import ExportJsonExcel from "js-export-excel";
 
 type listType = {
-  time1: string;
-  time2: string;
+  startTime: string;
+  endTime: string;
   day: number;
 };
 
 function A1xlsx() {
   const [list, setList] = useState<listType[]>([]);
 
-  useEffect(() => {
+  const myInput = useRef<HTMLInputElement>(null);
+
+  const dataChangeFu = useCallback((list: listType[]) => {
     const arr = [] as listType[];
 
-    listTemp.forEach((v) => {
-      const temp1 = dayjs(v.time1).format("YYYY-MM-DD");
-      const temp2 = dayjs(v.time2).format("YYYY-MM-DD");
+    list.forEach((v) => {
+      const temp1 = dayjs(v.startTime).format("YYYY-MM-DD");
+      const temp2 = dayjs(v.endTime).format("YYYY-MM-DD");
 
       let num = dayjs(temp2).diff(temp1, "day");
 
-      const Sshi = dayjs(v.time1).get("hour");
-      const Sfen = dayjs(v.time1).get("minute");
+      const Sshi = dayjs(v.startTime).get("hour");
+      const Sfen = dayjs(v.startTime).get("minute");
 
       // console.log("ppp", Sshi);
 
       if (Sshi < 12 || (Sshi === 12 && Sfen <= 30)) num += 0.5;
 
-      const Eshi = dayjs(v.time2).get("hour");
-      // const Efen = dayjs(v.time2).get("minute");
+      const Eshi = dayjs(v.endTime).get("hour");
+      // const Efen = dayjs(v.endTime).get("minute");
 
       if (Eshi >= 14) num += 0.5;
       arr.push({
-        time1: v.time1,
-        time2: v.time2,
+        startTime: v.startTime,
+        endTime: v.endTime,
         day: num,
       });
     });
     setList(arr);
   }, []);
 
+  // 上传表格
+  const handeUpPhoto = useCallback(
+    async (e: React.ChangeEvent<HTMLInputElement>) => {
+      if (e.target.files) {
+        // 拿到files信息
+        const filesInfo = e.target.files[0];
+        // console.log("-----", filesInfo.type);
+        console.log(filesInfo);
+
+        // 校验格式
+        // const type = format;
+        if (!filesInfo.name.includes(".xlsx"))
+          return MessageFu.warning("只支持.xlsx文件!");
+
+        // 创建FormData对象
+        const fd = new FormData();
+        fd.append("type", "doc");
+        fd.append("dirCode", "A1Day");
+        fd.append("file", filesInfo);
+
+        e.target.value = "";
+
+        try {
+          const res = await API_upFile(fd, "cms/trip/upload");
+          if (res.code === 0) {
+            MessageFu.success("上传成功!");
+            // setFileUrl(res.data);
+            dataChangeFu(res.data || []);
+          }
+          fileDomInitialFu();
+        } catch (error) {
+          fileDomInitialFu();
+        }
+      }
+    },
+    [dataChangeFu]
+  );
+
+  // 点击导出
+  const deriveFu = useCallback(async () => {
+    // if (list.length <= 0) return;
+
+    const name = "计算差旅天数" + dayjs(new Date()).format("YYYY-MM-DD HH:mm");
+
+    const option = {
+      fileName: name,
+      datas: [
+        {
+          sheetData: list,
+          sheetName: name,
+          sheetFilter: ["startTime", "endTime", "day"],
+          sheetHeader: ["开始时间", "结束时间", "计算后天数"],
+          columnWidths: [10, 10, 10],
+        },
+      ],
+    };
+
+    const toExcel = new ExportJsonExcel(option); //new
+    toExcel.saveExcel(); //保存
+  }, [list]);
+
   return (
     <div className={styles.A1xlsx}>
+      <input
+        id="upInput"
+        type="file"
+        accept=".xlsx"
+        ref={myInput}
+        onChange={(e) => handeUpPhoto(e)}
+      />
       <div className="pageTitle">计算差旅天数</div>
 
-      {list.map((v, i) => (
-        <div key={i} className="A1row">
-          <div>{v.time1}</div>
-          <div>{v.time2}</div>
-          <div>{v.day}</div>
-        </div>
-      ))}
+      <div className="A1top">
+        {list.length ? (
+          <>
+            <Button className="A1btn" onClick={() => setList([])}>
+              清空
+            </Button>
+            &emsp;&emsp;
+            <Button type="primary" onClick={deriveFu}>
+              导出表格
+            </Button>
+          </>
+        ) : (
+          <Button
+            type="primary"
+            className="A1btn"
+            onClick={() => myInput.current?.click()}
+          >
+            上传表格
+          </Button>
+        )}
+      </div>
+
+      <div className="tableBox">
+        <MyTable
+          yHeight={707}
+          list={list}
+          columnsTemp={A1tableC}
+          pagingInfo={false}
+        />
+      </div>
     </div>
   );
 }

+ 5 - 3
src/pages/Layout/index.tsx

@@ -46,9 +46,11 @@ function Layout() {
       const tempList: UserListType[] = res.data || [];
       // console.log(123, tempList);
       tempList.forEach((v) => {
-        v.children.forEach((c) => {
-          if (c.authority) isOkIdArr.push(c.id);
-        });
+        if (v.children) {
+          v.children.forEach((c) => {
+            if (c.authority) isOkIdArr.push(c.id);
+          });
+        }
       });
       // 是管理员
       if (userInfo.isAdmin === 1) {

+ 18 - 12
src/pages/Z1user/Z1auth.tsx

@@ -56,9 +56,11 @@ function Z1auth({ authInfo, closeFu }: Props) {
   const checkIds = useMemo(() => {
     const arr: number[] = [];
     list.forEach((v) => {
-      v.children.forEach((c) => {
-        if (c.authority) arr.push(c.id);
-      });
+      if (v.children) {
+        v.children.forEach((c) => {
+          if (c.authority) arr.push(c.id);
+        });
+      }
     });
     return arr;
   }, [list]);
@@ -92,15 +94,19 @@ function Z1auth({ authInfo, closeFu }: Props) {
           <div key={v.id} className="Z1aRow">
             <div className="Z1aRow1">{v.name}</div>
             <div className="Z1aRow2">
-              {v.children.map((c) => (
-                <Checkbox
-                  key={c.id}
-                  checked={c.authority}
-                  onChange={(e) => onChange(e.target.checked, v.id, c.id)}
-                >
-                  {c.name}
-                </Checkbox>
-              ))}
+              {v.children ? (
+                <>
+                  {v.children.map((c) => (
+                    <Checkbox
+                      key={c.id}
+                      checked={c.authority}
+                      onChange={(e) => onChange(e.target.checked, v.id, c.id)}
+                    >
+                      {c.name}
+                    </Checkbox>
+                  ))}
+                </>
+              ) : null}
             </div>
           </div>
         ))}

+ 1 - 1
src/store/action/layout.ts

@@ -21,7 +21,7 @@ export const passWordEditAPI = (data: any) => {
  * 获取验证码
  */
 export const API_LoginGetCode = () => {
-  return http.get("show/getRandCode", { responseType: "blob" });
+  return http.get("admin/getRandCode", { responseType: "blob" });
 };
 
 const CancelToken = axios.CancelToken;

+ 4 - 88
src/utils/tableData.ts

@@ -15,94 +15,10 @@
 //   ];
 // };
 
-export const A2tableC = [
-  ["txt", "标题", "name"],
-  ["img", "封面", "thumb"],
-  ["txt", "发布日期", "publishDate"],
-  ["txt", "所属栏目", "dictName"],
-  ["text", "摘要", "description", 50],
-];
-
-export const A3tableC = [
-  ["txt", "标题", "name"],
-  ["img", "封面", "thumb"],
-  ["txt", "发布日期", "publishDate"],
-  ["text", "链接", "link", 50, "A"],
-];
-
-export const A4tableC = [
-  ["txt", "标题", "name"],
-  ["img", "封面", "thumb"],
-  ["txt", "发布日期", "publishDate"],
-  ["txt", "所属栏目", "dictName"],
-  ["txt", "质地", "texture"],
-  ["txt", "年代", "age"],
-  ["text", "简介", "description", 50],
-];
-
-export const A5tableC = [
-  ["txt", "标题", "name"],
-  ["img", "封面", "thumb"],
-  ["txt", "发布日期", "publishDate"],
-  ["txt", "展览类型", "type"],
-  ["text", "摘要", "description", 50],
-];
-
-export const A6tableC = [
-  ["txt", "标题", "name"],
-  ["img", "封面", "thumb"],
-  ["txt", "发布日期", "publishDate"],
-  ["txt", "所属栏目", "dictName"],
-  ["txtChange", "需要预约", "isNeed", { 1: "是", 0: "否" }],
-];
-
-export const A7tableC = [
-  ["txt", "标题", "name"],
-  ["img", "封面", "thumb"],
-  ["txt", "发布日期", "publishDate"],
-];
-
-export const B1tableC = [
-  ["txt", "申请时间", "createTime"],
-  ["txtChange", "验证状态", "status", { 0: "未验证", 1: "已验证" }],
-  ["txt", "姓名", "name"],
-  ["txt", "联系电话", "phone"],
-  ["txt", "人数", "pcs"],
-  ["txt", "预约日期", "bookDate"],
-  ["txt", "预约时段", "time"],
-];
-
-export const B2tableC = [
-  ["txt", "申请时间", "createTime"],
-  ["txt", "姓名", "name"],
-  ["txt", "活动名称", "title"],
-  ["txt", "联系电话", "phone"],
-  ["txt", "身份证", "identity"],
-  ["text", "预约说明", "description", 50],
-];
-
-export const B3tableC = [
-  ["txt", "申请时间", "createTime"],
-  ["txt", "姓名", "name"],
-  ["txt", "联系电话", "phone"],
-  ["txt", "身份证", "identity"],
-  ["text", "预约说明", "description", 50],
-];
-
-export const C1tableC = [
-  ["txt", "时段", "time"],
-  ["txt", "周一", "monday"],
-  ["txt", "周二", "tuesday"],
-  ["txt", "周三", "wednesday"],
-  ["txt", "周四", "thursday"],
-  ["txt", "周五", "friday"],
-  ["txt", "周六", "saturday"],
-  ["txt", "周日", "sunday"],
-];
-
-export const Z0tableC = [
-  ["txt", "栏目名称", "name"],
-  ["text", "说明", "rtf", 50],
+export const A1tableC = [
+  ["txt", "开始时间", "startTime"],
+  ["txt", "结束时间", "endTime"],
+  ["txt", "计算后天数", "day"],
 ];
 
 export const Z1tableC = [

+ 123 - 0
yarn.lock

@@ -2799,6 +2799,19 @@ adjust-sourcemap-loader@^4.0.0:
     loader-utils "^2.0.0"
     regex-parser "^2.2.11"
 
+adler-32@~1.2.0:
+  version "1.2.0"
+  resolved "https://registry.npmmirror.com/adler-32/-/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25"
+  integrity sha512-/vUqU/UY4MVeFsg+SsK6c+/05RZXIHZMGJA+PX5JyWI0ZRcBpupnRuPLU/NXXoFwMYCPCoxIfElM2eS+DUXCqQ==
+  dependencies:
+    exit-on-epipe "~1.0.1"
+    printj "~1.1.0"
+
+adler-32@~1.3.0:
+  version "1.3.1"
+  resolved "https://registry.npmmirror.com/adler-32/-/adler-32-1.3.1.tgz#1dbf0b36dda0012189a32b3679061932df1821e2"
+  integrity sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==
+
 agent-base@6:
   version "6.0.2"
   resolved "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
@@ -3391,6 +3404,11 @@ binary-extensions@^2.0.0:
   resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
   integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
 
+blob.js@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.npmmirror.com/blob.js/-/blob.js-1.0.1.tgz#547b449b252c855313e837b53d15b41d000ea1d2"
+  integrity sha512-TkPuWPeCHBbN+LWFg7BlXdSh6stRxwmAbuirKfiiHTMmo/uQfKFQMx2jrxVUkueKRiG+Tc7Os1Zn618Yc0MZpg==
+
 bluebird@^3.7.2:
   version "3.7.2"
   resolved "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
@@ -3583,6 +3601,14 @@ case-sensitive-paths-webpack-plugin@^2.4.0:
   resolved "https://registry.npmmirror.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4"
   integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==
 
+cfb@^1.1.4:
+  version "1.2.2"
+  resolved "https://registry.npmmirror.com/cfb/-/cfb-1.2.2.tgz#94e687628c700e5155436dac05f74e08df23bc44"
+  integrity sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==
+  dependencies:
+    adler-32 "~1.3.0"
+    crc-32 "~1.2.0"
+
 chalk@^2.4.1, chalk@^2.4.2:
   version "2.4.2"
   resolved "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -3693,6 +3719,14 @@ coa@^2.0.2:
     chalk "^2.4.1"
     q "^1.1.2"
 
+codepage@~1.14.0:
+  version "1.14.0"
+  resolved "https://registry.npmmirror.com/codepage/-/codepage-1.14.0.tgz#8cbe25481323559d7d307571b0fff91e7a1d2f99"
+  integrity sha512-iz3zJLhlrg37/gYRWgEPkaFTtzmnEv1h+r7NgZum2lFElYQPi0/5bnmuDfODHxfp0INEfnRqyfyeIJDbb7ahRw==
+  dependencies:
+    commander "~2.14.1"
+    exit-on-epipe "~1.0.1"
+
 collect-v8-coverage@^1.0.0:
   version "1.0.2"
   resolved "https://registry.npmmirror.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9"
@@ -3759,6 +3793,16 @@ commander@^8.3.0:
   resolved "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
   integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
 
+commander@~2.14.1:
+  version "2.14.1"
+  resolved "https://registry.npmmirror.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
+  integrity sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==
+
+commander@~2.17.1:
+  version "2.17.1"
+  resolved "https://registry.npmmirror.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
+  integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
+
 common-path-prefix@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npmmirror.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0"
@@ -3902,6 +3946,11 @@ cosmiconfig@^7.0.0:
     path-type "^4.0.0"
     yaml "^1.10.0"
 
+crc-32@~1.2.0:
+  version "1.2.2"
+  resolved "https://registry.npmmirror.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff"
+  integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==
+
 cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
   version "7.0.3"
   resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
@@ -5012,6 +5061,11 @@ execa@^5.0.0:
     signal-exit "^3.0.3"
     strip-final-newline "^2.0.0"
 
+exit-on-epipe@~1.0.1:
+  version "1.0.1"
+  resolved "https://registry.npmmirror.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692"
+  integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==
+
 exit@^0.1.2:
   version "0.1.2"
   resolved "https://registry.npmmirror.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
@@ -5150,6 +5204,11 @@ file-loader@^6.2.0:
     loader-utils "^2.0.0"
     schema-utils "^3.0.0"
 
+file-saver@^1.3.3:
+  version "1.3.8"
+  resolved "https://registry.npmmirror.com/file-saver/-/file-saver-1.3.8.tgz#e68a30c7cb044e2fb362b428469feb291c2e09d8"
+  integrity sha512-spKHSBQIxxS81N/O21WmuXA2F6wppUCsutpzenOeZzOCCJ5gEfcbqJP983IrpLXzYmXnMUa6J03SubcNPdKrlg==
+
 filelist@^1.0.4:
   version "1.0.4"
   resolved "https://registry.npmmirror.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5"
@@ -5290,6 +5349,11 @@ forwarded@0.2.0:
   resolved "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
   integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
 
+frac@~1.1.2:
+  version "1.1.2"
+  resolved "https://registry.npmmirror.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b"
+  integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==
+
 fraction.js@^4.3.7:
   version "4.3.7"
   resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
@@ -6768,6 +6832,16 @@ js-cookie@^2.x.x:
   resolved "https://registry.npmmirror.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8"
   integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==
 
+js-export-excel@^1.1.4:
+  version "1.1.4"
+  resolved "https://registry.npmmirror.com/js-export-excel/-/js-export-excel-1.1.4.tgz#65ebeb278010f301bee26bba909d7ffec7f28877"
+  integrity sha512-19m7e3Gnn4CRfHXoFrLYj4fFfJ/KpvI7HRRn25p4GXYD+AlTV+1oU24NH6S904Ksi44tSx7futxhouOPAQ22oQ==
+  dependencies:
+    blob.js "^1.0.1"
+    file-saver "^1.3.3"
+    script-loader "0.7.2"
+    xlsx "0.16.3"
+
 "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
   version "4.0.0"
   resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -8342,6 +8416,11 @@ pretty-format@^29.0.0, pretty-format@^29.7.0:
     ansi-styles "^5.0.0"
     react-is "^18.0.0"
 
+printj@~1.1.0:
+  version "1.1.2"
+  resolved "https://registry.npmmirror.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
+  integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
+
 process-nextick-args@~2.0.0:
   version "2.0.1"
   resolved "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -8457,6 +8536,11 @@ raw-body@2.5.1:
     iconv-lite "0.4.24"
     unpipe "1.0.0"
 
+raw-loader@~0.5.1:
+  version "0.5.1"
+  resolved "https://registry.npmmirror.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa"
+  integrity sha512-sf7oGoLuaYAScB4VGr0tzetsYlS8EJH6qnTCfQ/WVEa89hALQ4RQfCKt5xCyPQKPDUbVUAIP1QsxAwfAjlDp7Q==
+
 rc-cascader@~3.21.2:
   version "3.21.2"
   resolved "https://registry.npmmirror.com/rc-cascader/-/rc-cascader-3.21.2.tgz#3421841131cdc15157201fefd955da31f409ac85"
@@ -9408,6 +9492,13 @@ screenfull@^5.0.0:
   resolved "https://registry.npmmirror.com/screenfull/-/screenfull-5.2.0.tgz#6533d524d30621fc1283b9692146f3f13a93d1ba"
   integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==
 
+script-loader@0.7.2:
+  version "0.7.2"
+  resolved "https://registry.npmmirror.com/script-loader/-/script-loader-0.7.2.tgz#2016db6f86f25f5cf56da38915d83378bb166ba7"
+  integrity sha512-UMNLEvgOAQuzK8ji8qIscM3GIrRCWN6MmMXGD4SD5l6cSycgGsCo0tX5xRnfQcoghqct0tjHjcykgI1PyBE2aA==
+  dependencies:
+    raw-loader "~0.5.1"
+
 scroll-into-view-if-needed@^3.1.0:
   version "3.1.0"
   resolved "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz#fa9524518c799b45a2ef6bbffb92bcad0296d01f"
@@ -9676,6 +9767,13 @@ sprintf-js@~1.0.2:
   resolved "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
   integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
 
+ssf@~0.11.2:
+  version "0.11.2"
+  resolved "https://registry.npmmirror.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c"
+  integrity sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==
+  dependencies:
+    frac "~1.1.2"
+
 stable@^0.1.8:
   version "0.1.8"
   resolved "https://registry.npmmirror.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
@@ -10747,11 +10845,21 @@ which@^2.0.1:
   dependencies:
     isexe "^2.0.0"
 
+wmf@~1.0.1:
+  version "1.0.2"
+  resolved "https://registry.npmmirror.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da"
+  integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==
+
 word-wrap@~1.2.3:
   version "1.2.5"
   resolved "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
   integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
 
+word@~0.3.0:
+  version "0.3.0"
+  resolved "https://registry.npmmirror.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961"
+  integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==
+
 workbox-background-sync@6.6.1:
   version "6.6.1"
   resolved "https://registry.npmmirror.com/workbox-background-sync/-/workbox-background-sync-6.6.1.tgz#08d603a33717ce663e718c30cc336f74909aff2f"
@@ -10964,6 +11072,21 @@ ws@^8.13.0:
   resolved "https://registry.npmmirror.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4"
   integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==
 
+xlsx@0.16.3:
+  version "0.16.3"
+  resolved "https://registry.npmmirror.com/xlsx/-/xlsx-0.16.3.tgz#7a91a75eb939db4961122da6f949b8a8f0c8af1a"
+  integrity sha512-LInZ1OK6vpe+Em8XDZ5gDH3WixARwxI7UWc+3chLeafI6gUwECEgL43k4Tjbs1uRfkxpM7wQFy5DLE0hFBRqRw==
+  dependencies:
+    adler-32 "~1.2.0"
+    cfb "^1.1.4"
+    codepage "~1.14.0"
+    commander "~2.17.1"
+    crc-32 "~1.2.0"
+    exit-on-epipe "~1.0.1"
+    ssf "~0.11.2"
+    wmf "~1.0.1"
+    word "~0.3.0"
+
 xml-name-validator@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"