循环类成员并写入 Excel Apache POI

问题描述 投票:0回答:2

我有一个自定义对象的数组列表。我正在尝试循环这些对象以将输出写入 Excel 文件。

在下面的代码中,在第一个循环中,我通过循环类成员变量来设置 Excel 文件中的标题行。在第二个循环中,我写入对象值。

我的代码:

class ChecklistOutput {
    //Instantiating class data members
String a, b, c;

public ChecklistOutput() { 
     a = ""; b = ""; c = ""; }
}

private static ArrayList<ChecklistOutput> MasterOutput = new ArrayList<ChecklistOutput>();

private static void writeToMasterExcel() {
    ChecklistOutput obj1 = new ChecklistOutput();
    obj1.a = "AA"; obj1.b = "BB"; obj1.c = "CC"; 
    ChecklistOutput obj1 = new ChecklistOutput();
    obj2.a = "AA"; obj2.b = "BB"; obj2.c = "CC";
    ChecklistOutput obj1 = new ChecklistOutput();
    obj3.a = "AA"; obj3.b = "BB"; obj3.c = "CC"; 
    ChecklistOutput obj1 = new ChecklistOutput();
    obj4.a = "AA"; obj4.b = "BB"; obj4.c = "CC"; 

    MasterOutput.add(obj1);
    MasterOutput.add(obj2);
    MasterOutput.add(obj3);
    MasterOutput.add(obj4);
    System.out.println(MasterOutput.size());

    HSSFWorkbook workbook = new HSSFWorkbook();
    HSSFSheet sheet = null;
    HSSFRow row = null;
    HSSFCell cell = null;
    int rownum = 0, cellnum = 0;
    sheet = workbook.createSheet("Master Spreadsheet");
    row = sheet.createRow(rownum);
    System.out.println("rownum " + rownum);
    Class<?> c = new ChecklistOutput().getClass();
    Field[] fields = c.getDeclaredFields();

    // First loop
    for (Field field : fields) {
        cell = row.createCell(cellnum);
        cell.setCellType(Cell.CELL_TYPE_STRING);
        cell.setCellValue(field.getName());
        cellnum += 1;
    }
    System.out.println(MasterOutput.size());
    // Second loop
    for (ChecklistOutput x : MasterOutput) {
        // This prints 4 times meaning that there are 4 values in
        // MasterOutput
        System.out.println("Hell");
        rownum += 1;
        cellnum = 0;
        row = sheet.createRow(rownum);
        for (Field field : fields) {
            cell = row.createCell(cellnum);
            cell.setCellType(Cell.CELL_TYPE_STRING);
            try {
                // I can see values here
                System.out.println(field.get(x).toString());
                cell.setCellValue(field.get(x).toString());
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            cellnum += 1;
        }
    }
    BufferedOutputStream bos;
    try {
        bos = new BufferedOutputStream(new FileOutputStream(
                "C:\\Users\\ABC\\Documents\\Checklist-Output.xls",
                true));
        workbook.write(bos);
        bos.close();
        workbook.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

但是,我只获取 Excel 文件中的标题值。

输出:

| a | b | c |

有人可以帮我解决这个问题吗?谢谢!

java excel apache-poi
2个回答
0
投票

试试这个:

for (int col = 0; col < fields.length; col++) {
    Field field = fields[col];
    HSSFRow header = sheet.getRow(rownum);
    if (header == null) {
        header = sheet.createRow(rownum);
    }
    HSSFCell cell = header.createCell(col);
    cell.setCellType(Cell.CELL_TYPE_STRING);
    cell.setCellValue(field.getName());
}
for (ChecklistOutput x : MasterOutput) {
    rownum += 1;
    HSSFRow rowData = sheet.getRow(rownum);
    if (rowData == null) {
        rowData = sheet.createRow(rownum);
    }

    for (int col = 0; col < fields.length; col++) {
        Field field = fields[col];
        HSSFCell cellData = rowData.createCell(col);
        cellData.setCellType(Cell.CELL_TYPE_STRING);
        try {
            // I can see values here
            System.out.println(field.get(x).toString());
            cellData.setCellValue(field.get(x).toString());
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

我还建议您使用 POJO 而不是 ChecklistOutput(带有 getter 和 setter 的私有字段)。 我做了和你一样的事。如果您想要 pojo 中字段的值,您可以使用反射来调用 getter。你可以看看我的问题。它要求其他内容,但提供了一个通过反射获取值的工作示例(我也将其用于 POI)。


0
投票

您可以尝试这个 Excel Service 库,看看它是否可以为您简化事情。该库抽象了 apache poi 代码,并帮助您轻松地将 DTO 列表转换为 Excel 文件。 (https://github.com/dev-codehub/excel-service)。

示例:

class ExampleService {
    private final ExcelService excelService;

    public ExampleService(ExcelService excelService) {
        this.excelService = excelService;
    }

    public Resource generateExampleExcel() {
        // Headers
        List<ExcelHeaderBase> headers = List.of(ExcelExampleHeader.values());
    
        // List of objects
        List<ChecklistOutput> exampleDTOList = new ArrayList<>();
        exampleDTOList.add(ChecklistOutput.builder().t1("AA").t2("BB").t3("CC").build());
        exampleDTOList.add(ChecklistOutput.builder().t1("AA").t2("BB").t3("CC").build());

        // Excel settings
        ExcelSettings excelSettings = ExcelSettings.builder()
            .sheetName("example")
            // Multiple settings and styles available
            .build();
    
        // Generate excel
        byte[] bytes = excelService.generateDynamicExcel(headers, exampleDTOList, ChecklistOutput.class, excelSettings);
    
        //...
    }
}
        
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ChecklistOutput {
    private String a;
    private String b;
    private String c;
}
       
@Getter
@AllArgsConstructor
public enum ExcelChecklistOutputHeader implements ExcelHeaderBase {
    VALUE1("a", "Display Column A"),
    VALUE2("b", "Display Column B"),
    VALUE3("c", "Display Column C");

    private final String field;
    private final String displayName;
}
© www.soinside.com 2019 - 2024. All rights reserved.