当前位置: 首页 > 知识库问答 >
问题:

使用Apache POI事件模型读取空单元格(第一列)

范浩荡
2023-03-14

下面是XLS的代码:

public void processRecord(Record record) {
        int thisRow = -1;
        String thisStr = null;

        switch (record.getSid()) {
            case BoundSheetRecord.sid:
                boundSheetRecords.add(record);
                break;
            case BOFRecord.sid:
                BOFRecord br = (BOFRecord)record;
                if(br.getType() == BOFRecord.TYPE_WORKSHEET) {
                    // Works by ordering the BSRs by the location of their BOFRecords, and then knowing that we
                    // process BOFRecords in byte offset order
                    if(orderedBSRs == null) {
                        orderedBSRs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);
                    }

                    // Check the existence of sheets
                    if(sheetIndex == 0) {
                        for(int i=0;i<excelSheetList.length;i++) {
                            boolean found = false;
                            for(int j=0;j<orderedBSRs.length;j++) {
                                if(this.getExcelSheetSpecification().equals(MSExcelAdapter.USE_WORKSHEET_NAME)) {
                                    String sheetName = ((BoundSheetRecord) boundSheetRecords.get(j)).getSheetname();
                                    if(excelSheetList[i].equals(sheetName)) {
                                        found = true;
                                        break;
                                    }
                                } else {
                                    try {
                                        if(Integer.parseInt(excelSheetList[i]) == j) {
                                            found = true;
                                            break;
                                        }
                                    } catch (NumberFormatException e) {
                                    }
                                }
                            }
                            if(!found)
                                this.warning("processRecord()","Sheet: " + excelSheetList[i] + " does not exist.");
                        }
                    }

                    readCurrentSheet = true;
                    sheetIndex++;
                    if(this.getExcelSheetSpecification().equals(MSExcelAdapter.USE_WORKSHEET_NAME)) {
                        String sheetName = ((BoundSheetRecord) boundSheetRecords.get(sheetIndex-1)).getSheetname();
                        if(!canRead(sheetName)) {
                            readCurrentSheet = false;                       
                        }
                    } else {
                        if(!canRead(sheetIndex + "")) {
                            readCurrentSheet = false;
                        }
                    }
                }
                break;

            case SSTRecord.sid:
                sstRecord = (SSTRecord) record;
                break;

            case BlankRecord.sid:
                BlankRecord brec = (BlankRecord) record;

                thisRow = brec.getRow();
                thisStr = null;
                values.add(thisStr);
                columnCount++;
                break;

            case FormulaRecord.sid:
                FormulaRecord frec = (FormulaRecord) record;

                thisRow = frec.getRow();
                if(Double.isNaN( frec.getValue() )) {
                    // Formula result is a string
                    // This is stored in the next record
                    outputNextStringRecord = true;
                    nextRow = frec.getRow();
                } else {
                    thisStr = formatListener.formatNumberDateCell(frec);
                }
                break;  

            case StringRecord.sid:
                if(outputNextStringRecord) {
                    // String for formula
                    StringRecord srec = (StringRecord)record;
                    thisStr = srec.getString();
                    thisRow = nextRow;
                    outputNextStringRecord = false;
                }
                break;

            case LabelSSTRecord.sid:
                if(readCurrentSheet) {
                    LabelSSTRecord lsrec = (LabelSSTRecord) record;
                    thisRow = lsrec.getRow() + 1;
                    if(rowNumberList.contains(thisRow + "") ||
                            (rowNumberList.contains(END_OF_ROWS) && thisRow >= secondLastRow)) {
                        if(sstRecord == null) {
                            thisStr = "(No SST Record, can't identify string)";
                        } else {
                            thisStr = sstRecord.getString(lsrec.getSSTIndex()).toString();
                        }
                    }
                }
                break;

            case NumberRecord.sid:
                if(readCurrentSheet) {
                    NumberRecord numrec = (NumberRecord) record;
                    thisRow = numrec.getRow() + 1;
                    if(rowNumberList.contains(thisRow + "") ||
                                (rowNumberList.contains(END_OF_ROWS) && thisRow >= secondLastRow)) {
                            thisStr = formatListener.formatNumberDateCell(numrec); // Format
                    }
                }
                break;
            default:
                break;
        }

        // Handle missing column
        if(record instanceof MissingCellDummyRecord) {
            thisStr = "";
        }

        // If we got something to print out, do so
        if(thisStr != null) {
            values.add(thisStr);
            columnCount++;
        }

        // Handle end of row
        if(record instanceof LastCellOfRowDummyRecord) { 
               .....
        }
        ...

