| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- /**
- * 简易文件解析工具
- * 支持从上传的 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) 提取纯文本
- * 简易实现:查找 <w:t> 标签内容
- */
- 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 <w:t> tags
- const regex = /<w:t[^>]*>([^<]*)<\/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 <t> tags in shared strings
- const regex = /<t[^>]*>([^<]*)<\/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);
- }
|