Closed julianjupiter closed 1 year ago
Your usage of this class is at first a little weird as you are using it outside the scope of Spring Batch but as a regular way to parse Excel files. You are probably better of using Apache POI directly instead of this wrapper.
That being said, due to your usage you are missing some callback methods to properly initialize the reader and prepare it to read rows.
First you need to call afterPropertiesSet
to ensure proper setup of the PoiItemReader
and BeanWrapperRowMapper
. Next you need to call open
with an empty ExecutionContext
to properly open the Excel file for reading. So your ExcelUtils
should look something like this.
public class ExcelUtils {
public static <T> ItemReader<T> excelToItemReader(Path file, Class<T> clazz) throws Exception {
PoiItemReader<T> reader = new PoiItemReader<>();
reader.setLinesToSkip(1);
System.out.println("File Name: " + file.toString()); // Displays: File Name: uploads/excel/<Excel file selected to import>
Resource resource = new FileSystemResource(file);
System.out.println("File exists? " + resource.exists()); // Displays: File exists? true
reader.setResource(resource);
reader.setRowMapper(excelRowMapper(clazz));
reader.afterPropertiesSet(); // To ensure proper set
reader.open(new ExecutionContext()); // To ensure properly opened and accessible file
return reader;
}
private static <T> RowMapper<T> excelRowMapper(Class<T> clazz) {
BeanWrapperRowMapper<T> rowMapper = new BeanWrapperRowMapper<>();
rowMapper.setTargetType(clazz);
rowMapper.afterPropertiesSet();
return rowMapper;
}
}
And when you are doing reading the file you should actually call close()
on the PoiItemReader
to properly close the underlying resources. If you don't call close()
you have a resource leak and eventually your application will halt with an error indicating that you have too many files open.
@PostMapping("/import")
public String importStudents(@RequestParam String fileName, RedirectAttributes redirectAttributes) throws Exception {
PoiItemReader<Student> studentItemReader = ExcelUtils.excelToItemReader(storageService.load(fileName), Student.class);
try {
Student student = studentItemReader.read();
finally {
studentItemReader.close(); // Close reader to release resources
}
if (student != null) {
System.out.println("Student has data.");
studentService.save(student);
} else {
System.out.println("Student is null");
throw new Exception("Student is null");
}
redirectAttributes.addFlashAttribute("message", "You successfully imported students data from " + fileName + "!");
return "redirect:/students";
}
Closing due to inactivity.
I'm using Spring Batch Excel Extension to read Excel (.xlx) file. I cloned the source and did mvn install and added the dependency to my Spring Boot project. I also added Apache poi-ooxml.
My Excel file has simple data:
This is my Student class:
I created utility class whose method does actual reading of Excel file:
After uploading the files, I would select a file to import its data to my database:
I don't understand why student is getting null when there is not error being logged in console at all.