Skip to content

Commit 823fc85

Browse files
authored
rewrite shared formula shifting code (#253)
* rewrite shared formula shifting code * add test
1 parent c8842e0 commit 823fc85

File tree

3 files changed

+59
-8
lines changed

3 files changed

+59
-8
lines changed

src/main/java/com/github/pjfanning/xlsx/impl/StreamingRowIterator.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import org.apache.poi.ss.SpreadsheetVersion;
1414
import org.apache.poi.ss.formula.FormulaParser;
1515
import org.apache.poi.ss.formula.FormulaRenderer;
16-
import org.apache.poi.ss.formula.FormulaShifter;
1716
import org.apache.poi.ss.formula.FormulaType;
1817
import org.apache.poi.ss.formula.ptg.Ptg;
1918
import org.apache.poi.ss.usermodel.*;
@@ -356,25 +355,27 @@ && isSpreadsheetTag(event.asEndElement().getName())) {
356355
if (sf == null) {
357356
LOG.warn("No SharedFormula found for si={}", formulaSI);
358357
} else {
359-
CurrentRowEvaluationWorkbook evaluationWorkbook =
358+
final CurrentRowEvaluationWorkbook evaluationWorkbook =
360359
new CurrentRowEvaluationWorkbook(wb, currentRow);
361360
int sheetIndex = wb.getSheetIndex(sheet);
362361
if (sheetIndex < 0) {
363362
LOG.warn("Failed to find correct sheet index; defaulting to zero");
364363
sheetIndex = 0;
365364
}
366365
try {
367-
Ptg[] ptgs = FormulaParser.parse(sf.getFormula(), evaluationWorkbook, FormulaType.CELL, sheetIndex, currentRow.getRowNum());
366+
Ptg[] ptgs = FormulaParser.parse(
367+
sf.getFormula(), evaluationWorkbook, FormulaType.CELL, sheetIndex, currentRow.getRowNum());
368368
final int rowsToMove = currentRowNum - sf.getCellAddress().getRow();
369-
FormulaShifter formulaShifter = FormulaShifter.createForRowShift(sheetIndex, sheet.getSheetName(),
370-
0, SpreadsheetVersion.EXCEL2007.getLastRowIndex(), rowsToMove, SpreadsheetVersion.EXCEL2007);
371-
formulaShifter.adjustFormula(ptgs, sheetIndex);
369+
final int colsToMove = currentColNum - sf.getCellAddress().getColumn();
370+
org.apache.poi.ss.formula.SharedFormula formulaShifter = new org.apache.poi.ss.formula.SharedFormula(
371+
SpreadsheetVersion.EXCEL2007);
372+
ptgs = formulaShifter.convertSharedFormulas(ptgs, rowsToMove, colsToMove);
372373
// There are some corner cases regarding formulas in this PR
373374
// https://github.com/pjfanning/excel-streaming-reader/issues/151
374375
String shiftedFmla = FormulaRenderer.toFormulaString(evaluationWorkbook, ptgs);
375376

376-
LOG.debug("cell {} should have formula {} based on shared formula {} (rowsToMove={})",
377-
currentCell.getAddress(), shiftedFmla, sf.getFormula(), rowsToMove);
377+
LOG.debug("cell {} should have formula {} based on shared formula {} (rowsToMove={} colsToMove={})",
378+
currentCell.getAddress(), shiftedFmla, sf.getFormula(), rowsToMove, colsToMove);
378379
currentCell.setFormula(shiftedFmla);
379380
} catch (Exception e) {
380381
LOG.warn("cell {} has a shared formula but excel-streaming-reader has an issue parsing it - will ignore the formula",

src/test/java/com/github/pjfanning/xlsx/StreamingReaderTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,56 @@ public void testReadSharedFormulasEnabled() throws Exception {
12141214
}
12151215
}
12161216

1217+
@Test
1218+
public void testReadSharedFormulasIssue252() throws Exception {
1219+
// https://github.com/pjfanning/excel-streaming-reader/issues/252
1220+
try (
1221+
InputStream inputStream = new FileInputStream("src/test/resources/SharedFormula252.xlsx");
1222+
Workbook wb = StreamingReader.builder()
1223+
.setReadSharedFormulas(true)
1224+
.open(inputStream)
1225+
) {
1226+
Sheet sheet = wb.getSheetAt(0);
1227+
Cell b11 = null;
1228+
Cell c11 = null;
1229+
Cell d11 = null;
1230+
Cell b23 = null;
1231+
Cell c23 = null;
1232+
Cell d23 = null;
1233+
for (Row row : sheet) {
1234+
if (row.getRowNum() == 10) {
1235+
b11 = row.getCell(1);
1236+
c11 = row.getCell(2);
1237+
d11 = row.getCell(3);
1238+
} else if (row.getRowNum() == 22) {
1239+
b23 = row.getCell(1);
1240+
c23 = row.getCell(2);
1241+
d23 = row.getCell(3);
1242+
}
1243+
}
1244+
assertNotNull("b11 found", b11);
1245+
assertNotNull("c11 found", c11);
1246+
assertNotNull("d11 found", d11);
1247+
assertNotNull("b23 found", b23);
1248+
assertNotNull("c23 found", c23);
1249+
assertNotNull("d23 found", d23);
1250+
assertEquals("SUM(B12:B20)", b11.getCellFormula());
1251+
assertEquals("SUM(C12:C20)", c11.getCellFormula());
1252+
assertEquals("SUM(D12:D20)", d11.getCellFormula());
1253+
assertEquals("B22+B11+B5+B21", b23.getCellFormula());
1254+
assertEquals("C22+C11+C5+C21", c23.getCellFormula());
1255+
assertEquals("D22+D11+D5+D21", d23.getCellFormula());
1256+
StreamingSheet ss = (StreamingSheet)sheet;
1257+
Map<String, SharedFormula> sharedFormulaMap = ss.getSharedFormulaMap();
1258+
assertEquals(2, sharedFormulaMap.size());
1259+
assertEquals("SUM(A12:A20)", sharedFormulaMap.get("0").getFormula());
1260+
assertEquals("A11", sharedFormulaMap.get("0").getCellAddress().formatAsString());
1261+
assertEquals("A22+A11+A5+A21", sharedFormulaMap.get("1").getFormula());
1262+
assertEquals("A23", sharedFormulaMap.get("1").getCellAddress().formatAsString());
1263+
}
1264+
}
1265+
1266+
12171267
@Test
12181268
public void testReadSharedFormulasSimple() throws Exception {
12191269
try (
9.18 KB
Binary file not shown.

0 commit comments

Comments
 (0)