Repository: wangguanquan/eec
Pull request #315 (2022-12-09 01:57:26)

#314 Row#isBlank


Patch:
diff --git a/src/main/java/org/ttzero/excel/reader/Row.java b/src/main/java/org/ttzero/excel/reader/Row.java
index 630ef237..2dff9ba3 100644
--- a/src/main/java/org/ttzero/excel/reader/Row.java
+++ b/src/main/java/org/ttzero/excel/reader/Row.java
@@ -114,7 +114,7 @@ public abstract class Row {
     }
 
     /**
-     * Returns the index of the last column (zero base).
+     * Returns the index of the last column (zero base, exclude).
      * The last index of column is increment the max available index
      *
      * @return the last column index
@@ -132,6 +132,21 @@ public abstract class Row {
         return lc - fc <= 0;
     }
 
+    /**
+     * Tests the value of all cells is null or whitespace
+     *
+     * @return true if all cell value is null
+     */
+    public boolean isBlank() {
+        if (lc > fc) {
+            for (int i = fc; i < lc; i++) {
+                Cell c = cells[i];
+                if (!isBlank(c)) return false;
+            }
+        }
+        return true;
+    }
+
     /**
      * Check the cell ranges,
      *
@@ -172,7 +187,7 @@ public abstract class Row {
      *
      * @return header Row
      */
