POI中的Java Excel/POJO映射

POI中的Java Excel/POJO映射,java,excel,apache-poi,xlsx,Java,Excel,Apache Poi,Xlsx,Java8在这里使用ApachePOI4.1将Excel(XLSX)文件加载到内存中,并将JavaBean/POJO列表写回新的Excel文件 对我来说,Excel文件(至少是我正在使用的文件)实际上是一个POJO列表,每一行都是POJO的不同实例,每一列都是该实例的不同字段值。注意: 这里我可能有一个名为Car的POJO,上面的示例电子表格是一个列表: 因此,我有一个功能代码,可以将Excel文件(“new cars.xlsx”)读入列表,处理该列表,然后将处理后的列表写回输出文件,比如,“

Java8在这里使用ApachePOI4.1将Excel(XLSX)文件加载到内存中,并将JavaBean/POJO列表写回新的Excel文件

对我来说,Excel文件(至少是我正在使用的文件)实际上是一个POJO列表,每一行都是POJO的不同实例,每一列都是该实例的不同字段值。注意:

这里我可能有一个名为
Car
的POJO,上面的示例电子表格是一个
列表

因此,我有一个功能代码,可以将Excel文件(“
new cars.xlsx
”)读入
列表
,处理该列表,然后将处理后的列表写回输出文件,比如,“
processed cars.xlsx
”:

