/* eslint-disable */ import { UPLOAD_FILE_MAX_LINE } from "@/app/constant"; import * as XLSX from "xlsx"; import { removeDeepThink } from "../deepThink"; export function toExcel(content: string) { content = removeDeepThink(content); if (hasTable(content)) { htmlToExcel(content); } else { markdownToExcel(content); } } export function hasTable(htmlContent: string): boolean { const parser = new DOMParser(); const doc = parser.parseFromString(htmlContent, "text/html"); return doc.querySelector("table") !== null; } export function markdownToExcel(content: string) { let sheetName = "result"; // 默认表名 let tableContent = ""; // 查找标题内容(以 ** 或 ## 或 ### 开头) const titleMatch = content.match(/^(#{2,3}|\*\*)\s*(.*)/m); if (titleMatch) { sheetName = titleMatch[2].trim().replace(/\s+/g, "_"); // 使用标题作为表名 // 提取表格内容(跳过标题部分) tableContent = content.substring(titleMatch[0].length).trim(); } else { tableContent = content; } // 查找表格的起始位置(第一行以 | 开头且以 | 结尾) let tableStartIndex = -1; const lines = tableContent.split("\n"); for (let i = 0; i < lines.length; i++) { if (lines[i].trim().startsWith("|") && lines[i].trim().endsWith("|")) { tableStartIndex = i; break; } } if (tableStartIndex === -1) { throw new Error("表格内容未找到"); return; } // 查找表格的结束位置(遇到不以 | 开头或者不以 | 结尾的行) let tableEndIndex = -1; for (let i = tableStartIndex; i < lines.length; i++) { if (!lines[i].trim().startsWith("|") || !lines[i].trim().endsWith("|")) { tableEndIndex = i; break; } } if (tableEndIndex === -1) { tableEndIndex = lines.length; } // 提取表格内容 const tableData = lines .slice(tableStartIndex, tableEndIndex) .join("\n") .trim(); // 解析表格内容 const rows = tableData.split("\n"); const data: any[] = []; let headers: string[] = []; rows.forEach((row, rowIndex) => { // 去掉行首尾的 | 符号,并按 | 分割 const cells = row .replace(/^\s*\|/g, "") .replace(/\|\s*$/g, "") .split(/\s*\|\s*/); // 跳过分隔线(假设分隔线的每个单元格都是由短横线组成) if ( rowIndex > 0 && cells.every( (cell) => cell.trim().replace(/-/g, "").length === 0, // 检查单元格内容是否只包含短横线 ) ) { return; } if (rowIndex === 0) { // 第一行是表头 headers = cells.map((cell) => cell.trim()); } else { // 数据行 const rowData: any = {}; cells.forEach((cell, cellIndex) => { if (cellIndex < headers.length) { rowData[headers[cellIndex]] = cell.trim(); } }); data.push(rowData); } }); // 创建工作表 const ws = XLSX.utils.json_to_sheet(data); const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, sheetName); // 生成文件并下载 XLSX.writeFile(wb, `${sheetName}.xlsx`); } export function getExcelData(file: File): Promise<any[][]> { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { try { const data = e.target?.result; if (!data) { reject(new Error("Failed to read file data")); return; } const workbook = XLSX.read(data, { type: "array" }); const firstSheetName = workbook.SheetNames[0]; const worksheet = workbook.Sheets[firstSheetName]; // 使用类型断言将 unknown[] 转换为 any[][] const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1, }) as any[][]; resolve(jsonData.slice(0, UPLOAD_FILE_MAX_LINE)); } catch (error) { reject(error); } }; reader.onerror = (error) => { reject(error); }; reader.readAsArrayBuffer(file); }); } export function htmlToExcel(htmlContent: string) { const parser = new DOMParser(); const doc = parser.parseFromString(htmlContent, "text/html"); const table = doc.querySelector("table"); if (!table) { return []; } const rows = table.querySelectorAll("tr"); const tableData: string[][] = []; // 提取表格数据(包含表头) rows.forEach((row) => { const cells = row.querySelectorAll("td, th"); const rowData: string[] = []; cells.forEach((cell) => { rowData.push(cell.textContent?.trim() || ""); }); tableData.push(rowData); }); // 使用二维数组直接创建工作表 const ws = XLSX.utils.aoa_to_sheet(tableData); // 创建工作簿并保存 const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); XLSX.writeFile(wb, "export.xlsx"); }