|
|
@@ -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>
|