import { useState } from 'react' import * as XLSX from 'xlsx' import { Table, Select, Pagination } from 'antd' import type { ColumnsType, ColumnType } from 'antd/es/table' import { UploadOutlined } from '@ant-design/icons' interface TableData { key: string [key: string]: any } export default function WeekPlanPage() { const [data, setData] = useState([]) const [columns, setColumns] = useState>([]) const [currentPage, setCurrentPage] = useState(1) const [trainingStatus, setTrainingStatus] = useState>({}) const pageSize = 1 // 每页显示一个第一列的唯一值 const handleFileUpload = (event: React.ChangeEvent) => { const file = event.target.files?.[0] if (!file) return const reader = new FileReader() reader.onload = (e) => { const data = new Uint8Array(e.target?.result as ArrayBuffer) const workbook = XLSX.read(data, { type: 'array' }) const firstSheet = workbook.Sheets[workbook.SheetNames[0]] // 处理合并单元格 if (firstSheet['!merges']) { firstSheet['!merges'].forEach(merge => { // 获取合并区域的起始单元格的值 const firstCell = XLSX.utils.encode_cell({ r: merge.s.r, c: merge.s.c }) const firstCellValue = firstSheet[firstCell]?.v // 将合并区域内的所有单元格设置为相同的值 for (let row = merge.s.r; row <= merge.e.r; row++) { for (let col = merge.s.c; col <= merge.e.c; col++) { const cell = XLSX.utils.encode_cell({ r: row, c: col }) if (!firstSheet[cell]) { firstSheet[cell] = { t: 's', v: firstCellValue } } } } }) } const jsonData: any[] = XLSX.utils.sheet_to_json(firstSheet, { header: 1, defval: '', blankrows: false, raw: false }) // 处理表头和数据 const headers = jsonData[0] const tableData: TableData[] = jsonData.slice(1).map((row, index) => ({ key: index.toString(), ...headers.reduce((acc: any, header: string, idx: number) => { acc[header] = row[idx] return acc }, {}) })) // 创建列配置 const tableColumns: ColumnsType = headers.map((header: string, index: number) => ({ title: header, dataIndex: header, key: header, width: 150, align: 'center', filterMultiple: true, filters: Array.from(new Set(tableData.map(item => item[header]))) .filter(Boolean) .map(value => ({ text: String(value), value: String(value) })), onFilter: (value, record) => String(record[header]) === value, ...(index < headers.length - 1 && { render: (text, record, index) => ({ children: text, props: { rowSpan: calculateRowSpan(tableData, index, header), style: { border: '1px solid #f0f0f0', borderBottom: '1px solid #f0f0f0' } } }) }) })) // 添加是否参训列 tableColumns.push({ title: '是否参训', dataIndex: 'isTraining', key: 'isTraining', width: 120, align: 'center', render: (_, record) => (

点击或拖拽文件到此处上传

支持 .xlsx, .xls 格式的Excel文件

{data.length > 0 && ( <>
item[(columns[0] as ColumnType)?.dataIndex as string] ))).filter(Boolean).length} pageSize={1} onChange={(page) => { setCurrentPage(page) }} /> )} ) }