对于xlsx,如果第一列有空单元格,则跳过它。下面是XLSX的代码:

 /** 
     * Default handler for parsing an excel sheet
     * @see org.xml.sax.helpers.DefaultHandler
     */
    private class SheetHandler extends DefaultHandler {
        private SharedStringsTable sst;
        private String lastContents;
        private boolean nextIsString;
        private MSExcelReader reader;

        private int thisColumn = -1;
        private int lastColumnNumber = -1;  // The last column printed to the output stream

        private SheetHandler(SharedStringsTable sst, MSExcelReader reader) {
            this.sst = sst;
            this.reader = reader;
        }

        public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
            // c => cell
            if(name.equals("c")) {
                // Figure out if the value is an index in the SST
                String cellType = attributes.getValue("t");
                if(cellType != null && cellType.equals("s")) {
                    nextIsString = true;
                } else {
                    nextIsString = false;
                }
                // Get the cell reference
                String r = attributes.getValue("r");
                int firstDigit = -1;
                for (int c = 0; c < r.length(); ++c) {
                    if (Character.isDigit(r.charAt(c))) {
                        firstDigit = c;
                        break;
                    }
                }
                thisColumn = nameToColumn(r.substring(0, firstDigit));
            }
            // Clear contents cache
            lastContents = "";
        }

        public void endElement(String uri, String localName, String name) throws SAXException {
            // Process the last contents as required.
            // Do now, as characters() may be called more than once
            if(nextIsString) {
                try {
                    int idx = Integer.parseInt(lastContents);
                    lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
                } catch (NumberFormatException e) {
                }
            }

            // v => contents of a cell
            // Output after we've seen the string contents
            if(name.equals("v")) {
                for (int i = lastColumnNumber; i < thisColumn - 1; ++i)
                    values.add(null);  // Add empty string for missing columns

                values.add(lastContents);

                // Update column
                if (thisColumn > -1)
                    lastColumnNumber = thisColumn;
            }

            if(name.equals("row")) {
            ...

与我的老问题一样,需要提到的是:我不是使用usermodel(org.apache.poi.ss.usermodel),而是使用一个事件API来处理xls和xlsx文件。

Column1 Column2 Column3 Column4 Column5 Column6 Column7
        Parag   Joshi   Pune                100     
        Parag   Joshi   Pune    200         
;Parag;Joshi;Pune;null;100;null
;Parag;Joshi;Pune;200;null;null

如上所示,它为第一列打印空字符串,但为其他列打印值NULL。我希望第一列打印相同的值NULL。

共有1个答案

锺离赤岩
2023-03-14

如果你有比这更干净的方法,请指教,谢谢!

创建一个ArrayList来存储ColumnIndex;

    ArrayList<Integer> listAllColInRow = new ArrayList<>(); 

创建ArrayList来存储数据;

    addDataToRow = new ArrayList<>();    
    while (cells.hasNext()) {   
        cell = (HSSFCell) cells.next();    
        int col = cell.getColumnIndex();    
        listAllColInRow.add(col);    
    }   
    Integer a = listAllColInRow.get(0);    
    // while a is not the 1st column    
    while( a != 0){    
        //add null to the 1st index of the ArrayList    
        addDataToRow.add(0,null);    
        a--;    
    }   
 类似资料:
  • 我有一个巨大的excel文件,其中包含大量列,如下所示:- 当我打印excel中的所有值时,我的代码生成的输出是:- 所以,如果我们看看上面的输出,我们可以注意到我留下空白值的单元格没有被POI库拾取。有没有一种方法可以让这些值为空?还是一种识别所呈现的值跳过空白单元格的方法? 请注意:我使用的不是usermodel(org.apache.poi.ss.usermodel),而是一个事件API来处

  • 我是否遗漏了一些奇怪的设置,会使忽略空白单元格? 最后我编写了一个helper函数,该函数删除了col_n)列。

  • 我有一个excel文件,其中有一个时间戳列,填充值为5/31/2011 5:49:44 PM。我正在使用POI事件模型读取此excel文件。(实施方式与中的说明相同http://poi.apache.org/spreadsheet/how-to.html#sxssf-“XSSF和SAX(事件API)”)上面的时间戳值被读取为40694.74287037037,我不知道为什么。我无法将此值格式化回日

  • 在谷歌搜索StackOverflow之后,我还没有找到与这个问题相关的地方。目前我可以将空白单元格读取为空,但一次只能读取一个单元格。所以我必须写这样的东西: 这对我来说不太好,因为我对重复感到不满。我们可以设置返回?

  • 我正在使用Apache POI读取零件编号电子表格中的数据。我在我们的数据库中查找零件编号,如果我们有零件的计算机辅助设计图纸,我将零件编号单元格涂成绿色,如果没有,我将其涂成红色。处理完成后,将保存电子表格。我遇到的问题是那列中的每个细胞都是绿色的。我已经完成了代码,查找零件号的逻辑工作正常,确定单元格应该是什么颜色以及设置颜色和填充的逻辑似乎也工作正常。知道我做错了什么吗? 谢谢

  • 我正在使用Poi.jar从excel表输入,想知道如何检查单元格是否为空。 现在我使用下面的代码。