我想有一个类雇主
,我从那里创建带有firstName
、lastName
和city
的对象。
我想遍历一个员工数组,并为每个创建的对象提取firstName
、lastName
和city
并将其写入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();
}
}
代码中的问题在于您从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);
}
}