file-parser.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /**
  2. * 简易文件解析工具
  3. * 支持从上传的 Excel/Word 文件中提取文本内容
  4. * 注意:完整实现需要 xlsx / mammoth 等库,此处提供基础文本提取
  5. */
  6. /**
  7. * 从文件 Buffer 提取可读文本
  8. * 对于 .docx 文件提取 XML 内的文本节点
  9. * 对于 .xlsx 文件提取 sharedStrings 中的文本
  10. */
  11. export function extractTextFromBuffer(buffer: Buffer, fileName: string): string {
  12. const ext = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();
  13. console.log(`[FileParser] 文件: ${fileName}, 扩展名: ${ext}, buffer大小: ${buffer.length} bytes`);
  14. let result: string;
  15. if (ext === '.docx') {
  16. result = extractDocxText(buffer);
  17. } else if (ext === '.xlsx' || ext === '.xls') {
  18. result = extractXlsxText(buffer);
  19. } else {
  20. // Fallback: try to read as plain text
  21. result = buffer.toString('utf-8').slice(0, 50000);
  22. }
  23. console.log(`[FileParser] 提取文本长度: ${result.length} 字符`);
  24. console.log(`[FileParser] 文本前300字: ${result.substring(0, 300)}`);
  25. return result;
  26. }
  27. /**
  28. * 从 .docx (ZIP 内的 XML) 提取纯文本
  29. * 简易实现:查找 <w:t> 标签内容
  30. */
  31. function extractDocxText(buffer: Buffer): string {
  32. // .docx is a ZIP file; for now, do regex extraction on raw buffer
  33. // A production implementation would use a proper ZIP + XML parser
  34. const raw = buffer.toString('utf-8');
  35. const textParts: string[] = [];
  36. // Extract text between <w:t> tags
  37. const regex = /<w:t[^>]*>([^<]*)<\/w:t>/g;
  38. let match: RegExpExecArray | null;
  39. while ((match = regex.exec(raw)) !== null) {
  40. if (match[1]) {
  41. textParts.push(match[1]);
  42. }
  43. }
  44. if (textParts.length > 0) {
  45. return textParts.join(' ');
  46. }
  47. // Fallback: extract any readable text segments
  48. return extractReadableText(buffer);
  49. }
  50. /**
  51. * 从 .xlsx (ZIP 内的 sharedStrings.xml) 提取文本
  52. */
  53. function extractXlsxText(buffer: Buffer): string {
  54. const raw = buffer.toString('utf-8');
  55. const textParts: string[] = [];
  56. // Extract text from <t> tags in shared strings
  57. const regex = /<t[^>]*>([^<]*)<\/t>/g;
  58. let match: RegExpExecArray | null;
  59. while ((match = regex.exec(raw)) !== null) {
  60. if (match[1] && match[1].trim()) {
  61. textParts.push(match[1].trim());
  62. }
  63. }
  64. if (textParts.length > 0) {
  65. return textParts.join(' | ');
  66. }
  67. return extractReadableText(buffer);
  68. }
  69. /**
  70. * 从二进制数据提取可读文本段
  71. */
  72. function extractReadableText(buffer: Buffer): string {
  73. const text = buffer.toString('utf-8');
  74. // Filter to only printable characters and common Chinese
  75. const readable = text.replace(/[^\u4e00-\u9fff\u0020-\u007e\u00a0-\u00ff\n\r\t]/g, ' ');
  76. // Collapse whitespace
  77. return readable.replace(/\s+/g, ' ').trim().slice(0, 30000);
  78. }