0

我正在使用 SpringMVC 在 Spring 中开发一个项目。我正在从 (.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;
}
}
4

1 回答 1

1

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

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

如果您想继续使用 Excel,最耗时但可能是最正确的方法是构建一个中间件层来解析行并正确识别和格式化单元格值。可以使用 Apache POI 和 HSSF & 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
于 2015-08-25T15:39:49.813 回答