简体   繁体   中英

Iterate through an array of objects and write the data into an excel file in Java

I want to have a class Employess from where I create objects with firstName , lastName and city .

I want to iterate through an Employees array, and for each object created to extract the firstName , lastName and city and write it into an Excel file.

My code blocks in the second for block with the following error message:

Exception in thread "main" java.lang.ClassCastException: class http.Employees cannot be cast to class [Ljava.lang.Object; (http.Employees is in unnamed module of loader 'app'; [Ljava.lang.Object; is in module java.base of loader 'bootstrap') at http.App.main(App.java:64).

I am new to Java and I think that the way I use that HashMap is wrong, but I couldn't figure out how to handle it in the correct way.

Any help would be much appreciated. Thank you.

Code below:

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

The problem in your code lies in the way you retrieve an Employees from the HashMap . In fact, your employeeData is defined as a HashMap with Integer keys and Object values (ie your Employees ). When you perform a map.get(key) , the method returns an Object , specifically an Employees , not an Object[] ; thus the ClassCastException .

Besides, HashMap is a generic class. This means that the type parameters K and V, representing the data types of your keys and values, can be specified with proper type arguments. In your case, it will be a better fit to use Employees as the data type for your values. In fact, Object is far too generic, it forces you to resort to casting and losing one of the many benefits of generics.

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

Lastly, It doesn't seem like a HashMap is actually needed for the code you've written. In fact, you could simplify it by using an array of Employees . Here I'll leave both implementations which rely on getter methods in your Employees class:

HashMap Implementation

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

Array of Employees Implementation

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

The value is not an array of objects, but objects of type 'Employees' so you cannot cast it to an array:

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

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

EDIT: i think this may be what you are trying to achieve:

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

Here is a complete example you can use. Pass the full path to the output file as an argument to the program:

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

}

This uses a little convenience method in class Employee that returns the class fields as an array:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM