Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从Excel文件中获取值并放入数据库_Java_Database_Excel_Apache Poi_Xlsm - Fatal编程技术网

Java 从Excel文件中获取值并放入数据库

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

我必须将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!!
 * @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());
    }
}