Java 从Excel文件中获取值并放入数据库
我必须将Excel文件映射到数据库值。考虑到Excel文件中有很多行我正在使用,否则,使用ApachePOI时,我会收到内存错误。 这是不适用于大文件的旧代码:Java 从Excel文件中获取值并放入数据库,java,database,excel,apache-poi,xlsm,Java,Database,Excel,Apache Poi,Xlsm,我必须将Excel文件映射到数据库值。考虑到Excel文件中有很多行我正在使用,否则,使用ApachePOI时,我会收到内存错误。 这是不适用于大文件的旧代码: /** * Private method called from single and multiple file upload to retrieve the excel fields values * This method works if THE EXCEL FILE IS WITHOUT empty row!! * @p
/**
* Private method called from single and multiple file upload to retrieve the excel fields values
* This method works if THE EXCEL FILE IS WITHOUT empty row!!
* @param file
* @return
* @throws IOException
*/
private ExcelField[][] getExcelField(MultipartFile file) throws IOException{
try{
ArrayList<ArrayList<ExcelField>> valuesMatrix= new ArrayList<ArrayList<ExcelField>>();
Workbook wb = WorkbookFactory.create(file.getInputStream());
//Sheet to use
Sheet firstSheet = wb.getSheetAt(0);
//Assuming that the first row is without blank cell and it has the maximum number of columns.
//numCol IS NECESSARY BECAUSE IF THERE IS A EMPTY CELL AT THE LAST POSITION OF THE ROW THE GETLASTCELLNUM RETURN
//THE NUMBER OF ROWS WITHOUT THE LAST
int numCol=firstSheet.getRow(0).getLastCellNum();
int numRow=firstSheet.getPhysicalNumberOfRows();
for(int rw=0;rw<numRow;rw++) {
Row row=firstSheet.getRow(rw);
ArrayList<ExcelField> rowValues=new ArrayList<ExcelField>();
for(int cn=0; cn<numCol; cn++) {
Cell cell = row.getCell(cn, Row.CREATE_NULL_AS_BLANK);
rowValues.add(getCellValue(cell));
//Print into console the fields values
//System.out.print(getCellValue(cell).getValue()!=null?getCellValue(cell).getValue().toString():" null"+" ");
}
valuesMatrix.add(rowValues);
//System.out.println();
}
wb.close();
return convert2DimensionalArrayToMatrix(valuesMatrix);
} catch (EncryptedDocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
相反,日期返回空值。我不关心公式,但我对值感兴趣,因为我必须将它存储在数据库中。这是我的代码:
@Override
public Response<ExcelField[][]> singleFileOpen(MultipartFile file) throws FileEmptyException, FileUploadException{
if (!file.isEmpty()) {
try {
openedFile=file;
//Retrieve the fields values
// ExcelField[][] valuesMatrix=getExcelField(openedFile);
ExcelField[][] valuesMatrix=getExcelFieldSpeedImproved(openedFile);
// //return the Response with status ad excel fields
return new Response<ExcelField[][]>(HttpStatus.OK.value(),valuesMatrix);
} catch (Exception e) {
throw new FileUploadException("You failed to read " + openedFile.getOriginalFilename(), e);
}
} else {
throw new FileEmptyException("You failed to read" );
}
}
检索Excel值的最佳方法是什么
更新:使用此代码,我使用旧方法、日期和公式进行解析:
/**
* Retrieve the value in one excel field
* @param cell
* @return
*/
private ExcelField getCellValue(int cellType, Cell cell) {
switch (cellType) {
case Cell.CELL_TYPE_STRING:
return new ExcelField(ExcelTypeEnum.STRING,cell.getStringCellValue());
case Cell.CELL_TYPE_BOOLEAN:
return new ExcelField(ExcelTypeEnum.BOOLEAN,cell.getBooleanCellValue());
case Cell.CELL_TYPE_NUMERIC:
if (HSSFDateUtil.isCellDateFormatted(cell))
//SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
//System.out.print(dateFormat.format(cell.getDateCellValue()) + "\t\t");
return new ExcelField(ExcelTypeEnum.NUMERIC,cell.getDateCellValue());
return new ExcelField(ExcelTypeEnum.NUMERIC,cell.getNumericCellValue());
case Cell.CELL_TYPE_ERROR:
return new ExcelField(ExcelTypeEnum.ERROR,cell.getErrorCellValue());
case Cell.CELL_TYPE_FORMULA:
return getCellValue(cell.getCachedFormulaResultType(),cell);
case Cell.CELL_TYPE_BLANK:
return new ExcelField(ExcelTypeEnum.BLANK,null);
default:
return new ExcelField(ExcelTypeEnum.BLANK,cell.getStringCellValue());
}
}
看起来像ApachePOI周围的一个bug包装器。为什么不自己调用Apache POI XLSX事件流代码呢?我发布了旧代码,我不得不在工作簿wb=WorkbookFactory.create(file.getInputStream())上等待很长时间;然后我接收到内存异常WorkbookFactory使用UserModel代码,这很简单,但是使用内存。也许我已经解决了这个链接,你会更好,这表明它是多么容易做到正确!
private ExcelField[][] getExcelFieldSpeedImproved(MultipartFile file) throws IOException{
ArrayList<ArrayList<ExcelField>> valuesMatrix= new ArrayList<ArrayList<ExcelField>>();
InputStream is = file.getInputStream();
StreamingReader reader = StreamingReader.builder()
.rowCacheSize(100) // number of rows to keep in memory (defaults to 10)
.bufferSize(4096) // buffer size to use when reading InputStream to file (defaults to 1024)
.sheetIndex(0) // index of sheet to use (defaults to 0)
.read(is); // InputStream or File for XLSX file (required)
for (Row r : reader) {
ArrayList<ExcelField> rowValues=new ArrayList<ExcelField>();
for (Cell c : r) {
rowValues.add(getCellValue(c));
System.out.print((String)getCellValue(c).getValue()+" ");
}
valuesMatrix.add(rowValues);
System.out.println();
}
return convert2DimensionalArrayToMatrix(valuesMatrix);
}
/**
* Retrieve the value in one excel field
* @param cell
* @return
*/
private ExcelField getCellValue(Cell cell) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
return new ExcelField(ExcelTypeEnum.STRING,cell.getStringCellValue());
case Cell.CELL_TYPE_BOOLEAN:
return new ExcelField(ExcelTypeEnum.BOOLEAN,cell.getBooleanCellValue());
case Cell.CELL_TYPE_NUMERIC:
return new ExcelField(ExcelTypeEnum.NUMERIC,cell.getNumericCellValue());
case Cell.CELL_TYPE_ERROR:
return new ExcelField(ExcelTypeEnum.ERROR,cell.getErrorCellValue());
case Cell.CELL_TYPE_FORMULA:
return new ExcelField(ExcelTypeEnum.FORMULA,cell.getCachedFormulaResultType());
default:
return new ExcelField(ExcelTypeEnum.BLANK,null);
}
}
/**
* Retrieve the value in one excel field
* @param cell
* @return
*/
private ExcelField getCellValue(int cellType, Cell cell) {
switch (cellType) {
case Cell.CELL_TYPE_STRING:
return new ExcelField(ExcelTypeEnum.STRING,cell.getStringCellValue());
case Cell.CELL_TYPE_BOOLEAN:
return new ExcelField(ExcelTypeEnum.BOOLEAN,cell.getBooleanCellValue());
case Cell.CELL_TYPE_NUMERIC:
if (HSSFDateUtil.isCellDateFormatted(cell))
//SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
//System.out.print(dateFormat.format(cell.getDateCellValue()) + "\t\t");
return new ExcelField(ExcelTypeEnum.NUMERIC,cell.getDateCellValue());
return new ExcelField(ExcelTypeEnum.NUMERIC,cell.getNumericCellValue());
case Cell.CELL_TYPE_ERROR:
return new ExcelField(ExcelTypeEnum.ERROR,cell.getErrorCellValue());
case Cell.CELL_TYPE_FORMULA:
return getCellValue(cell.getCachedFormulaResultType(),cell);
case Cell.CELL_TYPE_BLANK:
return new ExcelField(ExcelTypeEnum.BLANK,null);
default:
return new ExcelField(ExcelTypeEnum.BLANK,cell.getStringCellValue());
}
}