huminmin
10 天以前 0268f58a18bfcf061389387ef5322bf11aece154
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package com.ruoyi.ai.service;
 
import com.ruoyi.common.utils.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
 
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
 
@Component
public class AiFileTextExtractor {
 
    private static final long MAX_FILE_SIZE = 10L * 1024 * 1024;
 
    public String extractText(MultipartFile file) throws IOException {
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("文件不能为空");
        }
        if (file.getSize() > MAX_FILE_SIZE) {
            throw new IllegalArgumentException("文件过大,请控制在10MB以内");
        }
 
        String filename = file.getOriginalFilename();
        String ext = getExtension(filename);
        byte[] bytes = file.getBytes();
 
        if (isPlainText(ext)) {
            return decodeText(bytes);
        }
        if ("docx".equals(ext)) {
            return extractDocx(bytes);
        }
        if ("xlsx".equals(ext)) {
            return extractXlsx(bytes);
        }
        if ("xls".equals(ext)) {
            return extractXls(bytes);
        }
        throw new IllegalArgumentException("暂不支持该文件类型: " + ext);
    }
 
    private String extractDocx(byte[] bytes) throws IOException {
        try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
             XWPFDocument document = new XWPFDocument(inputStream);
             XWPFWordExtractor extractor = new XWPFWordExtractor(document)) {
            return extractor.getText();
        }
    }
 
    private String extractXlsx(byte[] bytes) throws IOException {
        try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
             XSSFWorkbook workbook = new XSSFWorkbook(inputStream)) {
            return extractWorkbook(workbook);
        }
    }
 
    private String extractXls(byte[] bytes) throws IOException {
        try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
             HSSFWorkbook workbook = new HSSFWorkbook(inputStream)) {
            return extractWorkbook(workbook);
        }
    }
 
    private String extractWorkbook(org.apache.poi.ss.usermodel.Workbook workbook) {
        StringBuilder text = new StringBuilder();
        DataFormatter formatter = new DataFormatter();
        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
            Sheet sheet = workbook.getSheetAt(i);
            text.append("Sheet: ").append(sheet.getSheetName()).append("\n");
            for (Row row : sheet) {
                short lastCellNum = row.getLastCellNum();
                if (lastCellNum <= 0) {
                    text.append("\n");
                    continue;
                }
                for (int c = 0; c < lastCellNum; c++) {
                    String cellText = formatter.formatCellValue(row.getCell(c));
                    text.append(cellText);
                    if (c < lastCellNum - 1) {
                        text.append('\t');
                    }
                }
                text.append('\n');
            }
        }
        return text.toString();
    }
 
    private String decodeText(byte[] bytes) {
        String utf8 = new String(bytes, StandardCharsets.UTF_8);
        if (utf8.contains("�")) {
            return new String(bytes, java.nio.charset.Charset.forName("GBK"));
        }
        return utf8;
    }
 
    private String getExtension(String filename) {
        if (!StringUtils.hasText(filename) || !filename.contains(".")) {
            return "";
        }
        return filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
    }
 
    private boolean isPlainText(String ext) {
        return StringUtils.inStringIgnoreCase(ext,
                "txt", "md", "markdown", "json", "xml", "yaml", "yml", "csv", "log", "properties",
                "java", "js", "ts", "vue", "html", "css", "sql", "py", "go", "sh", "bat");
    }
}