将 Excel 或 CSV 文件转换为 Java 对象 (POJO) 以及将 Java 对象转换为 Excel 或 CSV 文件可能是一个复杂的过程,但如果使用正确的工具和技术,这个过程就会变得十分简单。在本文中,我们将了解如何利用一个 Java 反射的库来实现这个功能。
首先,我们将依赖关系添加到 Maven。
代码语言:javascript复制<dependency>
<groupId>com.adnanebk</groupId>
<artifactId>excel-csv-converter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
了解 POJO 类
在深入研究该库之前,让我们仔细看看作为数据模型的 Java 示例类:
代码语言:javascript复制@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@SheetDefinition(datePattern = "dd/MM/yyyy")
public class Product {
@CellDefinition(0)
private String name;
@CellDefinition(1)
private long price;
@CellDefinition(2)
@CellBoolean(trueValue = "yes",falseValue = "no")
private boolean active;
@CellDefinition(value = 3, title = "Promo price")
private double promoPrice;
// Additional fields...
@CellEnum(enumsMapperMethod = "categoryMap")
@CellDefinition(10)
private Category category;
@CellDefinition(11)
private LocalDateTime localDateTime;
private Map<Category,String> categoryMap(){
return Map.of(Category.A,"Formatted A",
Category.B,"Formatted B");
}
}
该类Product
带有各种注释,这些注释在转换过程中起着至关重要的作用。每个字段都带有注释@CellDefinition
,指示其在Excel 或 CSV 文件中的位置。
我们还可以定义单元格的标题,默认情况下,它会将字段的驼峰式名称转换为带空格的名称(例如:firstName=>First name)
该@SheetDefinition
注释提供了附加信息,例如将在日期字段类型转换期间使用的日期格式化模式。
枚举注释:@CellEnum(enumsMapperMethod = “categoryMap”)
在Product
类中,我们使用@CellEnum
枚举 Category 字段中的注释。enumsMapperMethod 参数允许我们定义方法名称;此方法应返回一个映射,该映射定义枚举常量与 Excel/CSV 单元格中的格式化值之间的映射(转换)(默认情况下,将使用枚举常量),请注意,方法名称必须与 enumsMapperMethod 参数值相同。
[布尔注解:@CellBoolean(trueValue = “yes”,falseValue = “no”)]
在我们需要使用Boolean类型的字段中使用 @CellBoolean 注释,它有两个参数代表我们要在 Excel/CSV 字段中使用的格式值。
现在,让我们介绍 POJO 类的更新版本ProductV2
:
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@SheetDefinition(includeAllFields = true,titles={"Name","Category","Date"})
public class ProductV2 {
private String name;
// Additional fields...
private Category category;
@IgnoreCell
private LocalDateTime localDateTime;
}
@SheetDefinition
通过类中提供的注释将字段映射到 Excel 文件中的相应单元格,将 Excel 文件转换为 POJO 变得更加简单。
当 includeAllFields 参数设置为 true 时,字段将根据其声明的顺序自动包含并映射到单元格中,并忽略使用 @IgnoreCell 注释进行注释的字段。
我们可以在标题参数中定义标题,条件是它们必须与字段的顺序一致。
将 Excel/CSV 转换为 POJO
代码语言:javascript复制@RestController
@RequestMapping("excel/products")
public class ExcelFieldsController {
private final ExcelHelper<Product> excelHelper = ExcelHelper.create(Product.class);
@GetMapping
public List<Product> excelToProducts(@RequestBody MultipartFile file){
return excelHelper.toStream(file.getInputStream()).toList();
}
@GetMapping("/download")
public ResponseEntity<InputStreamResource>
downloadExcelFromProducts() {
String filename = "products-" LocalDate.now() ".xlsx";
InputStreamResource file = new InputStreamResource(excelHelper.toExcel(getProducts()));
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" filename)
.contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
.body(file);
}
}
这同样适用于转换 CSV 文件,只是我们需要定义将使用的分隔符
代码语言:javascript复制 private final CsvHelper<ProductV2> csvHelper = CsvHelper.create(ProductV2.class,";");
ReflectionUtil
:动态检验类
ReflectionUtil 类是该 Java 库的支柱,通过 Java 反射的强大功能促进动态类检查和操作。ReflectionUtil 类的一个显著特点是为提高性能而进行的优化。在初始化过程中,所有的get、set和字段都会被快速加载并封装在 SheetField 中。这种有意识的操作最大限度地减少了后续操作中的反射查找需求,提高了整体效率。
主要方法:
public Object getValue(T obj)
:使用对象的 getter 方法检索字段的值。如果该字段是枚举,它会根据定义的枚举映射提供格式化值。
public void setValue(T obj, Object value)
:使用对象的 setter 方法设置对象中字段的值。它处理枚举值并确保正确的转换。
结论
通过利用这个自定义库,开发人员可以显着简化将 Excel 和 CSV 文件转换为Java 中的 POJO的过程。Java 反射的集成以及深思熟虑的设计考虑支持动态映射,使其成为数据处理任务的宝贵工具。