diff --git a/fastexcel-reader/src/main/java/org/dhatim/fastexcel/reader/RowSpliterator.java b/fastexcel-reader/src/main/java/org/dhatim/fastexcel/reader/RowSpliterator.java index 6be28ba..8f8485d 100644 --- a/fastexcel-reader/src/main/java/org/dhatim/fastexcel/reader/RowSpliterator.java +++ b/fastexcel-reader/src/main/java/org/dhatim/fastexcel/reader/RowSpliterator.java @@ -15,14 +15,21 @@ */ package org.dhatim.fastexcel.reader; -import javax.xml.stream.XMLStreamException; +import static org.dhatim.fastexcel.reader.DefaultXMLInputFactory.factory; + import java.io.InputStream; import java.math.BigDecimal; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.Spliterator; import java.util.function.Consumer; import java.util.function.Function; -import static org.dhatim.fastexcel.reader.DefaultXMLInputFactory.factory; +import javax.xml.stream.XMLStreamException; class RowSpliterator implements Spliterator { @@ -85,7 +92,7 @@ private Row next() throws XMLStreamException { } int trackedColIndex = 0; - int rowIndex = getRowIndexWithFallback(++trackedRowIndex); + int rowIndex = getRowIndexWithFallback(trackedRowIndex); boolean isHidden = "1".equals(r.getAttribute("hidden")); List cells = new ArrayList<>(rowCapacity); @@ -98,11 +105,14 @@ private Row next() throws XMLStreamException { Cell cell = parseCell(trackedColIndex++); CellAddress addr = cell.getAddress(); + // we may have to adjust because we may have skipped blanks + trackedColIndex = addr.getColumn() + 1; ensureSize(cells, addr.getColumn() + 1); cells.set(addr.getColumn(), cell); physicalCellCount++; } + trackedRowIndex++; rowCapacity = Math.max(rowCapacity, cells.size()); return new Row(rowIndex, physicalCellCount, cells, isHidden); } @@ -112,7 +122,7 @@ private int getRowIndexWithFallback(int fallbackRowIndex) { return rowIndexOrNull != null ? rowIndexOrNull : fallbackRowIndex; } - private CellAddress getCellAddressWithFallback(int trackedColIndex) { + private CellAddress getCellAddressWithFallback(int trackedColIndex, int trackedRowIndex) { String cellRefOrNull = r.getAttribute("r"); return cellRefOrNull != null ? new CellAddress(cellRefOrNull) : @@ -120,7 +130,7 @@ private CellAddress getCellAddressWithFallback(int trackedColIndex) { } private Cell parseCell(int trackedColIndex) throws XMLStreamException { - CellAddress addr = getCellAddressWithFallback(trackedColIndex); + CellAddress addr = getCellAddressWithFallback(trackedColIndex, trackedRowIndex); String type = r.getOptionalAttribute("t").orElse("n"); String styleString = r.getAttribute("s"); String formatId = null; @@ -192,7 +202,7 @@ private Cell parseOther(CellAddress addr, String type, String dataFormatId, Stri if (formula == null && value == null && definedType == CellType.NUMBER) { return new Cell(workbook, CellType.EMPTY, null, addr, null, rawValue); } else { - CellType cellType = (formula != null) ? CellType.FORMULA : definedType; + CellType cellType = formula != null ? CellType.FORMULA : definedType; return new Cell(workbook, cellType, value, addr, formula, rawValue, dataFormatId, dataFormatString); } } @@ -209,7 +219,7 @@ private String parseSharedFormula(Integer si, CellAddress addr) { * @see here */ private String parseSharedFormula(Integer dCol, Integer dRow, String baseFormula) { - String res = ""; + StringBuilder res = new StringBuilder(); int start = 0; boolean stringLiteral = false; for (int end = 0; end < baseFormula.length(); end++) { @@ -222,7 +232,7 @@ private String parseSharedFormula(Integer dCol, Integer dRow, String baseFormula } if (c >= 'A' && c <= 'Z' || c == '$') { - res += baseFormula.substring(start, end); + res.append(baseFormula.substring(start, end)); start = end; end++; boolean foundNum = false; @@ -240,17 +250,17 @@ private String parseSharedFormula(Integer dCol, Integer dRow, String baseFormula } if (foundNum) { String cellID = baseFormula.substring(start, end); - res += shiftCell(cellID, dCol, dRow); + res.append(shiftCell(cellID, dCol, dRow)); start = end; } } } if (start < baseFormula.length()) { - res += baseFormula.substring(start); + res.append(baseFormula.substring(start)); } - return res; + return res.toString(); } /** diff --git a/fastexcel-reader/src/test/java/org/dhatim/fastexcel/reader/RowSpliteratorTest.java b/fastexcel-reader/src/test/java/org/dhatim/fastexcel/reader/RowSpliteratorTest.java new file mode 100644 index 0000000..dade7a0 --- /dev/null +++ b/fastexcel-reader/src/test/java/org/dhatim/fastexcel/reader/RowSpliteratorTest.java @@ -0,0 +1,28 @@ +package org.dhatim.fastexcel.reader; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.InputStream; + +import org.junit.jupiter.api.Test; + +public class RowSpliteratorTest { + + @Test + void testBlankCells() throws Exception { + InputStream is = Resources.open("/xml/blank_cells.xml"); + RowSpliterator it = new RowSpliterator(null, is); + it.tryAdvance(row -> { + assertEquals(8, row.getCellCount()); + Cell cell = row.getCell(7); + assertEquals("H1", cell.getAddress().toString()); + }); + it.tryAdvance(row -> { + assertEquals(8, row.getCellCount()); + Cell cell = row.getCell(7); + assertEquals("H2", cell.getAddress().toString()); + }); + } + +} + diff --git a/fastexcel-reader/src/test/resources/xml/blank_cells.xml b/fastexcel-reader/src/test/resources/xml/blank_cells.xml new file mode 100644 index 0000000..2148f5d --- /dev/null +++ b/fastexcel-reader/src/test/resources/xml/blank_cells.xml @@ -0,0 +1,48 @@ + + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + \ No newline at end of file