shaogen1995 2 месяцев назад
Родитель
Сommit
325daac3bf
7 измененных файлов с 4457 добавлено и 4863 удалено
  1. 488 458
      package-lock.json
  2. 2 1
      package.json
  3. 27 5
      src/pages/Bresource/B1overview/index.tsx
  4. 1 1
      src/types/declaration.d.ts
  5. 2 2
      src/utils/dataChange.ts
  6. 132 0
      src/utils/index.ts
  7. 3805 4396
      yarn.lock

Разница между файлами не показана из-за своего большого размера
+ 488 - 458
package-lock.json


+ 2 - 1
package.json

@@ -37,7 +37,8 @@
     "sass": "^1.55.0",
     "typescript": "^4.8.4",
     "web-vitals": "^2.1.4",
-    "xlsx": "^0.18.5"
+    "xlsx": "^0.18.5",
+    "xlsx-js-style": "^1.2.0"
   },
   "scripts": {
     "dev": "react-app-rewired start",

+ 27 - 5
src/pages/Bresource/B1overview/index.tsx

@@ -7,7 +7,7 @@ import { getKuListByOpenFu } from '@/pages/Zother/data'
 import { ziyuanAcGet, ziyuanAcSet } from '@/utils/storage'
 import { APIdelTable, APIdownXlsx, B1_APIgetList } from '@/store/action/Bresource/B1overview'
 import { RootState } from '@/store'
-import { Button, Cascader, Input, Select } from 'antd'
+import { Button, Cascader, Input, Select, message } from 'antd'
 import { Z1_APIgetFormZiDuan } from '@/store/action/Zsystem/Z1sysSet'
 import { baseFormType } from '@/pages/Zsystem/Z1sysSet/data'
 import { treeOneIdByResFu } from '@/pages/Zother/Z1formSet/data'
@@ -16,7 +16,7 @@ import { MessageFu } from '@/utils/message'
 import Z0sonTable from '@/components/Z0sonTable'
 import { openLink } from '@/utils/history'
 import MyPopconfirm from '@/components/MyPopconfirm'
-import { downloadFileByUrl } from '@/utils'
+import { downloadFileByUrl, transformTableDataForExport, downloadExcel } from '@/utils'
 function B1overview() {
   const [kuList, setKuList] = useState<antdSelectType[]>([])
 
@@ -160,7 +160,7 @@ function B1overview() {
       {
         title: '入库状态',
         width: 100,
-        render: (item: any) => tableSelectToTxt(item.status_storage, selectObj['入库状态'])
+        render: (item: any) => tableSelectToTxt(item.status_storage, selectObj['入库状态'], '入库')
       },
       {
         title: '发布状态',
@@ -215,6 +215,11 @@ function B1overview() {
 
   // 点击数据导出
   const deriveFu = useCallback(async () => {
+    if (!formZi.length) {
+      MessageFu.warning('请先获取表单字段')
+      return
+    }
+
     const obj = {
       ...formDataOldRef.current,
       pageNum: 1,
@@ -230,12 +235,29 @@ function B1overview() {
 
     obj.dictQuery = sonObj
 
+    const hideLoading = message.loading('正在导出...', 0)
     const res = await B1_APIgetList(obj, true)
+    hideLoading()
+
     if (res.code === 0) {
       const list = res.data.records || []
-      console.log('-----------', list)
+      if (!list.length) {
+        MessageFu.warning('没有可导出的数据')
+        return
+      }
+
+      // 转换数据为导出格式
+      const { headers, data } = transformTableDataForExport(list, formZi, selectObj)
+
+      // 获取文件名(使用资源库名称)
+      const kuObj = kuList.find(v => v.value === formData.formDefId)
+      const fileName = kuObj ? `${kuObj.label}-数据导出` : '数据导出'
+
+      // 下载 Excel 文件
+      downloadExcel(headers, data, fileName)
+      MessageFu.success('导出成功')
     }
-  }, [])
+  }, [formZi, formData.formDefId, kuList])
 
   return (
     <div className={styles.B1overview}>

+ 1 - 1
src/types/declaration.d.ts

@@ -4,6 +4,6 @@ declare module '*.png'
 declare module '*.jpg'
 declare module '*.gif'
 declare module '*.svg'
-declare module 'js-export-excel'
+declare module 'xlsx-js-style'
 declare module 'braft-utils'
 declare module 'file-saver'

+ 2 - 2
src/utils/dataChange.ts

@@ -55,9 +55,9 @@ export const selectObj = {
 export type antdSelectType = { value: number; label: string; isEnabled: 0 | 1 }
 
 // 表格下拉
-export const tableSelectToTxt = (val: number, arr: any[]) => {
+export const tableSelectToTxt = (val: number, arr: any[], flag?: string) => {
   let txt = '(空)'
-  const obj = arr.find(v => v.value === (val || 0))
+  const obj = arr.find(v => v.value === (val || (flag ? 1 : 0)))
   if (obj) txt = obj.label
   return txt
 }

+ 132 - 0
src/utils/index.ts

@@ -1,5 +1,6 @@
 import store from '@/store'
 import { baseURL } from './http'
+import { tableSelectToTxt } from './dataChange'
 
 // 上传文件自动归类
 type FileObjType = {
@@ -101,3 +102,134 @@ export const dictIdByName = (ids: string): string => {
 
   return names && names.length ? names.join(' / ') : '(空)'
 }
+
+/**
+ * 将表格数据转换为 Excel 导出格式(带表头,按指定顺序)
+ * @param list 原始数据列表
+ * @param formZi 动态表单字段配置
+ * @param selectObj 状态下拉选项对象
+ * @param filterLabels 需要过滤的字段标签(如操作列、排序值等)
+ * @returns { headers: 表头数组, data: 数据数组 }
+ */
+export const transformTableDataForExport = (
+  list: any[],
+  formZi: any[],
+  selectObj: any,
+  filterLabels: string[] = [
+    '操作',
+    '附件',
+    '大封面',
+    '关联资源',
+    '排序值',
+    '入库状态',
+    '发布状态',
+    '推荐状态',
+    '封面',
+    '权限级'
+  ]
+) => {
+  // 过滤掉不需要导出的动态字段
+  const filteredFormZi = formZi.filter(v => !filterLabels.includes(v.fieldLabel))
+
+  // 构建表头数组(按顺序)
+  const headers: string[] = ['资源编码', '资源名称', '责任者', '封面', '权限级']
+
+  // 添加动态表单字段的表头
+  filteredFormZi.forEach(field => {
+    headers.push(field.fieldLabel)
+  })
+
+  // 创建时间
+  headers.push('创建时间')
+
+  // 状态字段放到最后
+  headers.push('入库状态')
+  headers.push('发布状态')
+  headers.push('推荐状态')
+
+  // 构建数据数组(按表头顺序)
+  const data = list.map(item => {
+    const fengMian = item.thumbPc
+      ? baseURL + item.thumbPc
+      : item.thumb
+        ? baseURL + item.thumb
+        : '(空)'
+
+    const row: any[] = []
+
+    // 1. 固定列数据
+    row.push(item.num || '(空)')
+    row.push(item.name || '(空)')
+    row.push(item.create_by || '(空)')
+    row.push(fengMian) // 封面用路径字符串
+    row.push(item.level_perm || '(空)')
+
+    // 2. 动态表单字段数据转换
+    filteredFormZi.forEach(field => {
+      const value = item[field.fieldName]
+      if (['文本', '数字'].includes(field.tag)) {
+        row.push(value || '(空)')
+      } else if (['关联字典', '关联标签'].includes(field.tag)) {
+        row.push(dictIdByName(value))
+      } else if (field.tag === '下拉') {
+        row.push(value || '(空)')
+      } else {
+        row.push('(空)')
+      }
+    })
+
+    // 3. 创建时间
+    row.push(item.create_time || '(空)')
+
+    // 4. 状态字段放到最后(数字转文本)
+    row.push(tableSelectToTxt(item.status_storage, selectObj['入库状态'], '入库'))
+    row.push(tableSelectToTxt(item.status_publish, selectObj['发布状态']))
+    row.push(tableSelectToTxt(item.status_hot, selectObj['推荐状态']))
+
+    return row
+  })
+
+  return { headers, data }
+}
+
+/**
+ * 生成并下载 Excel 文件(表头加粗)
+ * @param headers 表头数组
+ * @param data 数据数组
+ * @param fileName 文件名
+ */
+export const downloadExcel = (headers: string[], data: any[], fileName: string = '导出数据') => {
+  // 动态导入 xlsx-js-style
+  import('xlsx-js-style').then(XLSX => {
+    // 构建完整数据(表头 + 数据)
+    const sheetData = [headers, ...data]
+
+    // 创建工作表
+    const ws = XLSX.utils.aoa_to_sheet(sheetData)
+
+    // 设置表头样式(第一行加粗)
+    const colCount = headers.length
+    for (let col = 0; col < colCount; col++) {
+      const cellRef = XLSX.utils.encode_cell({ r: 0, c: col }) // 第一行,第 col 列
+      if (ws[cellRef]) {
+        ws[cellRef].s = {
+          font: {
+            bold: true,
+            sz: 12
+          },
+          alignment: {
+            horizontal: 'center',
+            vertical: 'center'
+          }
+        }
+      }
+    }
+
+    // 创建工作簿
+    const wb = XLSX.utils.book_new()
+    XLSX.utils.book_append_sheet(wb, ws, '数据列表')
+
+    // 导出文件
+    XLSX.writeFile(wb, `${fileName}.xlsx`)
+  })
+}

Разница между файлами не показана из-за своего большого размера
+ 3805 - 4396
yarn.lock