Ver código fonte

[bug-63934] Fix parsing of structure references. Thanks to Matthias Raschhofer. This closes #514

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1912263 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_5_2_4
PJ Fanning 8 meses atrás
pai
commit
ca681fd706

+ 18
- 0
poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFFormulaEvaluation.java Ver arquivo

import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;


import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import org.apache.poi.ss.usermodel.BaseTestFormulaEvaluator; import org.apache.poi.ss.usermodel.BaseTestFormulaEvaluator;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue; import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
assertEquals("another value", value.getStringCellValue(), "wrong value A5"); assertEquals("another value", value.getStringCellValue(), "wrong value A5");
} }
} }

@Test
void testBug63934() throws IOException {
try (Workbook wb = XSSFTestDataSamples.openSampleWorkbook("63934.xlsx")) {

final Cell cell = wb.getSheetAt(0).getRow(1).getCell(1);
assertNotNull(cell);

final FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
final CellValue value = evaluator.evaluate(cell);
assertEquals("Male", value.getStringValue());
}
}
} }

+ 9
- 1
poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java Ver arquivo

16 Table1[[#Headers],[#Data],[col2]] 16 Table1[[#Headers],[#Data],[col2]]
17 Table1[[#This Row], [col1]] 17 Table1[[#This Row], [col1]]
18 Table1[ [col1]:[col2] ] 18 Table1[ [col1]:[col2] ]
19 Table1[]
*/ */


final String tbl = "\\_Prime.1"; final String tbl = "\\_Prime.1";
assertEquals(1, ptgs.length); assertEquals(1, ptgs.length);
assertEquals("Table!A1:C7", ptgs[0].toFormulaString(), "Table1[#All]"); assertEquals("Table!A1:C7", ptgs[0].toFormulaString(), "Table1[#All]");


////// Case 5: Evaluate "Table1[#Data]" (excludes Header and Data rows) ////////
////// Case 5: Evaluate "Table1[#Data]" (excludes Header and Total rows) ////////
ptgs = parse(fpb, tbl+"[#Data]"); ptgs = parse(fpb, tbl+"[#Data]");
assertEquals(1, ptgs.length); assertEquals(1, ptgs.length);
assertEquals("Table!A2:C7", ptgs[0].toFormulaString(), "Table1[#Data]"); assertEquals("Table!A2:C7", ptgs[0].toFormulaString(), "Table1[#Data]");
assertEquals(1, ptgs.length); assertEquals(1, ptgs.length);
assertEquals("Table!B2:C7", ptgs[0].toFormulaString(), "Table1[[col]:[col2]]"); assertEquals("Table!B2:C7", ptgs[0].toFormulaString(), "Table1[[col]:[col2]]");


////// Case 19: Evaluate "Table1[]" ////////
// Excludes Header and Total rows, equivalent to Table1[#Data] (see case 5).
// This is the only case where [] is allowed.
ptgs = parse(fpb, tbl+"[]");
assertEquals(1, ptgs.length);
assertEquals("Table!A2:C7", ptgs[0].toFormulaString(), "Table1[]");

wb.close(); wb.close();
} }
} }

+ 24
- 0
poi/src/main/java/org/apache/poi/ss/formula/FormulaParser.java Ver arquivo

* Parses a structured reference, returns it as area reference. * Parses a structured reference, returns it as area reference.
* Examples: * Examples:
* <pre> * <pre>
* Table1[]
* Table1[col] * Table1[col]
* Table1[[#Totals],[col]] * Table1[[#Totals],[col]]
* Table1[#Totals] * Table1[#Totals]
int savePtr0 = _pointer; int savePtr0 = _pointer;
nextChar(); nextChar();


// Special case: Table1[] is equivalent to Table1[#Data]
if (look == ']') {

// Consume the ']' character
nextChar();

// Skip header and total rows if available
int actualStartRow = startRow;
if (tbl.getHeaderRowCount() > 0) {
actualStartRow = startRow + 1;
}
int actualEndRow = endRow;
if (tbl.getTotalsRowCount() > 0) {
actualEndRow = endRow - 1;
}

final CellReference topLeft = new CellReference(actualStartRow, startCol);
final CellReference bottomRight = new CellReference(actualEndRow, endCol);
final SheetIdentifier sheetIden = new SheetIdentifier( null, new NameIdentifier(sheetName, true));
final Ptg ptg = _book.get3DReferencePtg(new AreaReference(topLeft, bottomRight, _ssVersion), sheetIden);
return new ParseNode(ptg);
}

boolean isTotalsSpec = false; boolean isTotalsSpec = false;
boolean isThisRowSpec = false; boolean isThisRowSpec = false;
boolean isDataSpec = false; boolean isDataSpec = false;

BIN
test-data/spreadsheet/63934.xlsx Ver arquivo


Carregando…
Cancelar
Salvar