如何使用POI读取excel文件的空单元格

时间:2011-12-16 04:28:49

标签: java apache-poi

我尝试使用POI读取excel文件,然后我想将这些数据放入JTable

这是excel文件,

enter image description here

如您所见,上表中有两个空单元格,一旦我将上述数据读入JTable,我得到了以下结果,

enter image description here

在我的JTable中,空单元格已移至错误的位置,我使用以下代码获取此结果,请帮助我获得正确的结果,

private XLSContainer xLSContainer;
    Vector cellVectorHolder;
    private int noOfCells=0;

    public XLSContainer readXLS(XLSFile xLSFile) {
        cellVectorHolder = new Vector();

        try {

            FileInputStream inputStream = new FileInputStream(xLSFile.getFileName());

            POIFSFileSystem pOIFSFileSystem = new POIFSFileSystem(inputStream);

            HSSFWorkbook hSSFWorkbook = new HSSFWorkbook(pOIFSFileSystem);

            HSSFSheet hSSFSheet = hSSFWorkbook.getSheetAt(0);

            Iterator rowIter = hSSFSheet.rowIterator();


            while (rowIter.hasNext()) {
                HSSFRow row = (HSSFRow) rowIter.next();
                if(row.getRowNum()==0){
                    noOfCells = row.getLastCellNum();
                }
                Iterator cellIter = row.cellIterator();

                Vector cellStoreVector = new Vector();

                while (cellIter.hasNext()) {
                    HSSFCell hSSFCell = (HSSFCell) cellIter.next();
                    //System.out.println(hSSFCell.getCellNum());
                    cellStoreVector.addElement(hSSFCell);
                }
                cellVectorHolder.addElement(cellStoreVector);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        feedXLSContainer();
        return xLSContainer;
    }//readXLS

    private void feedXLSContainer() {

        xLSContainer = new XLSContainer();


        for (int i = 0; i < cellVectorHolder.size(); i++) {
            Vector cellStoreVector = (Vector) cellVectorHolder.elementAt(i);
            Vector item = new Vector();
            for (int j = 0; j < cellStoreVector.size(); j++) {
                HSSFCell cell = (HSSFCell) cellStoreVector.elementAt(j);
                item.add(cell.toString());
            }
            if (i == 0) {
                xLSContainer.addHeader(item);
            } else {
                xLSContainer.addRow(item);
            }

        }

    }

我上面所做的是将标题和数据行放在名为xLSContainer的类中的不同向量中,然后将这些向量放入JTable

以下是我在更多谷歌搜索后解决问题的方法: - )

private XLSContainer xLSContainer;

    public XLSContainer readXLS(XLSFile xLSFile) {
        try {

            WorkbookSettings ws = new WorkbookSettings();
            ws.setLocale(new Locale("en", "EN"));
            Workbook workbook = Workbook.getWorkbook(new File(xLSFile.getFileName()), ws);
            Sheet s = workbook.getSheet(0);
            System.out.println("Sheet Content::" + s.getName());
            readDataSheet(s);
            workbook.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return xLSContainer;

    }

    private void readDataSheet(Sheet s) {
        xLSContainer = new XLSContainer();

        int noOfRows = s.getRows();
        int noOfCols = s.getColumns();



        for (int i = 0; i < noOfRows; i++) {
            Vector item = new Vector();
            for (int j = 0; j < noOfCols; j++) {

                if (s.getCell(j, i).getContents() == "") {
                    item.add("");

                } else {
                    item.add(s.getCell(j, i).getContents());

                }
            }

            if (i == 0) {
                xLSContainer.addHeader(item);
            }else{
                xLSContainer.addRow(item);
            }
        }
    }

4 个答案:

答案 0 :(得分:18)

迭代器会返回文件中实际存在的单元格。如果你试图复制他们的位置,那几乎肯定不是你想要的,而是你想要依次检查每个单元格

您可能希望代码类似:

workbook.setMissingCellPolicy(MissingCellPolicy.RETURN_BLANK_AS_NULL);
DataFormatter fmt = new DataFormatter();

for(int sn=0; sn<workbook.getNumberOfSheets(); sn++) {
   Sheet sheet = workbook.getSheetAt(sn);
   for (int rn=sheet.getFirstRowNum(); rn<=sheet.getLastRowNum(); rn++) {
      Row row = sheet.getRow(rn);
      if (row == null) {
         // There is no data in this row, handle as needed
      } else {
         // Row "rn" has data
         for (int cn=0; cn<row.getLastCellNum(); cn++) {
            Cell cell = row.getCell(cn);
            if (cell == null) {
              // This cell is empty/blank/un-used, handle as needed
            } else {
               String cellStr = fmt.formatCell(cell);
               // Do something with the value
            }
         }
      }
   }
}

此代码可让您依次获取每个单元格,并且还可以正确格式化单元格(以便将数字格式化为与Excel中的格式相同)

答案 1 :(得分:2)

这就是我的方法。希望这可以帮助。确保导入必要的东西。在您的项目中。

            FileInputStream excelFile = new FileInputStream(new File(path));
            XSSFWorkbook wb = new XSSFWorkbook(excelFile);
            XSSFSheet sheet = wb.getSheetAt(0);
            XSSFRow row;
            XSSFCell cell;
            Iterator rows = sheet.rowIterator();
            //int count =0;
            DataFormatter df= new DataFormatter();
            while(rows.hasNext()) {
                row = (XSSFRow) rows.next();
                for(int i =1; i< 14; ++i) {
                    cell = row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                    if(cell==null || cell.getCellTypeEnum()== CellType.BLANK) {
                        //count++;
                        //out.println("okay " + count );
                        if(i==1) {
                        declarationDate.add("");
                        }else if(i==2){
                            poNumber.add("");
                        }
                    }else {
                        String str = df.formatCellValue(cell);
                        if(i==1) {
                        declarationDate.add(str);
                        }else if(i==2) {
                            poNumber.add(str);
                        }
                    }
                }
            }

答案 2 :(得分:0)

以下代码将根据标题大小获取所有单元格值。

public String getRowValueAsString(Row row, 
    int sizeOfHeader, String colSep) {

        StringBuffer sBuf = new StringBuffer();
        for (int i = 0; i < sizeOfHeader; i++) {
            Cell cell = row.getCell(i);
            if(cell == null) {
                sBuf.append(colSep);
                continue;
            }
            switch (cell.getCellType()) {

            case Cell.CELL_TYPE_NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    sBuf.append(format.format(cell.getDateCellValue()) + colSep);
                }
                else{
                    sBuf.append(cell.getNumericCellValue() + colSep);
                }
                break;
            case Cell.CELL_TYPE_STRING:
                    sBuf.append(cell.getStringCellValue() + colSep);
                break;
            case Cell.CELL_TYPE_FORMULA:
                sBuf.append(cell.getCellFormula() + colSep);
                break;
            case Cell.CELL_TYPE_BLANK:
                sBuf.append(" "+colSep);
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                sBuf.append(cell.getBooleanCellValue()+ colSep);
                break;
            case Cell.CELL_TYPE_ERROR:
                sBuf.append(cell.getErrorCellValue() + colSep);
                break;
            default:
                sBuf.append(cell.getStringCellValue() + colSep);
                break;
            }
        }
        return sBuf.toString()
    }

答案 3 :(得分:0)

根据先前的答案使用了此功能。

    private static NPOI.SS.UserModel.ICell[] GetCells(NPOI.SS.UserModel.IRow wr, int columnCount)
    {
        try
        {
            List<NPOI.SS.UserModel.ICell> values = new List<NPOI.SS.UserModel.ICell>();

            for (int i = 0; i < columnCount; i++) values.Add(wr.GetCell(i));

            return values.ToArray();
        }
        catch (Exception)
        {
            throw;
        }
    }