/** * 简易文件解析工具 * 支持从上传的 Excel/Word 文件中提取文本内容 * 注意:完整实现需要 xlsx / mammoth 等库,此处提供基础文本提取 */ /** * 从文件 Buffer 提取可读文本 * 对于 .docx 文件提取 XML 内的文本节点 * 对于 .xlsx 文件提取 sharedStrings 中的文本 */ export function extractTextFromBuffer(buffer: Buffer, fileName: string): string { const ext = fileName.substring(fileName.lastIndexOf('.')).toLowerCase(); console.log(`[FileParser] 文件: ${fileName}, 扩展名: ${ext}, buffer大小: ${buffer.length} bytes`); let result: string; if (ext === '.docx') { result = extractDocxText(buffer); } else if (ext === '.xlsx' || ext === '.xls') { result = extractXlsxText(buffer); } else { // Fallback: try to read as plain text result = buffer.toString('utf-8').slice(0, 50000); } console.log(`[FileParser] 提取文本长度: ${result.length} 字符`); console.log(`[FileParser] 文本前300字: ${result.substring(0, 300)}`); return result; } /** * 从 .docx (ZIP 内的 XML) 提取纯文本 * 简易实现:查找 标签内容 */ function extractDocxText(buffer: Buffer): string { // .docx is a ZIP file; for now, do regex extraction on raw buffer // A production implementation would use a proper ZIP + XML parser const raw = buffer.toString('utf-8'); const textParts: string[] = []; // Extract text between tags const regex = /]*>([^<]*)<\/w:t>/g; let match: RegExpExecArray | null; while ((match = regex.exec(raw)) !== null) { if (match[1]) { textParts.push(match[1]); } } if (textParts.length > 0) { return textParts.join(' '); } // Fallback: extract any readable text segments return extractReadableText(buffer); } /** * 从 .xlsx (ZIP 内的 sharedStrings.xml) 提取文本 */ function extractXlsxText(buffer: Buffer): string { const raw = buffer.toString('utf-8'); const textParts: string[] = []; // Extract text from tags in shared strings const regex = /]*>([^<]*)<\/t>/g; let match: RegExpExecArray | null; while ((match = regex.exec(raw)) !== null) { if (match[1] && match[1].trim()) { textParts.push(match[1].trim()); } } if (textParts.length > 0) { return textParts.join(' | '); } return extractReadableText(buffer); } /** * 从二进制数据提取可读文本段 */ function extractReadableText(buffer: Buffer): string { const text = buffer.toString('utf-8'); // Filter to only printable characters and common Chinese const readable = text.replace(/[^\u4e00-\u9fff\u0020-\u007e\u00a0-\u00ff\n\r\t]/g, ' '); // Collapse whitespace return readable.replace(/\s+/g, ' ').trim().slice(0, 30000); }