当前位置:  开发笔记 > 编程语言 > 正文

POI中的Java Excel / POJO映射

如何解决《POI中的JavaExcel/POJO映射》经验,为你挑选了1个好方法。

这里的Java 8使用Apache POI 4.1将Excel(XLSX)文件加载到内存中,并将Java bean / POJO的列表写回到新的Excel文件中。

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

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

@Getter
@Setter
public class Car {

  private String manufacturer;
  private String model;
  private String color;
  private String year;
  private BigDecimal price;

}

因此,我有正常运行的代码,可以将Excel文件(“ new-cars.xlsx”)读入List,处理该列表,然后将处理后的列表写回到输出文件,例如“ processed-cars.xlsx”:

// 1. Load excel file into a List
InputStream inp = new FileInputStream("new-cars.xlsx");
Workbook workbook = WorkbookFactory.create(inp);
Iterator iterator = workbook.getSheetAt(0).iterator();

List carsInventory = new ArrayList<>();
while (iterator.hasNext()) {

    Car car = new Car();

    Row currentRow = iterator.next();

    // don't read the header
    if (currentRow.getRowNum() == 0) {
        continue;
    }

    Iterator cellIterator = currentRow.iterator();

    while (cellIterator.hasNext()) {

        Cell currentCell = cellIterator.next();
        CellAddress address = currentCell.getAddress();

        if (0 == address.getColumn()) {
            // 1st col is "Manufacturer"
            car.setManufacturer(currentCell.getStringCellValue());
        } else if (1 == address.getColumn()) {
            // 2nd col is "Model"
            car.setModel(currentCell.getStringCellValue());
        } else if (2 == address.getColumn()) {
            // 3rd col is "Color"
            car.setColor(currentCell.getStringCellValue());
        } else if (3 == address.getColumn()) {
            // 4th col is "Year"
            car.setYear(currentCell.getStringCellValue());
        } else if (4 == address.getColumn()) {
            // 5th col is "Price"
            car.setPrice(BigDecimal.valueOf(currentCell.getNumericCellValue()));
        }

    }

    carsInventory.add(car);

}

// 2. Process the list of Cars; doesn't matter what this does
List processedInventory = processInventory(carsInventory);

// 3. Output to "processed-cars.xlsx"
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Processed Inventory");
int rowNum = 0;

// create headers
Row headerRow = sheet.createRow(rowNum);
headerRow.createCell(0).setCellValue("Manufacturer");
headerRow.createCell(1).setCellValue("Model");
headerRow.createCell(2).setCellValue("Color");
headerRow.createCell(3).setCellValue("Year");
headerRow.createCell(4).setCellValue("Price");

rowNum++;

// rip through the cars list and convert each one into a subsequent row
for (Car processedCar : processedInventory) {

    Row nextRow = sheet.createRow(rowNum);

    nextRow.createCell(0).setCellValue(processedCar.getManufacturer());
    nextRow.createCell(1).setCellValue(processedCar.getModel());
    nextRow.createCell(2).setCellValue(processedCar.getColor());
    nextRow.createCell(3).setCellValue(processedCar.getYear());
    nextRow.createCell(4).setCellValue(processedCar.getPrice().doubleValue());

    rowNum++;

}

FileOutputStream fos = new FileOutputStream("processed-cars.xlsx");
workbook.write(fos);

workbook.close();

尽管此方法有效,但对我来说确实很难看/讨厌。我使用JSON映射器(杰克逊,GSON等),多年来XML映射器(XStream的)和OR / M工具(休眠),它发生,我认为POI的API(或其他库)可能会提供一个“ 映射器-esque “解决方案,使我能够以最少的代码和最大的优雅度将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
InputStream inp = new FileInputStream("new-cars.xlsx");
List carsInventory = WorkbookFactory.create(inp).buildList(Car.class);

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

//4. Write to a new file
WorkbookFactory.write(processInventory, "processed-cars.xlsx");

在POI领域是否存在类似的内容?还是我坚持我得到的东西?



1> Sambit..:

到目前为止,Apache POI还没有这种功能。您可以检查一些外部库。我在下面提供一些库。

https://github.com/ozlerhakan/poiji

该库在mvnrepository中可用,链接在下面给出。该库仅提供一种从excel表格到Java pojo的绑定方式。

https://mvnrepository.com/artifact/com.github.ozlerhakan/poiji/2.2.0

如上所述,您可以执行以下操作。

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;
}

要将信息从excel工作表获取到java对象,您必须按照以下方式进行操作。

List employees = Poiji.fromExcel(new File("employees.xls"), Employee.class);

还有另一个库可以同时执行excel和java以及excel等功能。我在链接下方提供。

https://github.com/millij/poi-object-mapper

根据上述库,您可以执行以下操作。

@Sheet
public class Employee {

    @SheetColumn("Age")
    private Integer age;

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

}

要从xlsx文件获取数据,您必须这样编写。

final File xlsxFile = new File("");
final XlsReader reader = new XlsReader();
List employees = reader.read(Employee.class, xlsxFile);

要将数据写入excel工作表,您必须这样做。

List employees = new ArrayList();
employees.add(new Employee("1", "foo", 12, "MALE", 1.68));
SpreadsheetWriter writer = new SpreadsheetWriter("");
writer.addSheet(Employee.class, employees);
writer.write();

您必须为您的用例评估两个库。

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有