字符串在春天自动转换

时间:2015-08-25 14:39:42

标签: excel type-conversion apache-poi implicit-conversion hssf

我正在Spring中使用SpringMVC开发一个项目。我正在从(.xls)文件导入数据。

问题是:

  • 我正在将此值“ 945854955 ”作为字符串读取,但在数据库中保存为“ 9.45854955E8

  • 此值“ 26929 ”保存为“ 26929.0

  • 此值“ 21/05/1987 ”保存为“ 31918.0

/阅读代码

    // import ...
    @RequestMapping(value="/read")
    public String Read(Model model,@RequestParam CommonsMultipartFile[] fileUpload)
    throws IOException, EncryptedDocumentException, InvalidFormatException {

    List<String> liste = new ArrayList();
    Employe employe = new Employe();
    String modelnom = null;

    liste = extraire(modelnom); //See the second code

    for (int m=0, i=29;i<liste.size();i=i+29) {
        if(i % 29 == 0) {
            m++;
        }
            employe.setNomEmploye(liste.get(29*m+1));
            //...
            employe.setDateNaissance((String)liste.get(29*m+8).toString());  // here i had the date problem
            employe.setDateEntree((String)liste.get(29*m+9).toString());     // here i had the date problem
            employe.setDateSortie((String)liste.get(29*m+10).toString());    // here i had the date problem
            // ...
            employe.setNumCpteBanc(liste.get(29*m+17)); // here i had the first & second case problem
            employe.setNumCIMR(liste.get(29*m+19));     // here i had the first & second case problem
            employe.setNumMUT(liste.get(29*m+20));      // here i had the first & second case problem
            employe.setNumCNSS(liste.get(29*m+21));     // here i had the first & second case problem

            boolean bool=true;
            List<Employe> employes = dbE.getAll();// liste des employes

            for (int n=0;n<employes.size();n++) {
                if (employes.get(n).getMatriculeMY() ==  (int)mat ) {
                    bool= false;
                }
            }
            if (bool) {

                dbE.create(employe);
            }
    }
     return "redirect";
    }

外部代码

private List<String> extraire (String nomFichier) throws IOException {
    List<String> liste = new ArrayList();
    FileInputStream fis = new FileInputStream(new File(nomFichier));
    HSSFWorkbook  workbook = new HSSFWorkbook(fis);
    HSSFSheet spreadsheet = workbook.getSheetAt(0);
    Iterator < Row > rowIterator = null;
// recup une ligne
    rowIterator = spreadsheet.iterator();
    while (rowIterator.hasNext()) {
        int i = 0;
        row =  (HSSFRow) rowIterator.next();
        Iterator < Cell > cellIterator = row.cellIterator();
        while ( cellIterator.hasNext()) {
            Cell cell = cellIterator.next();
            i++;
            /**
             * Pour verifier si une ligne est vide. (for verifing if the line is empty)
             */
            if (i % 29 == 0 || i == 1) {
                while ( cellIterator.hasNext() && cell.getCellType() == Cell.CELL_TYPE_BLANK) {
                    cell = cellIterator.next();
                }
            }

            switch (cell.getCellType()) {
                case Cell.CELL_TYPE_NUMERIC:
                    String cellule = String.valueOf(cell.getNumericCellValue());
                    liste.add(cellule);
                    break;
                case Cell.CELL_TYPE_STRING:
                    liste.add(cell.getStringCellValue());
                    break;
                case Cell.CELL_TYPE_BLANK:
                     cellule = " ";
                             liste.add(cellule);
                             break;
            }
        }
    }
        fis.close();
        return liste;
}
}

1 个答案:

答案 0 :(得分:1)

Excel尝试数据类型单元格,有时当您明确指定数据类型时,Excel可能会尝试并转换单元格。您可以尝试右键单击单元格并选择“格式化单元格”,然后选择“文本”作为类型(类别)。但是,在解析时,它仍然可能会被淹没。

您最快的解决方案可能是将文件另存为CSV并使用它。您仍然可以在Excel中编辑它。虽然您需要进行一些验证,以确保Excel不会尝试在CSV上执行上述转换另存为。 OpenCSV,Super CSV有很多优秀的Java CSV解析器。

最耗时但可能是最正确的方法,如果您想继续使用Excel,则构建一个中间件层来解析行并正确识别和格式化单元格值。 Apache POI和HSSF&amp;可以使用XSSF。请注意,处理xls和xlsx需要两组不同的库,并且通常需要足够的抽象来处理这两种库。 见https://poi.apache.org/spreadsheet/

作为例子:

protected String getCellValue(final Cell cell){
    if (null == cell) { return null; }
    // For Excel binaries 97 and below, The method of setting the cell type to CELL_TYPE_STRING converts the
    // Formatted to date to a short. To correct this we check that the cell type is numeric and the check that it is
    // date formatted. If we don't check that it is Numeric first an IllegalAccessorException is thrown.
    if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC && isCellDateFormated(cell) {
        // isCellDateFormated is seperate util function to look at the cell value in order to determine if the date is formatted as a double.
        // is a date format.
        return // do date format procedure.
    }
    cell.setTypeCell(Cell.CELL_TYPE_STRING);
    return cell.toString();
}

希望这有帮助。

============更新==================

不要像“getNumericCellValue()”那样调用方法,而是尝试将单元格类型设置为String并使用toString,如上例所示。这是我的测试代码。 注意xls文件在csv中有一行和4个单元格:“abba,1,211,q123,11.22”

public void testExtract() throws Exception{
    InputStream is = new FileInputStream("/path/to/project/Test/src/test/java/excelTest.xls");
    HSSFWorkbook wb = new HSSFWorkbook(is);
    HSSFSheet sheet = wb.getSheetAt(0);
    Iterator<Row> rowIter = sheet.iterator();
    while (rowIter.hasNext()){
        HSSFRow row = (HSSFRow) rowIter.next();
        Iterator<Cell> cellIter = row.cellIterator();
        while (cellIter.hasNext()){
            Cell cell = cellIter.next();
            System.out.println("Raw to string: " + cell.toString());

            // Check for data format here. If you set a date cell to string and to string the response the output is funky.
            cell.setCellType(Cell.CELL_TYPE_STRING);
            System.out.println("Formatted to string: " + cell.toString());
        }
    }
    is.close();
}

输出

Raw to string: abba
Formatted to string: abba
Raw to string: 1.0
Formatted to string: 1
Raw to string: 211.0
Formatted to string: 211
Raw to string: q1123
Formatted to string: q1123
Raw to string: 11.22
Formatted to string: 11.22