123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You 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.apache.poi.ss.formula;
-
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertFalse;
- import static org.junit.Assert.assertTrue;
- import static org.junit.Assert.fail;
-
- import org.apache.poi.ss.usermodel.Cell;
- import org.apache.poi.ss.usermodel.CellType;
- import org.apache.poi.ss.usermodel.CellValue;
- import org.apache.poi.ss.usermodel.FormulaEvaluator;
- import org.apache.poi.ss.usermodel.Row;
- import org.apache.poi.ss.usermodel.Table;
- import org.apache.poi.ss.util.AreaReference;
- import org.apache.poi.ss.util.CellReference;
- import org.apache.poi.xssf.XSSFTestDataSamples;
- import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
- import org.apache.poi.xssf.usermodel.XSSFSheet;
- import org.apache.poi.xssf.usermodel.XSSFTable;
- import org.apache.poi.xssf.usermodel.XSSFWorkbook;
- import org.junit.Test;
-
- /**
- * Tests Excel Table expressions (structured references)
- * @see <a href="https://support.office.com/en-us/article/Using-structured-references-with-Excel-tables-F5ED2452-2337-4F71-BED3-C8AE6D2B276E">
- * Excel Structured Reference Syntax
- * </a>
- */
- public class TestStructuredReferences {
-
- /**
- * Test the regular expression used in INDIRECT() evaluation to recognize structured references
- */
- @Test
- public void testTableExpressionSyntax() {
- assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("abc[col1]").matches());
- assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("_abc[col1]").matches());
- assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("_[col1]").matches());
- assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("\\[col1]").matches());
- assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("\\[col1]").matches());
- assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("\\[#This Row]").matches());
- assertTrue("Valid structured reference syntax didn't match expression", Table.isStructuredReference.matcher("\\[ [col1], [col2] ]").matches());
-
- // can't have a space between the table name and open bracket
- assertFalse("Invalid structured reference syntax didn't fail expression", Table.isStructuredReference.matcher("\\abc [ [col1], [col2] ]").matches());
- }
-
- @Test
- public void testTableFormulas() throws Exception {
- XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("StructuredReferences.xlsx");
- try {
-
- final FormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
- final XSSFSheet tableSheet = wb.getSheet("Table");
- final XSSFSheet formulaSheet = wb.getSheet("Formulas");
-
- confirm(eval, tableSheet.getRow(5).getCell(0), 49);
- confirm(eval, formulaSheet.getRow(0).getCell(0), 209);
- confirm(eval, formulaSheet.getRow(1).getCell(0), "one");
-
- // test changing a table value, to see if the caches are properly cleared
- // Issue 59814
-
- // this test passes before the fix for 59814
- tableSheet.getRow(1).getCell(1).setCellValue("ONEA");
- confirm(eval, formulaSheet.getRow(1).getCell(0), "ONEA");
-
- // test adding a row to a table, issue 59814
- Row newRow = tableSheet.getRow(7);
- if (newRow == null) newRow = tableSheet.createRow(7);
- newRow.createCell(0, CellType.FORMULA).setCellFormula("\\_Prime.1[[#This Row],[@Number]]*\\_Prime.1[[#This Row],[@Number]]");
- newRow.createCell(1, CellType.STRING).setCellValue("thirteen");
- newRow.createCell(2, CellType.NUMERIC).setCellValue(13);
-
- // update Table
- final XSSFTable table = wb.getTable("\\_Prime.1");
- final AreaReference newArea = new AreaReference(table.getStartCellReference(), new CellReference(table.getEndRowIndex() + 1, table.getEndColIndex()));
- String newAreaStr = newArea.formatAsString();
- table.getCTTable().setRef(newAreaStr);
- table.getCTTable().getAutoFilter().setRef(newAreaStr);
- table.updateHeaders();
- table.updateReferences();
-
- // these fail before the fix for 59814
- confirm(eval, tableSheet.getRow(7).getCell(0), 13*13);
- confirm(eval, formulaSheet.getRow(0).getCell(0), 209 + 13*13);
-
- } finally {
- wb.close();
- }
- }
-
- private static void confirm(FormulaEvaluator fe, Cell cell, double expectedResult) {
- fe.clearAllCachedResultValues();
- CellValue cv = fe.evaluate(cell);
- if (cv.getCellTypeEnum() != CellType.NUMERIC) {
- fail("expected numeric cell type but got " + cv.formatAsString());
- }
- assertEquals(expectedResult, cv.getNumberValue(), 0.0);
- }
-
- private static void confirm(FormulaEvaluator fe, Cell cell, String expectedResult) {
- fe.clearAllCachedResultValues();
- CellValue cv = fe.evaluate(cell);
- if (cv.getCellTypeEnum() != CellType.STRING) {
- fail("expected String cell type but got " + cv.formatAsString());
- }
- assertEquals(expectedResult, cv.getStringValue());
- }
- }
|