shaogen1995 2 miesięcy temu
rodzic
commit
721cbd2dc9

+ 4 - 2
src/pages/Aanalyse/A1resStat/data.ts

@@ -1,7 +1,7 @@
 import * as echarts from 'echarts'
 
 // 生成柱状图
-export const initEchZhuFu = (data: any[], dom: any, title: string) => {
+export const initEchZhuFu = (data: any[], dom: any, title: string, back: (id: string) => void) => {
   if (!dom) return
 
   // 销毁已存在的实例
@@ -13,7 +13,7 @@ export const initEchZhuFu = (data: any[], dom: any, title: string) => {
   const myChart = echarts.init(dom)
 
   // 根据类型获取数据
-  const chartData = data.map(v => ({ value: v.pcs || 0, name: v.name }))
+  const chartData = data.map(v => ({ id: v.id, value: v.pcs || 0, name: (v.num || '') + v.name }))
   const total = chartData.reduce((sum, item) => sum + item.value, 0)
 
   const option = {
@@ -108,6 +108,8 @@ export const initEchZhuFu = (data: any[], dom: any, title: string) => {
       系列名称: params.seriesName,
       数据索引: params.dataIndex
     })
+    // 把id传出去
+    // back()
   })
 
   // 自适应

+ 241 - 2
src/pages/Aanalyse/A1resStat/index.tsx

@@ -13,6 +13,7 @@ import {
 import { antdSelectType } from '@/utils/dataChange'
 import { getKuListByOpenFu } from '@/pages/Zother/data'
 import { ziyuanAcGet } from '@/utils/storage'
+import { MessageFu } from '@/utils/message'
 function A1resStat() {
   // 1--------------------------------获取资源总数
   const [allNum, setAllNum] = useState<any>({})
@@ -83,7 +84,9 @@ function A1resStat() {
   useEffect(() => {
     if (zhuData.list && zhuData.list.length) {
       zhuData.list.forEach((v, i) => {
-        initEchZhuFu(v.children, document.querySelector(`#echZhu${i + 1}`), v.name)
+        initEchZhuFu(v.children, document.querySelector(`#echZhu${i + 1}`), v.name, id => {
+          setZhuSonId(id)
+        })
       })
     }
   }, [zhuData])
@@ -145,6 +148,240 @@ function A1resStat() {
     getBingDataFu()
   }, [getBingDataFu])
 
+  // 导出Excel功能
+  const exportExcelFu = useCallback(async () => {
+    try {
+      // 动态导入 xlsx-js-style
+      const XLSX = await import('xlsx-js-style')
+
+      // 创建工作簿
+      const wb = XLSX.utils.book_new()
+
+      // 创建一个工作表(使用空数组初始化,后续手动添加数据)
+      const wsData: any[][] = []
+
+      // 获取选择的资源库名称
+      const kuName1 = kuList.find(item => String(item.value) === String(kuId1))?.label || '未选择'
+      const kuName2 = kuList.find(item => String(item.value) === String(kuId2))?.label || '未选择'
+
+      // ========== 第1部分:总览统计 ==========
+      wsData.push(['资源统计报表'])
+      wsData.push(['导出时间:' + dayjs().format('YYYY-MM-DD HH:mm:ss')])
+      wsData.push([]) // 空行
+
+      // 添加总览统计表格
+      wsData.push(['一、总览统计'])
+      wsData.push(['统计项', '数量'])
+      wsData.push(['总资源数', allNum.total || 0])
+      wsData.push(['已发布资源数', allNum.pcsPublish || 0])
+      wsData.push(['公开级资源', allNum.pcsLevelPermOpen || 0])
+      wsData.push(['内部级资源', allNum.pcsLevelPermIn || 0])
+      wsData.push(['年度新增资源数量(' + time + '年)', yearNum || 0])
+      wsData.push([]) // 空行
+      wsData.push([]) // 空行
+
+      // ========== 第2部分:字典统计(柱状图数据)==========
+      wsData.push(['二、字典统计'])
+      wsData.push(['资源库:' + kuName1])
+      if (zhuData.list && zhuData.list.length > 0) {
+        zhuData.list.forEach((category, index) => {
+          // 分类标题
+          wsData.push([`${index + 1}. ${category.name}`])
+
+          if (category.children && category.children.length > 0) {
+            // 计算总数
+            const total = category.children.reduce(
+              (sum: number, item: any) => sum + (item.pcs || 0),
+              0
+            )
+
+            // 表头
+            wsData.push(['分类名称', '数量', '占比'])
+
+            // 数据行
+            category.children.forEach((item: any) => {
+              const percent = total > 0 ? ((item.pcs / total) * 100).toFixed(1) + '%' : '0%'
+              wsData.push([(item.num || '') + item.name || '(空)', item.pcs || 0, percent])
+            })
+
+            // 合计行
+            wsData.push(['合计', total, '100%'])
+          } else {
+            wsData.push(['暂无数据'])
+          }
+          wsData.push([]) // 空行
+        })
+      } else {
+        wsData.push(['暂无数据'])
+        wsData.push([]) // 空行
+      }
+      wsData.push([]) // 空行
+
+      // ========== 第3部分:资源库资源数统计(饼图数据)==========
+      wsData.push(['三、资源库资源数统计'])
+      if (defCount.current && defCount.current.length > 0) {
+        // 计算总数
+        const total = defCount.current.reduce((sum: number, item: any) => sum + (item.pcs || 0), 0)
+
+        // 表头
+        wsData.push(['资源库名称', '资源数量', '占比'])
+
+        // 数据行
+        defCount.current.forEach((item: any) => {
+          const percent = total > 0 ? ((item.pcs / total) * 100).toFixed(1) + '%' : '0%'
+          wsData.push([item.name || '(空)', item.pcs || 0, percent])
+        })
+
+        // 合计行
+        wsData.push(['合计', total, '100%'])
+      } else {
+        wsData.push(['暂无数据'])
+      }
+      wsData.push([]) // 空行
+      wsData.push([]) // 空行
+
+      // ========== 第4部分:标签统计(饼图数据)==========
+      wsData.push(['四、标签统计'])
+      wsData.push(['资源库:' + kuName2])
+      if (bingData.list && bingData.list.length > 0) {
+        bingData.list.forEach((category, index) => {
+          // 分类标题
+          wsData.push([`${index + 1}. ${category.name}`])
+
+          if (category.children && category.children.length > 0) {
+            // 计算总数
+            const total = category.children.reduce(
+              (sum: number, item: any) => sum + (item.pcs || 0),
+              0
+            )
+
+            // 表头
+            wsData.push(['标签名称', '数量', '占比'])
+
+            // 数据行
+            category.children.forEach((item: any) => {
+              const percent = total > 0 ? ((item.pcs / total) * 100).toFixed(1) + '%' : '0%'
+              wsData.push([item.name || '(空)', item.pcs || 0, percent])
+            })
+
+            // 合计行
+            wsData.push(['合计', total, '100%'])
+          } else {
+            wsData.push(['暂无数据'])
+          }
+          wsData.push([]) // 空行
+        })
+      } else {
+        wsData.push(['暂无数据'])
+        wsData.push([]) // 空行
+      }
+
+      // 创建工作表
+      const ws = XLSX.utils.aoa_to_sheet(wsData)
+
+      // 设置列宽
+      ws['!cols'] = [
+        { wch: 30 }, // 第1列
+        { wch: 15 }, // 第2列
+        { wch: 12 } // 第3列
+      ]
+
+      // 手动设置样式:遍历所有单元格
+      const rowCount = wsData.length
+      const colCount = 3
+
+      for (let r = 0; r < rowCount; r++) {
+        for (let c = 0; c < colCount; c++) {
+          const cellRef = XLSX.utils.encode_cell({ r: r, c: c })
+          if (ws[cellRef]) {
+            // 判断是否为标题行或表头行
+            const cellValue = wsData[r][c]
+            const isTitle =
+              r === 0 || // 报表标题
+              cellValue === '一、总览统计' ||
+              cellValue === '二、字典统计' ||
+              cellValue === '三、资源库资源数统计' ||
+              cellValue === '四、标签统计' ||
+              cellValue?.toString()?.startsWith?.('资源库:') || // 资源库信息行
+              cellValue?.toString()?.startsWith?.('1.') ||
+              cellValue?.toString()?.startsWith?.('2.') ||
+              cellValue?.toString()?.startsWith?.('3.') ||
+              cellValue?.toString()?.startsWith?.('4.') ||
+              cellValue?.toString()?.startsWith?.('5.') ||
+              cellValue?.toString()?.startsWith?.('6.') ||
+              cellValue?.toString()?.startsWith?.('7.') ||
+              cellValue?.toString()?.startsWith?.('8.') ||
+              cellValue?.toString()?.startsWith?.('9.') ||
+              cellValue?.toString()?.startsWith?.('10.')
+
+            const isTableHeader =
+              cellValue === '统计项' ||
+              cellValue === '分类名称' ||
+              cellValue === '标签名称' ||
+              cellValue === '资源库名称' ||
+              cellValue === '数量' ||
+              cellValue === '占比'
+
+            const isTotalRow = cellValue === '合计'
+
+            if (isTitle || isTableHeader || isTotalRow) {
+              ws[cellRef].s = {
+                font: {
+                  bold: true,
+                  sz: isTitle ? 14 : 12
+                },
+                alignment: {
+                  horizontal: 'center',
+                  vertical: 'center'
+                },
+                fill: isTableHeader
+                  ? {
+                      fgColor: { rgb: 'E6F3FF' }
+                    }
+                  : undefined
+              }
+            } else if (r === 1) {
+              // 导出时间行
+              ws[cellRef].s = {
+                font: {
+                  sz: 10,
+                  color: { rgb: '666666' }
+                }
+              }
+            } else {
+              // 普通数据单元格
+              ws[cellRef].s = {
+                alignment: {
+                  horizontal: 'center',
+                  vertical: 'center'
+                }
+              }
+            }
+          }
+        }
+      }
+
+      // 合并第一行标题单元格
+      ws['!merges'] = [
+        { s: { r: 0, c: 0 }, e: { r: 0, c: 2 } } // 合并第1行的第0-2列
+      ]
+
+      // 添加工作表到工作簿
+      XLSX.utils.book_append_sheet(wb, ws, '资源统计')
+
+      // 导出文件
+      XLSX.writeFile(wb, `资源统计报表_${dayjs().format('YYYY-MM-DD_HH-mm-ss')}.xlsx`)
+
+      MessageFu.success('导出成功')
+    } catch (error) {
+      MessageFu.error('导出失败')
+      console.error('导出错误:', error)
+    }
+  }, [allNum, time, yearNum, zhuData, bingData, kuId1, kuId2, kuList])
+
+  // 点击柱子打开弹窗
+  const [zhuSonId, setZhuSonId] = useState('')
+
   return (
     <div className={styles.A1resStat}>
       <div className='pageTitle'>资源统计</div>
@@ -229,7 +466,9 @@ function A1resStat() {
       </div>
       <div className='A1trr'>
         <div className='A1trrTop'>
-          <Button type='primary'>数据导出</Button>
+          <Button type='primary' onClick={exportExcelFu}>
+            数据导出
+          </Button>
         </div>
         <div className='A1trrMain A1box'>
           <div className='A1tit'>资源库资源数统计</div>