循环类成员并写入 Excel Apache POI

Posted

技术标签:

【中文标题】循环类成员并写入 Excel Apache POI【英文标题】:Loop on Class Members and write to Excel Apache POI 【发布时间】:2015-08-02 19:22:09 【问题描述】:

我有一个自定义对象的数组列表。我正在尝试循环这些对象以将我的输出写入 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 |

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

【问题讨论】:

不就是你的MasterOutput列表是空的吗?此外,您将cellnum 重置在错误的位置。它应该在外循环而不是内循环。 我同意。此外,您应该将该字段重命名为“masterOutput”以遵循 Java 命名约定。 我检查了 MasterOutput,它有 4 个值。 您的MasterOutput 列表中的所有ChecklistOutput 实例是否都包含ABC 值的空字符串(由构造函数初始化)? 没有。事实上,它们都不是空字符串。我将值存储在实例中,打印时可以看到它们。我已经更新了相同的代码。 【参考方案1】:

试试这个:

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。您可以查看 my question 。它要求其他东西,但提供了一个工作示例来通过反射获取值(我也将它用于 POI)。

【讨论】:

以上是关于循环类成员并写入 Excel Apache POI的主要内容,如果未能解决你的问题,请参考以下文章

excel写入笔记

用java的poi类读取一个excel表格的内容后再写入到一个新excel表格中的完整代码

POI向Excel中写入数据及追加数据

无法写入Excel文件(Apache POI)

使用 Apache POI 从 Java 应用程序删除行时 Excel 公式未更新

Apache POI 4.0.1版本写入普通Excel文件(兼容 xls 和 xlsx)