//1。将excel文件加载到列表中
InputStream Input=新文件InputStream(“new cars.xlsx”);
工作簿=WorkbookFactory.create(inp);
迭代器迭代器=工作簿.getSheetAt(0.Iterator();
List carsInventory=new ArrayList();
while(iterator.hasNext()){
汽车=新车();
Row currentRow=iterator.next();
//不要读标题
如果(currentRow.getRowNum()==0){
继续;
}
迭代器cellIterator=currentRow.Iterator();
while(cellIterator.hasNext()){
Cell currentCell=cellIterator.next();
CellAddress=currentCell.getAddress();
如果(0==address.getColumn()){
//第1列为“制造商”
setManufacturer(currentCell.getStringCellValue());
}else if(1==address.getColumn()){
//第二列是“模型”
setModel(currentCell.getStringCellValue());
}else if(2==address.getColumn()){
//第三列是“颜色”
setColor(currentCell.getStringCellValue());
}else if(3==address.getColumn()){
//第四列是“年”
setYear(currentCell.getStringCellValue());
}else if(4==address.getColumn()){
//第五列是“价格”
setPrice(BigDecimal.valueOf(currentCell.getNumericCellValue());
}
}
carsInventory.add(car);
}
// 2. 处理车辆清单;这不重要
列表加工库存=加工库存(汽车库存);
// 3. 输出到“已加工汽车.xlsx”
工作簿=新的XSSF工作簿();
工作表=工作簿.createSheet(“已处理库存”);
int rowNum=0;
//创建标题
Row headerRow=sheet.createRow(rowNum);
headerRow.createCell(0.setCellValue(“制造商”);
headerRow.createCell(1.setCellValue(“模型”);
headerRow.createCell(2.setCellValue(“颜色”);
headerRow.createCell(3.setCellValue(“年”);
headerRow.createCell(4.setCellValue(“价格”);
rowNum++;
//翻阅cars列表,并将每个列表转换为后续行
用于(车辆处理车辆:处理车辆){
Row nextRow=sheet.createRow(rowNum);
createCell(0).setCellValue(processedCar.getManufacturer());
createCell(1).setCellValue(processedCar.getModel());
createCell(2).setCellValue(processedCar.getColor());
createCell(3).setCellValue(processedCar.getYear());
createCell(4).setCellValue(processedCar.getPrice().doubleValue());
rowNum++;
}
FileOutputStream fos=新的FileOutputStream(“processed cars.xlsx”);
练习册。写作(fos);
workbook.close();
虽然这很管用,但在我看来它真的很难看/难看。多年来,我一直使用JSON映射器(Jackson、GSON等)、XML映射器(XStream)和OR/M工具(Hibernate),我突然想到POI的API(或其他一些库)可能提供一种“映射器式”解决方案,允许我以最少的代码和最优雅的方式将Excel数据映射到POJO列表中。但是,我在任何地方都找不到这样的功能。也许这是因为它不存在,或者我只是没有搜索正确的关键字

理想情况下,应遵循以下原则:

// Annotate the fields with something that POI (or whatever tool) can pick up
@Getter
@Setter
public class Car {

  @ExcelColumn(name = "Manufacturer", col = 0)
  private String manufacturer;

  @ExcelColumn(name = "Model", col = 1)
  private String model;

  @ExcelColumn(name = "Color", col = 2)
  private String color;

  @ExcelColumn(name = "Year", col = 3)
  private String year;

  @ExcelColumn(name = "Price", col = 4)
  private BigDecimal price;

}

// 2. Now load the Excel into a List<Car>
InputStream inp = new FileInputStream("new-cars.xlsx");
List<Car> carsInventory = WorkbookFactory.create(inp).buildList(Car.class);

// 3. Process the list
List<Car> processedInventory = processInventory(carsInventory);

//4. Write to a new file
WorkbookFactory.write(processInventory, "processed-cars.xlsx");
//使用POI(或任何工具)可以获取的内容对字段进行注释
@吸气剂
@塞特
公车{
@ExcelColumn(name=“Manufacturer”,col=0)
私人字符串制造商;
@ExcelColumn(name=“Model”,col=1)
私有字符串模型;
@ExcelColumn(name=“Color”,col=2)
私有字符串颜色;
@Excel列(name=“Year”,col=3)
私人弦年;
@ExcelColumn(name=“Price”,col=4)
私人价格;
}
// 2. 现在将Excel加载到列表中
InputStream Input=新文件InputStream(“new cars.xlsx”);
List carsInventory=WorkbookFactory.create(inp.buildList)(Car.class);
// 3. 处理列表
列表加工库存=加工库存(汽车库存);
//4. 写入新文件
write(processInventory,“processed cars.xlsx”);

在POI土地上有类似的东西吗?还是我一直在坚持我所得到的?

到目前为止,Apache POI还没有这样的功能。您可以查看外部库。我提供以下几个库

该库在mvnrepository中提供,链接如下。该库仅提供一种方式绑定,如从excel工作表到java pojo的绑定

根据上面的说明,你可以这样做

public class Employee {

    @ExcelRow                  
    private int rowIndex;

    @ExcelCell(0)                
    private long employeeId;  

    @ExcelCell(1)
    private String name;

    @ExcelCell(2)
    private String surname;

    @ExcelCell(3)
    private int age;
}
@Sheet
public class Employee {

    @SheetColumn("Age")
    private Integer age;

    @SheetColumn("Name")
    public String getName() {
        return name;
    }

}
final File xlsxFile = new File("<path_to_file>");
final XlsReader reader = new XlsReader();
List<Employee> employees = reader.read(Employee.class, xlsxFile);
List<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee("1", "foo", 12, "MALE", 1.68));
SpreadsheetWriter writer = new SpreadsheetWriter("<output_file_path>");
writer.addSheet(Employee.class, employees);
writer.write();
要从excel工作表到java对象获取信息,必须按照以下方式执行

List<Employee> employees = Poiji.fromExcel(new File("employees.xls"), Employee.class);
要从xlsx文件中获取数据,必须这样编写

public class Employee {

    @ExcelRow                  
    private int rowIndex;

    @ExcelCell(0)                
    private long employeeId;  

    @ExcelCell(1)
    private String name;

    @ExcelCell(2)
    private String surname;

    @ExcelCell(3)
    private int age;
}
@Sheet
public class Employee {

    @SheetColumn("Age")
    private Integer age;

    @SheetColumn("Name")
    public String getName() {
        return name;
    }

}
final File xlsxFile = new File("<path_to_file>");
final XlsReader reader = new XlsReader();
List<Employee> employees = reader.read(Employee.class, xlsxFile);
List<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee("1", "foo", 12, "MALE", 1.68));
SpreadsheetWriter writer = new SpreadsheetWriter("<output_file_path>");
writer.addSheet(Employee.class, employees);
writer.write();
final File xlsxFile=新文件(“”);
最终XlsReader读取器=新XlsReader();
List employees=reader.read(Employee.class,xlsxFile);
要将数据写入excel工作表,必须执行以下操作

public class Employee {

    @ExcelRow                  
    private int rowIndex;

    @ExcelCell(0)                
    private long employeeId;  

    @ExcelCell(1)
    private String name;

    @ExcelCell(2)
    private String surname;

    @ExcelCell(3)
    private int age;
}
@Sheet
public class Employee {

    @SheetColumn("Age")
    private Integer age;

    @SheetColumn("Name")
    public String getName() {
        return name;
    }

}
final File xlsxFile = new File("<path_to_file>");
final XlsReader reader = new XlsReader();
List<Employee> employees = reader.read(Employee.class, xlsxFile);
List<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee("1", "foo", 12, "MALE", 1.68));
SpreadsheetWriter writer = new SpreadsheetWriter("<output_file_path>");
writer.addSheet(Employee.class, employees);
writer.write();
List employees=new ArrayList();
新增(新员工(“1”,“foo”,12,“男性”,1.68));
电子表格书写器=新的电子表格书写器(“”);
writer.addSheet(Employee.class,employees);
writer.write();

您必须对两个库进行用例评估。

< p>我会考虑编写我自己的代码> Apache POI <代码>到/从<代码> POJO 映射器包代替SIM。
@Data
public  class TestProduct{
    @ExcelColumn(name = "Product Name")
    private String productName;
    @ExcelColumn(name = "Image Urls")
    private Set<String> mediaUrls;
}