-    protected HeaderRow asHeader() {
+    public HeaderRow asHeader() {
         return new HeaderRow().with(this);
     }
 
@@ -182,7 +197,7 @@ public abstract class Row {
      * @param hr {@link HeaderRow}
      * @return self
      */
-    protected Row setHr(HeaderRow hr) {
+    public Row setHr(HeaderRow hr) {
         this.hr = hr;
         return this;
     }
@@ -215,7 +230,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return {@code Boolean}
      */
-    protected Boolean getBoolean(Cell c) {
+    public Boolean getBoolean(Cell c) {
         boolean v;
         switch (c.t) {
             case BOOL:
@@ -270,7 +285,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return {@code Byte}
      */
-    protected Byte getByte(Cell c) {
+    public Byte getByte(Cell c) {
         byte b = 0;
         switch (c.t) {
             case NUMERIC:
@@ -323,7 +338,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return {@code Character}
      */
-    protected Character getChar(Cell c) {
+    public Character getChar(Cell c) {
         char cc = 0;
         switch (c.t) {
             case SST:
@@ -386,7 +401,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return {@code Short}
      */
-    protected Short getShort(Cell c) {
+    public Short getShort(Cell c) {
         short s = 0;
         switch (c.t) {
             case NUMERIC:
@@ -454,7 +469,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return {@code Integer}
      */
-    protected Integer getInt(Cell c) {
+    public Integer getInt(Cell c) {
         int n;
         switch (c.t) {
             case NUMERIC:
@@ -523,7 +538,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return {@code Long}
      */
-    protected Long getLong(Cell c) {
+    public Long getLong(Cell c) {
         long l;
         switch (c.t) {
             case LONG:
@@ -591,7 +606,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return string
      */
-    protected String getString(Cell c) {
+    public String getString(Cell c) {
         String s;
         switch (c.t) {
             case SST:
@@ -674,7 +689,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return {@code Double}
      */
-    protected Double getDouble(Cell c) {
+    public Double getDouble(Cell c) {
         double d;
         switch (c.t) {
             case DOUBLE:
@@ -734,7 +749,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return BigDecimal
      */
-    protected BigDecimal getDecimal(Cell c) {
+    public BigDecimal getDecimal(Cell c) {
         BigDecimal bd;
         switch (c.t) {
             case DOUBLE:
@@ -793,7 +808,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return BigDecimal
      */
-    protected Date getDate(Cell c) {
+    public Date getDate(Cell c) {
         Date date;
         switch (c.t) {
             case NUMERIC:
@@ -849,7 +864,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return java.sql.Timestamp
      */
-    protected Timestamp getTimestamp(Cell c) {
+    public Timestamp getTimestamp(Cell c) {
         Timestamp ts;
         switch (c.t) {
             case NUMERIC:
@@ -903,7 +918,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return java.sql.Time
      */
-    protected java.sql.Time getTime(Cell c) {
+    public java.sql.Time getTime(Cell c) {
         java.sql.Time t;
         switch (c.t) {
             case DOUBLE: t = toTime(c.dv); break;
@@ -953,7 +968,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return java.time.LocalDateTime
      */
-    protected LocalDateTime getLocalDateTime(Cell c) {
+    public LocalDateTime getLocalDateTime(Cell c) {
         LocalDateTime ldt;
         switch (c.t) {
             case NUMERIC:
@@ -1009,7 +1024,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return java.time.LocalDate
      */
-    protected LocalDate getLocalDate(Cell c) {
+    public LocalDate getLocalDate(Cell c) {
         LocalDate ld;
         switch (c.t) {
             case NUMERIC:
@@ -1065,7 +1080,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return java.time.LocalTime
      */
-    protected LocalTime getLocalTime(Cell c) {
+    public LocalTime getLocalTime(Cell c) {
         LocalTime lt;
         switch (c.t) {
             case NUMERIC:
@@ -1171,7 +1186,7 @@ public abstract class Row {
      * @param c the {@link Cell}
      * @return the {@link CellType}
      */
-    protected CellType getCellType(Cell c) {
+    public CellType getCellType(Cell c) {
         CellType type;
         switch (c.t) {
             case SST:
@@ -1209,6 +1224,55 @@ public abstract class Row {
         return type;
     }
 
+    /**
+     * Tests the specify cell value is blank
+     *
+     * @param columnIndex the cell index
+     * @return true if cell value is blank
+     */
+    public boolean isBlank(int columnIndex) {
+        Cell c = getCell(columnIndex);
+        return isBlank(c);
+    }
+
+    /**
+     * Tests the specify cell value is blank
+     *
+     * @param columnName the cell name
+     * @return true if cell value is blank
+     */
+    public boolean isBlank(String columnName) {
+        Cell c = getCell(columnName);
+        return isBlank(c);
+    }
+
+    /**
+     * Tests the specify cell value is blank
+     *
+     * @param c the {@link Cell}
+     * @return true if cell value is blank
+     */
+    public boolean isBlank(Cell c) {
+        boolean blank;
+        switch (c.t) {
+            case SST:
+                if (c.sv == null) {
+                    c.setSv(sst.get(c.nv));
+                }
+                // @Mark:=>There is no missing `break`, this is normal logic here
+            case INLINESTR:
+                blank = StringUtil.isBlank(c.sv);
+                break;
+            case BLANK:
+            case EMPTY_TAG:
+            case UNALLOCATED:
+                blank = true;
+                break;
+            default: blank = false;
+        }
+        return blank;
+    }
+
     /**
      * Returns the binding type if is bound, otherwise returns Row
      *
diff --git a/src/main/java/org/ttzero/excel/reader/RowSetIterator.java b/src/main/java/org/ttzero/excel/reader/RowSetIterator.java
index 1bbaf471..9e91a512 100644
--- a/src/main/java/org/ttzero/excel/reader/RowSetIterator.java
+++ b/src/main/java/org/ttzero/excel/reader/RowSetIterator.java
@@ -39,8 +39,8 @@ public class RowSetIterator implements Iterator<Row> {
             return true;
         } else {
             if (onlyDataRow) {
-                // Skip empty rows
-                for (; (nextRow = supplier.get()) != null && nextRow.isEmpty(); ) ;
+                // Skip blank rows
+                for (; (nextRow = supplier.get()) != null && nextRow.isBlank(); ) ;
             } else {
                 nextRow = supplier.get();
             }


Test patch:
diff --git a/src/test/java/org/ttzero/excel/annotation/CustomAnnoReaderTest.java b/src/test/java/org/ttzero/excel/annotation/CustomAnnoReaderTest.java
index 2e3ce917..3d3973a1 100644
--- a/src/test/java/org/ttzero/excel/annotation/CustomAnnoReaderTest.java
+++ b/src/test/java/org/ttzero/excel/annotation/CustomAnnoReaderTest.java
@@ -87,7 +87,7 @@ public class CustomAnnoReaderTest {
 
     public static class MyRow extends XMLRow {
         @Override
-        protected HeaderRow asHeader() {
+        public HeaderRow asHeader() {
             return new HeaderRow() {
                 @Override
                 protected ListSheet.EntryColumn createColumn(AccessibleObject ao) {
diff --git a/src/test/java/org/ttzero/excel/reader/ExcelReaderTest2.java b/src/test/java/org/ttzero/excel/reader/ExcelReaderTest2.java
new file mode 100644
index 00000000..3a2f03c3
--- /dev/null
+++ b/src/test/java/org/ttzero/excel/reader/ExcelReaderTest2.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017-2023, guanquan.wang@yandex.com All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.ttzero.excel.reader;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.ttzero.excel.reader.ExcelReaderTest.testResourceRoot;
+
+/**
+ * @author guanquan.wang at 2023-01-06 09:32
+ */
+public class ExcelReaderTest2 {
+    @Test public void testIsBlank() throws IOException {
+        try (ExcelReader reader = ExcelReader.read(testResourceRoot().resolve("#150.xlsx"))) {
+            reader.sheet(0).rows().forEach(row -> {
+                switch (row.getRowNum()) {
+                    case 1:
+                        assert !row.isEmpty();
+                        assert !row.isBlank();
+                        break;
+                    case 2:
+                        assert !row.isEmpty();
+                        assert row.isBlank();
+                        break;
+                }
+            });
+        }
+    }
+}