提问者:小点点

遍历对象数组并将数据写入Java的excel文件


我想有一个类雇主,我从那里创建带有firstNamelastNamecity的对象。

我想遍历一个员工数组,并为每个创建的对象提取firstNamelastNamecity并将其写入Excel文件。

我的代码阻塞在第二个for block中,并带有以下错误消息:

线程"main"中的异常java. lang.ClassCastException:class http.员工不能被强制转换为class[Ljava.lang.Object;(http.员工在loader'app'的未命名模块中;[Ljava.lang.Object;在loader'bootstrap'的module java.base中)http.App(App.java:64)。

我是Java新手,我认为我使用HashMap的方式是错误的,但我不知道如何以正确的方式处理它。

任何帮助都将不胜感激。谢谢你。

下面的代码:

class Employees {
    String firstName;
    String lastName;
    String city;

    public Employees(String firstName, String lastName, String city) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.city = city;
    }
}

public class App {
    public static void main(String[] args) throws Exception {
        String excelPath = "C:/Work/01_TSM/java/test.xlsx";

        FileInputStream inputStream = new FileInputStream(new File(excelPath));

//      create workbook object
        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);

//      create spreadsheet object
        XSSFSheet spreadsheet = workbook.getSheetAt(1);

//       create row object
        XSSFRow row;

//       This data needs to be written in (Object[])
        HashMap<Integer, Object> employeeData = new HashMap<Integer, Object>();

        Employees employee1 = new Employees("John", "Smith", "CT");
        Employees employee2 = new Employees("Jane", "Doe", "O");
        Employees[] employees = { employee1, employee2 };

//       Insert data
        for (int i = 0; i < employees.length; i++) {
            employeeData.put(i, employees[i]);
        }
        ;

        Set<Integer> keyid = employeeData.keySet();

        int rowid = 1;

//       writing the data into the sheets
        for (Integer key : keyid) {
            row = spreadsheet.createRow(rowid++);

            // here the code breaks
            Object[] objectArr = (Object[]) employeeData.get(key);
            int cellid = 0;
            
            
            for (Object obj : objectArr) {

                Cell cell = row.createCell(cellid++);
                cell.setCellValue((String) obj);
            }
        }

//       writing the workbook into the file
        FileOutputStream out = new FileOutputStream(new File("C:/Work/01_TSM/java/test.xlsx"));
        workbook.write(out);
        out.close();
    }
}

共3个答案

匿名用户

代码中的问题在于您从HashMap中检索员工的方式。事实上,您的员工数据被定义为具有整数键和对象值(即您的员工)的HashMap。当您执行map. get(key)时,该方法返回一个对象,特别是员工,而不是对象[];因此ClassCastException

此外,HashMap是一个泛型类。这意味着类型参数K和V,代表你的键和值的数据类型,可以用适当的类型参数来指定。在你的情况下,使用员工作为你的值的数据类型会更合适。事实上,对象太通用了,它迫使你求助于转换并失去泛型的众多好处之一。

https://docs.oracle.com/javase/tutorial/java/generics/why.html

最后,您编写的代码似乎并不需要HashMap。事实上,您可以通过使用员工数组来简化它。在这里,我将在您的员工类中保留依赖getter方法的两种实现:

String pathFileExcel = "C:/Work/01_TSM/java/test.xlsx";

//Creating a workbook
XSSFWorkbook workbook = new XSSFWorkbook();

//Making sure a spreadSheet exsists before retrieving it
if (workbook.getNumberOfSheets() == 0) {
    workbook.createSheet();
}
XSSFSheet spreadsheet = workbook.getSheetAt(0);

//Creating a map
Map<Integer, Employees> employeeMap = new HashMap<>(Map.of(
        0, new Employees("John", "Smith", "CT"),
        1, new Employees("Jane", "Doe", "O")
));

int rowNum = 0;

//writing the data into the sheets
for (Integer key : employeeMap.keySet()) {
    XSSFRow row = spreadsheet.createRow(rowNum++);

    Employees emp = employeeMap.get(key);

    Cell cellFirstName = row.createCell(0);
    cellFirstName.setCellValue((emp.getFirstName()));

    Cell cellLastName = row.createCell(1);
    cellLastName.setCellValue((emp.getLastName()));

    Cell cellCity = row.createCell(2);
    cellCity.setCellValue((emp.getCity()));
}

