1. 程式人生 > 其它 >java去掉excel空行報錯

java去掉excel空行報錯

技術標籤:隨手記excelpoijavabug

功能需求:

傳入一個excel,刪除其中所有空行,返回新的excel

出現問題:

刪除空行後的檔案,可以正常開啟,但是接下的程式碼處理會報錯:

Invalid column index (-1). Allowable column range for BIFF8 is (0..255) or (‘A‘..‘IV‘) xxxxxx 異常

除錯報錯程式碼,發現程式碼處理excel時,sheet的row數目與實際的數量不一致。

原本excel資料:

去掉空行後的excel:

但是處理後的excel,sheet頁物件的row資料還有4行,並不是看到的2行。

初步判斷還有兩個空行沒過濾掉

解決程式碼

   /**
     * @param firstRow       從第幾行開始檢測空行
     * @param inPutFilePath  檔案路徑
     * @param outPutFilePath 檔案寫出路徑
     * @return void
     * @throws
     * @Author hxh
     * @Date 2021-01-25 16:32:16
     * @Desc: 去除excel裡的空行
     */
    public static void trimExcel(int firstRow, String inPutFilePath, String outPutFilePath) {
        Workbook wb = null;
        if (inPutFilePath == null) {
            return;
        }
        String extString = inPutFilePath.substring(inPutFilePath.lastIndexOf("."));
        InputStream is = null;
        try {
            is = new FileInputStream(inPutFilePath);
            if (extString.equals(".xls")) {
                wb = new HSSFWorkbook(is);
            } else if (".xlsx".equals(extString)) {
                wb = new XSSFWorkbook(is);
            } else {
                wb = null;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        Sheet sheet = null;
        Row row = null;
        String cellData = null;
        boolean empty = true;
        int useRows = firstRow;
        if (wb != null) {
            //獲取第一個sheet
            sheet = wb.getSheetAt(0);
            //獲取最大行數 從0開始算
            int rownum = Math.max(sheet.getLastRowNum(),sheet.getPhysicalNumberOfRows())+1;
            //獲取最大列數
            int colnum = 0;
            for (int i = firstRow; i < rownum; i++) {
                row = sheet.getRow(i);
                if (row != null) {
                    colnum = Math.max( row.getLastCellNum(),row.getPhysicalNumberOfCells());
                    empty = true;
                    for (int j = 0; j < colnum; j++) {
                        cellData = (String) getCellFormatValue(row.getCell(j));
                        if (StringUtils.isNotBlank(cellData)) {
                            empty = false;
                            useRows++;
                            break;
                        }
                    }
                    if (empty) {
                        sheet.removeRow(row);
                        sheet.shiftRows(i + 1, rownum, -1);
                        i--;
                        rownum--;
                    }

                } else {
                    sheet.shiftRows(i + 1, rownum, -1);
                    i--;
                    rownum--;
                }
            }

//          rownum = sheet.getPhysicalNumberOfRows(); 
//      begin      這是個大坑!!!程式碼後來才加上去的
            rownum = Math.max(sheet.getLastRowNum(),sheet.getPhysicalNumberOfRows());
            for (int i=useRows;i<rownum;i++){
                row = sheet.getRow(i);
                sheet.removeRow(row);
            }
//      end      這是個大坑!!!程式碼後來才加上去的

            FileOutputStream out = null;
            try {
                out = new FileOutputStream(outPutFilePath);
                wb.write(out);
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (out != null)
                        out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

注意:

去掉空行後,除錯發現

sheet.getPhysicalNumberOfRows();結果是4
sheet.getLastRowNum(); 結果是2

大坑,按照解釋:

getPhysicalNumberOfRows()獲取的是物理行數,也就是不包括那些空行(隔行)的情況。

getLastRowNum()獲取的是最後一行的編號(編號從0開始)。

原以為getLastRowNum 一定會大於getPhysicalNumberOfRows,但是實際卻不是,看到除錯結果也是一臉懵逼,不知道為什麼,知道的小夥伴可以解釋下。