Skip to content

Commit 4a2dc21

Browse files
committed
增加序列化能力和修改格式
1 parent 3384e17 commit 4a2dc21

File tree

9 files changed

+144
-76
lines changed

9 files changed

+144
-76
lines changed

app-builder/plugins/aipp-file-extract-excel/pom.xml

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,6 @@
2222
<groupId>org.fitframework</groupId>
2323
<artifactId>fit-util</artifactId>
2424
</dependency>
25-
<dependency>
26-
<groupId>org.junit.jupiter</groupId>
27-
<artifactId>junit-jupiter</artifactId>
28-
</dependency>
29-
<dependency>
30-
<groupId>org.fitframework</groupId>
31-
<artifactId>fit-test-framework</artifactId>
32-
</dependency>
33-
<dependency>
34-
<groupId>org.assertj</groupId>
35-
<artifactId>assertj-core</artifactId>
36-
</dependency>
3725

3826
<!-- fast excel -->
3927
<dependency>
@@ -50,6 +38,23 @@
5038
<groupId>modelengine.fit.jade</groupId>
5139
<artifactId>aipp-service</artifactId>
5240
</dependency>
41+
42+
<!-- Tests -->
43+
<dependency>
44+
<groupId>org.junit.jupiter</groupId>
45+
<artifactId>junit-jupiter</artifactId>
46+
<scope>test</scope>
47+
</dependency>
48+
<dependency>
49+
<groupId>org.fitframework</groupId>
50+
<artifactId>fit-test-framework</artifactId>
51+
<scope>test</scope>
52+
</dependency>
53+
<dependency>
54+
<groupId>org.assertj</groupId>
55+
<artifactId>assertj-core</artifactId>
56+
<scope>test</scope>
57+
</dependency>
5358
</dependencies>
5459

5560
<build>

