Как читать пустые ячейки файла Excel с помощью POI - PullRequest
10 голосов
/ 16 декабря 2011

Я пытался прочитать файл Excel с помощью POI, а затем я хотел поместить эти данные в 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.

Вот как я решил это после дополнительных поисков в Google: -)

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 ]

20 голосов
/ 16 декабря 2011

Итераторы возвращают вам ячейки, которые фактически существуют в файле.Если вы пытаетесь повторить их позиции, это почти наверняка не то, что вам нужно, вместо этого вы захотите проверять каждую ячейку по очереди

Скорее всего, вам понадобится код:

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)

2 голосов
/ 18 июля 2018

Вот как я это сделал.Надеюсь это поможет.Убедитесь, что вы импортируете необходимые вещи.в вашем проекте.

            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);
                        }
                    }
                }
            }
0 голосов
/ 21 сентября 2018

Использовал это, основываясь на предыдущих ответах.

    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;
        }
    }
0 голосов
/ 23 августа 2016

Следующий код получит все значения ячеек на основе размера заголовка.

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()
    }
...