//the try-with automatically closes the connection once exited the try block
try (FileOutputStream out = new FileOutputStream(pathFileExcel);) {
    workbook.write(out);
}
String pathFileExcel = "C:/Work/01_TSM/java/test.xlsx";

//Creating a workbook
XSSFWorkbook workbook = new XSSFWorkbook();

//Making sure a spreadSheet exsists before retrieving it
if (workbook.getNumberOfSheets() == 0) {
    workbook.createSheet();
}
XSSFSheet spreadsheet = workbook.getSheetAt(0);

//Creating an array
Employees[] vetEmp = new Employees[]{
        new Employees("John", "Smith", "CT"),
        new Employees("Jane", "Doe", "O")
};

int rowNum = 0;

//writing the data into the sheets
for (Employees emp : vetEmp) {
    XSSFRow row = spreadsheet.createRow(rowNum++);

    Cell cellFirstName = row.createCell(0);
    cellFirstName.setCellValue((emp.getFirstName()));

    Cell cellLastName = row.createCell(1);
    cellLastName.setCellValue((emp.getLastName()));

    Cell cellCity = row.createCell(2);
    cellCity.setCellValue((emp.getCity()));
}

//the try-with automatically closes the connection once exited the try block
try (FileOutputStream out = new FileOutputStream(pathFileExcel);) {
    workbook.write(out);
}

匿名用户

这是您可以使用的一个完整示例。将输出文件的完整路径作为参数传递给程序:

package xlsconv;

import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFCell;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.IOException;
import java.io.OutputStream;
import java.io.BufferedOutputStream;

public class Beans2Sheet {

    public static void main(String[] args) {
        try {
            Beans2Sheet b2s = new Beans2Sheet();
            Employee[] emps = new Employee[] {
                new Employee("John", "Doe", "Kansas City"),
                new Employee("John", "Doe", "New York City")
            };
            b2s.beans2Sheet(emps, Paths.get(args[0]));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void beans2Sheet(Employee[] employees, Path outputPath) throws IOException {
        XSSFWorkbook workBook = new XSSFWorkbook();
        XSSFSheet sheet = workBook.createSheet();

        for (int rowNum = 0; rowNum < employees.length; rowNum++) {

            XSSFRow row = sheet.createRow(rowNum);
            String[] fields = employees[rowNum].toFields();
            for (int i = 0; i < fields.length; i++) {
                XSSFCell cell = row.createCell(i);
                cell.setCellValue(fields[i]);
            }
        }

        try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(outputPath))) {
            workBook.write(out);
        }
    }

}

这在类员工中使用了一个方便的方法,它将类字段作为数组返回:

public String[] toFields() {
    return new String[] { firstName, lastName, city };
}

匿名用户

该值不是对象数组,而是“员工”类型的对象,因此您不能将其强制转换为数组:

        Object[] objectArr = (Object[]) employeeData.get(key);
        int cellid = 0;
        
        
        for (Object obj : objectArr) {

            Cell cell = row.createCell(cellid++);
            cell.setCellValue((String) obj);
        }

编辑:我想这可能是你想要实现的:

    HashMap<Integer, Object> employeeData = new HashMap<Integer, Object>();

    Employees employee1 = new Employees("John", "Smith", "CT");
    Employees employee2 = new Employees("Jane", "Doe", "O");
    Employees[] employees = { employee1, employee2 };

    for (int i = 0; i < employees.length; i++) {
        employeeData.put(i, employees[i]);
    }

    Set<Integer> keyid = employeeData.keySet();
    int rowid = 1;
    for (Integer key : keyid) {
        row = spreadsheet.createRow(rowid++);

        // here the code breaks
        Employees employee = (Employees)employeeData.get(key);
        for (int cellid = 0; cellid < 3; cellid++)
        {
            Cell cell = row.createCell(cellid++):
            if (cellid == 0)
            {
                cell.setCellValue(employee.firstName);
            }
            else if(cellid == 1)
            {
                cell.setCellValue(employee.lastName);
            }
            else if(cellid == 2)
            {
                cell.setCellValue(employee.city);
            }
        }

相关问题