app-builder/plugins/aipp-file-extract-excel/src/main/java/modelengine/fit/jade/aipp/file/extract/ExcelFileExtractor.java

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@
2828
import java.io.InputStream;
2929
import java.math.BigDecimal;
3030
import java.nio.file.Files;
31+
import java.nio.file.InvalidPathException;
32+
import java.nio.file.Path;
3133
import java.nio.file.Paths;
3234
import java.text.SimpleDateFormat;
35+
import java.util.Arrays;
3336
import java.util.Date;
3437
import java.util.List;
3538
import java.util.Map;
@@ -38,16 +41,16 @@
3841
/**
3942
* Excel文件的提取器。
4043
*
41-
* @author jsbjfkbsjk
42-
* @since 2025-9-6
44+
* @author 黄政炫
45+
* @since 2025-09-06
4346
*/
4447
@Component
45-
public class ExcelFileExtractor implements AbstractFileExtractor {
48+
public class ExcelFileExtractor implements FileExtraction {
4649
/**
47-
* 把单元格转换成格式化字符串
50+
* 把单元格转换成格式化字符串
4851
*
49-
* @param cell 表示单元格数据 {@link ReadCellData}
50-
* @return 转换后的内容 {@link String}
52+
* @param cell 表示单元格数据 {@link ReadCellData}
53+
* @return 转换后的内容 {@link String}
5154
*/
5255
private static String getCellValueAsString(ReadCellData<?> cell) {
5356
switch (cell.getType()) {
@@ -73,44 +76,47 @@ private static String getCellValueAsString(ReadCellData<?> cell) {
7376
}
7477

7578
/**
76-
* 该文件提取器支持excel类型
79+
* 该文件提取器支持EXCEL和CSV类型。
7780
*
78-
* @return 枚举常量类型 {@link OperatorService.FileType}
81+
* @return 枚举常量类型集合 {@link List<String>}。
7982
*/
8083
@Override
8184
@Fitable(id = "get-fileType-excel")
82-
public OperatorService.FileType supportedFileType() {
83-
return OperatorService.FileType.EXCEL;
85+
public List<String> supportedFileType() {
86+
return Arrays.asList(OperatorService.FileType.EXCEL.toString(), OperatorService.FileType.CSV.toString());
87+
}
88+
89+
/**
90+
* @param fileUrl 表示文件路径 {@link String}。
91+
* @return 表示路径是否有效 {@link Boolean}。
92+
*/
93+
private boolean isValidPath(String fileUrl) {
94+
try {
95+
Path path = Paths.get(fileUrl);
96+
return Files.exists(path) && Files.isRegularFile(path);
97+
} catch (InvalidPathException e) {
98+
return false;
99+
}
84100
}
85101

86102
/**
87103
* 从指定路径的 Excel 文件中提取内容,并返回为字符串形式。
88104
*
89-
* @param fileUrl 表示文件路径的 {@link String}.
105+
* @param fileUrl 表示文件路径的 {@link String}
90106
* @return 表示文件内容的 {@link String}。
91107
*/
92108
@Override
93109
@Fitable(id = "extract-file-excel")
94110
public String extractFile(String fileUrl) {
111+
if (!isValidPath(fileUrl)) {
112+
throw new IllegalArgumentException("无效的文件路径: " + fileUrl);
113+
}
95114
File file = Paths.get(fileUrl).toFile();
96115
StringBuilder excelContent = new StringBuilder();
97-
ReadListener<Map<Integer, String>> listener = new ReadListener<>() {
98-
@Override
99-
public void invoke(Map<Integer, String> data, AnalysisContext context) {
100-
String line = data.entrySet()
101-
.stream()
102-
.sorted(Map.Entry.comparingByKey())
103-
.map(e -> e.getValue() == null ? "" : e.getValue())
104-
.collect(Collectors.joining("\t"));
105-
excelContent.append(line).append('\n');
106-
}
107-
108-
@Override
109-
public void doAfterAllAnalysed(AnalysisContext context) {
110-
}
111-
};
116+
ExcelReadListener listener = new ExcelReadListener(excelContent);
117+
ExcelReader reader = null;
112118
try (InputStream is = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
113-
ExcelReader reader = FastExcel.read(is, listener)
119+
reader = FastExcel.read(is, listener)
114120
.registerConverter(new CustomCellStringConverter())
115121
.headRowNumber(0)
116122
.build();
@@ -122,13 +128,41 @@ public void doAfterAllAnalysed(AnalysisContext context) {
122128
reader.read(readSheet);
123129
}
124130
excelContent.append('\n');
125-
reader.finish(); // 关闭资源
126131
} catch (IOException e) {
127-
throw new RuntimeException(e);
132+
throw new IllegalStateException("Excel文件读取失败", e);
133+
} finally {
134+
if (reader != null) {
135+
reader.finish(); // 关闭资源
136+
}
128137
}
129138
return excelContent.toString();
130139
}
131140

141+
/**
142+
* 读取监听器的内部类实现。
143+
*/
144+
private class ExcelReadListener implements ReadListener<Map<Integer, String>> {
145+
StringBuilder excelContent;
146+
147+
ExcelReadListener(StringBuilder excelContent) {
148+
this.excelContent = excelContent;
149+
}
150+
151+
@Override
152+
public void invoke(Map<Integer, String> data, AnalysisContext context) {
153+
String line = data.entrySet()
154+
.stream()
155+
.sorted(Map.Entry.comparingByKey())
156+
.map(e -> e.getValue() == null ? "" : e.getValue())
157+
.collect(Collectors.joining("\t"));
158+
this.excelContent.append(line).append('\n');
159+
}
160+
161+
@Override
162+
public void doAfterAllAnalysed(AnalysisContext context) {
163+
}
164+
}
165+
132166
/**
133167
* 自定义单元格数据转换器。
134168
* 该转换器实现了能够处理单元格数据并将其转换为字符串形式。

app-builder/plugins/aipp-file-extract-excel/src/test/java/modelengine/fit/jade/aipp/file/extract/ExcelFileExtractorTest.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package modelengine.fit.jade.aipp.file.extract;
88

99
import static org.assertj.core.api.Assertions.assertThat;
10+
import static org.junit.jupiter.api.Assertions.assertThrows;
1011

1112
import modelengine.fit.jober.aipp.service.OperatorService;
1213
import modelengine.fitframework.annotation.Fit;
@@ -17,12 +18,14 @@
1718
import org.junit.jupiter.api.Test;
1819

1920
import java.io.File;
21+
import java.util.Arrays;
22+
import java.util.List;
2023

2124
/**
22-
* 表示{@link ExcelFileExtractor}的测试集
25+
* 表示{@link ExcelFileExtractor}的测试集
2326
*
24-
* @author jsbjfkbsjk
25-
* @since 2025-9-6
27+
* @author 黄政炫
28+
* @since 2025-09-06
2629
*/
2730
@FitTestWithJunit(includeClasses = ExcelFileExtractor.class)
2831
@Disabled
@@ -33,13 +36,23 @@ class ExcelFileExtractorTest {
3336
@Test
3437
@DisplayName("测试获取支持文件类型")
3538
void supportedFileType() {
36-
assertThat(this.excelFileExtractor.supportedFileType()).isEqualTo(OperatorService.FileType.EXCEL);
39+
List<String> supportedTypes =
40+
Arrays.asList(OperatorService.FileType.EXCEL.toString(), OperatorService.FileType.CSV.toString());
41+
assertThat(this.excelFileExtractor.supportedFileType()).isEqualTo(supportedTypes);
42+
}
43+
44+
@Test
45+
@DisplayName("测试能否捕获错误路径")
46+
void validPath() {
47+
assertThrows(IllegalArgumentException.class, () -> {
48+
this.excelFileExtractor.extractFile("invalidPath.csv");
49+
});
3750
}
3851

3952
@Test
4053
@DisplayName("测试 excel 文件提取成功")
4154
void extractFile() {
42-
File file = new File(this.getClass().getClassLoader().getResource("file/content.xlsx").getFile());
55+
File file = new File(this.getClass().getClassLoader().getResource("file/content.csv").getFile());
4356
assertThat(this.excelFileExtractor.extractFile(file.getAbsolutePath())).isEqualTo(
4457
"Sheet 1:\nThis is an excel test\n\n");
4558
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is an excel test
Binary file not shown.

app-builder/plugins/aipp-plugin/pom.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@
151151
<dependency>
152152
<groupId>modelengine.fit.jade.plugin</groupId>
153153
<artifactId>aipp-file-extract-excel</artifactId>
154-
<version>1.0.0-SNAPSHOT</version>
155154
<scope>test</scope>
156155
</dependency>
157156

app-builder/plugins/aipp-plugin/src/main/java/modelengine/fit/jober/aipp/tool/FileExtractorContainer.java

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,55 @@
66

77
package modelengine.fit.jober.aipp.tool;
88

9-
import modelengine.fit.jade.aipp.file.extract.AbstractFileExtractor;
9+
import modelengine.fit.jade.aipp.file.extract.FileExtraction;
1010
import modelengine.fit.jober.aipp.service.OperatorService;
1111
import modelengine.fitframework.annotation.Component;
1212

13-
import java.util.EnumMap;
13+
import java.util.ArrayList;
14+
import java.util.HashMap;
1415
import java.util.List;
1516
import java.util.Map;
1617
import java.util.Optional;
1718

1819
/**
19-
* 管理文件提取器的容器
20+
* 管理文件提取器的容器
2021
*
21-
* @author jsbjfkbsjk
22-
* @since 2025-9-6
22+
* @author 黄政炫
23+
* @since 2025-09-06
2324
*/
2425
@Component
2526
public class FileExtractorContainer {
26-
private final Map<OperatorService.FileType, AbstractFileExtractor> map;
27+
/**
28+
* 一种文件类型对应一个提取器集合。
29+
*/
30+
private final Map<String, List<FileExtraction>> fileExtractorMap;
2731

2832
/**
29-
* 初始化用框架注入提取器
33+
* 初始化用框架注入提取器
3034
*
31-
* @param extractors 文件提取器 {@link AbstractFileExtractor}
35+
* @param extractors 文件提取器 {@link FileExtraction}。
3236
*/
33-
public FileExtractorContainer(List<AbstractFileExtractor> extractors) {
34-
map = new EnumMap<>(OperatorService.FileType.class);
35-
for (AbstractFileExtractor fileExtractor : extractors) {
36-
map.put(fileExtractor.supportedFileType(), fileExtractor);
37+
public FileExtractorContainer(List<FileExtraction> extractors) {
38+
this.fileExtractorMap = new HashMap<>();
39+
for (FileExtraction fileExtractor : extractors) {
40+
for (String supportedFileType : fileExtractor.supportedFileType()) {
41+
this.fileExtractorMap.computeIfAbsent(supportedFileType, k -> new ArrayList<>()).add(fileExtractor);
42+
}
3743
}
3844
}
3945

4046
/**
41-
* 根据文件类型找到支持文件类型的提取器
47+
* 根据文件类型找到支持文件类型的提取器
4248
*
43-
* @param fileUrl 文件路径 {@link String}
44-
* @param fileType 文件枚举类型 {@link OperatorService.FileType}
45-
* @return 提取的字符串 {@link Optional<String>}
49+
* @param fileUrl 文件路径 {@link String}
50+
* @param fileType 文件枚举类型 {@link OperatorService.FileType}
51+
* @return 提取的字符串 {@link Optional<String>}
4652
*/
4753
public Optional<String> extract(String fileUrl, OperatorService.FileType fileType) {
48-
return Optional.ofNullable(map.get(fileType))
49-
.map(extractor -> extractor.extractFile(fileUrl));
54+
List<FileExtraction> extractors = this.fileExtractorMap.get(fileType.toString());
55+
if (extractors == null || extractors.isEmpty()) {
56+
return Optional.empty();
57+
}
58+
return Optional.ofNullable(extractors.get(0)).map(extractor -> extractor.extractFile(fileUrl));
5059
}
5160
}

app-builder/services/aipp-file-extract-service/src/main/java/modelengine/fit/jade/aipp/file/extract/AbstractFileExtractor.java renamed to app-builder/services/aipp-file-extract-service/src/main/java/modelengine/fit/jade/aipp/file/extract/FileExtraction.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,31 @@
66

77
package modelengine.fit.jade.aipp.file.extract;
88

9-
import modelengine.fit.jober.aipp.service.OperatorService;
109
import modelengine.fitframework.annotation.Genericable;
1110

11+
import java.util.List;
12+
1213
/**
1314
* Excel文件提取器的抽象接口。
1415
*
15-
* @author jsbjfkbsjk
16-
* @since 2025-9-6
16+
* @author 黄政炫
17+
* @since 2025-09-06
1718
*/
18-
public interface AbstractFileExtractor {
19+
public interface FileExtraction {
1920
/**
20-
* 提取文件函数
21+
* 提取文件函数
2122
*
22-
* @param fileUrl 文件路径
23+
* @param fileUrl 表示文件路径 {@link String}。
2324
* @return 表示提取的文件信息的 {@link String}。
2425
*/
25-
@Genericable(id = "extract-file")
26+
@Genericable(id = "modelengine.fit.jade.file.extractFile")
2627
String extractFile(String fileUrl);
2728

2829
/**
29-
* 返回提取器支持文件类型
30+
* 返回提取器支持文件类型
3031
*
31-
* @return 表示返回的文件枚举类型 {@link OperatorService.FileType}
32+
* @return 表示返回的文件类型 {@link List<String>}。
3233
*/
33-
@Genericable(id = "get-fileType")
34-
OperatorService.FileType supportedFileType();
34+
@Genericable(id = "modelengine.fit.jade.file.getFileType")
35+
List<String> supportedFileType();
3536
}

common/dependency/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969

7070
<!-- Not Necessary versions -->
7171
<commons-io.version>2.16.1</commons-io.version>
72+
<file-extract.version>1.0.0-SNAPSHOT</file-extract.version>
7273

7374
</properties>
7475

@@ -597,6 +598,11 @@
597598
<artifactId>poi-scratchpad</artifactId>
598599
<version>${poi.version}</version>
599600
</dependency>
601+
<dependency>
602+
<groupId>modelengine.fit.jade.plugin</groupId>
603+
<artifactId>aipp-file-extract-excel</artifactId>
604+
<version>${file-extract.version}</version>
605+
</dependency>
600606

601607
<!-- Test -->
602608
<dependency>

0 commit comments

Comments
 (0)