Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed StreamingRow.getLastCellNum() #61

Merged
merged 3 commits into from
Nov 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 51 additions & 15 deletions src/main/java/com/monitorjbl/xlsx/impl/StreamingCell.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ public class StreamingCell implements Cell {

private Object contents;
private Object rawContents;
private String formula;
private String numericFormat;
private Short numericFormatIndex;
private String type;
private String cachedFormulaResultType;
private Row row;
private CellStyle cellStyle;

Expand Down Expand Up @@ -68,11 +70,19 @@ public void setNumericFormatIndex(Short numericFormatIndex) {
this.numericFormatIndex = numericFormatIndex;
}

public void setFormula(String formula) {
this.formula = formula;
}

public String getType() {
return type;
}

public void setType(String type) {
if("str".equals(type)) {
// this is a formula cell, cache the value's type
cachedFormulaResultType = this.type;
}
this.type = type;
}

Expand Down Expand Up @@ -237,30 +247,64 @@ public CellStyle getCellStyle() {
return this.cellStyle;
}


/* Not supported */
/**
* Return a formula for the cell, for example, <code>SUM(C4:E4)</code>
*
* @return a formula for the cell
* @throws IllegalStateException if the cell type returned by {@link #getCellType()} is not CELL_TYPE_FORMULA
*/
@Override
public String getCellFormula() {
if (type == null || !"str".equals(type))
throw new IllegalStateException("This cell does not have a formula");
return formula;
}

/**
* Not supported
* Only valid for formula cells
* @return one of ({@link #CELL_TYPE_NUMERIC}, {@link #CELL_TYPE_STRING},
* {@link #CELL_TYPE_BOOLEAN}, {@link #CELL_TYPE_ERROR}) depending
* on the cached value of the formula
*/
@Override
public void setCellType(int cellType) {
throw new NotSupportedException();
public int getCachedFormulaResultType() {
if (type != null && "str".equals(type)) {
if(contents == null || cachedFormulaResultType == null) {
return CELL_TYPE_BLANK;
} else if("n".equals(cachedFormulaResultType)) {
return CELL_TYPE_NUMERIC;
} else if("s".equals(cachedFormulaResultType) || "inlineStr".equals(cachedFormulaResultType)) {
return CELL_TYPE_STRING;
} else if("str".equals(cachedFormulaResultType)) {
return CELL_TYPE_FORMULA;
} else if("b".equals(cachedFormulaResultType)) {
return CELL_TYPE_BOOLEAN;
} else if("e".equals(cachedFormulaResultType)) {
return CELL_TYPE_ERROR;
} else {
throw new UnsupportedOperationException("Unsupported cell type '" + cachedFormulaResultType + "'");
}
}
else {
throw new IllegalStateException("Only formula cells have cached results");
}
}

/* Not supported */

/**
* Not supported
*/
@Override
public Sheet getSheet() {
public void setCellType(int cellType) {
throw new NotSupportedException();
}

/**
* Not supported
*/
@Override
public int getCachedFormulaResultType() {
public Sheet getSheet() {
throw new NotSupportedException();
}

Expand Down Expand Up @@ -312,14 +356,6 @@ public void setCellFormula(String formula) throws FormulaParseException {
throw new NotSupportedException();
}

/**
* Not supported
*/
@Override
public String getCellFormula() {
throw new NotSupportedException();
}

/**
* Not supported
*/
Expand Down
25 changes: 14 additions & 11 deletions src/main/java/com/monitorjbl/xlsx/impl/StreamingRow.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
public class StreamingRow implements Row {
private int rowIndex;
private boolean isHidden;
private Map<Integer, Cell> cellMap = new TreeMap<>();
private TreeMap<Integer, Cell> cellMap = new TreeMap<>();

public StreamingRow(int rowIndex, boolean isHidden) {
this.rowIndex = rowIndex;
Expand All @@ -24,7 +24,7 @@ public Map<Integer, Cell> getCellMap() {
return cellMap;
}

public void setCellMap(Map<Integer, Cell> cellMap) {
public void setCellMap(TreeMap<Integer, Cell> cellMap) {
this.cellMap = cellMap;
}

Expand Down Expand Up @@ -76,7 +76,7 @@ public Cell getCell(int cellnum) {
*/
@Override
public short getLastCellNum() {
return (short) (cellMap.size() == 0 ? -1 : cellMap.size() + 1);
return (short) (cellMap.size() == 0 ? -1 : cellMap.lastEntry().getValue().getColumnIndex() + 1);
}

/**
Expand All @@ -89,6 +89,17 @@ public boolean getZeroHeight() {
return isHidden;
}

/**
* Gets the number of defined cells (NOT number of cells in the actual row!).
* That is to say if only columns 0,4,5 have values then there would be 3.
*
* @return int representing the number of defined cells in the row.
*/
@Override
public int getPhysicalNumberOfCells() {
return cellMap.size();
}

/* Not supported */

/**
Expand Down Expand Up @@ -139,14 +150,6 @@ public short getFirstCellNum() {
throw new NotSupportedException();
}

/**
* Not supported
*/
@Override
public int getPhysicalNumberOfCells() {
throw new NotSupportedException();
}

/**
* Not supported
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ private void handleEvent(XMLEvent event) throws SAXException {
}
}
}
} else if ("f".equals(tagLocalName)) {
currentCell.setType("str");
}

// Clear contents cache
Expand All @@ -161,6 +163,8 @@ private void handleEvent(XMLEvent event) throws SAXException {
rowCache.add(currentRow);
} else if("c".equals(tagLocalName)) {
currentRow.getCellMap().put(currentCell.getColumnIndex(), currentCell);
} else if("f".equals(tagLocalName)) {
currentCell.setFormula(lastContents);
}

}
Expand Down
25 changes: 25 additions & 0 deletions src/test/java/com/monitorjbl/xlsx/StreamingWorkbookTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.monitorjbl.xlsx;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
Expand All @@ -9,8 +10,11 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Locale;

import static org.apache.poi.ss.usermodel.Cell.CELL_TYPE_FORMULA;
import static org.apache.poi.ss.usermodel.Cell.CELL_TYPE_NUMERIC;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
Expand Down Expand Up @@ -61,4 +65,25 @@ public void testHiddenCells() throws Exception {
assertFalse("Row 2 should not be hidden", sheet.rowIterator().next().getZeroHeight());
}
}

@Test
public void testFormulaCells() throws Exception {
try(
InputStream is = new FileInputStream(new File("src/test/resources/formula_cell.xlsx"));
Workbook workbook = StreamingReader.builder().open(is)
) {
assertEquals(1, workbook.getNumberOfSheets());
Sheet sheet = workbook.getSheetAt(0);

Iterator<Row> rowIterator = sheet.rowIterator();
rowIterator.next();
rowIterator.next();
Row row3 = rowIterator.next();
Cell A3 = row3.getCell(0);

assertEquals("Cell A3 should be of type formula", CELL_TYPE_FORMULA, A3.getCellType());
assertEquals("Cell A3's value should be of type numeric", CELL_TYPE_NUMERIC, A3.getCachedFormulaResultType());
assertEquals("Wrong formula", "SUM(A1:A2)", A3.getCellFormula());
}
}
}
Binary file added src/test/resources/formula_cell.xlsx
Binary file not shown.