/* * ==================================================================== * 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.xssf.streaming; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.IOException; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.xssf.SXSSFITestDataProvider; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.Test; /** * Formula Evaluation with SXSSF. * * Note that SXSSF can only evaluate formulas where the * cell is in the current window, and all references * from the cell are in the current window */ public final class TestSXSSFFormulaEvaluation { public static final SXSSFITestDataProvider _testDataProvider = SXSSFITestDataProvider.instance; /** * EvaluateAll will normally fail, as any reference or * formula outside of the window will fail, and any * non-active sheets will fail */ @Test public void testEvaluateAllFails() throws IOException { SXSSFWorkbook wb = new SXSSFWorkbook(5); SXSSFSheet s = wb.createSheet(); FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); s.createRow(0).createCell(0).setCellFormula("1+2"); s.createRow(1).createCell(0).setCellFormula("A21"); for (int i=2; i<19; i++) { s.createRow(i); } // Cells outside window will fail, whether referenced or not s.createRow(19).createCell(0).setCellFormula("A1+A2"); s.createRow(20).createCell(0).setCellFormula("A1+A11+100"); try { eval.evaluateAll(); fail("Evaluate All shouldn't work, as some cells outside the window"); } catch(SXSSFFormulaEvaluator.RowFlushedException e) { // Expected } // Inactive sheets will fail XSSFWorkbook xwb = new XSSFWorkbook(); xwb.createSheet("Open"); xwb.createSheet("Closed"); wb.close(); wb = new SXSSFWorkbook(xwb, 5); s = wb.getSheet("Closed"); s.flushRows(); s = wb.getSheet("Open"); s.createRow(0).createCell(0).setCellFormula("1+2"); eval = wb.getCreationHelper().createFormulaEvaluator(); try { eval.evaluateAll(); fail("Evaluate All shouldn't work, as sheets flushed"); } catch (SXSSFFormulaEvaluator.SheetsFlushedException e) {} wb.close(); } @Test public void testEvaluateRefOutsideWindowFails() throws IOException { SXSSFWorkbook wb = new SXSSFWorkbook(5); SXSSFSheet s = wb.createSheet(); s.createRow(0).createCell(0).setCellFormula("1+2"); assertEquals(false, s.areAllRowsFlushed()); assertEquals(-1, s.getLastFlushedRowNum()); for (int i=1; i<=19; i++) { s.createRow(i); } Cell c = s.createRow(20).createCell(0); c.setCellFormula("A1+100"); assertEquals(false, s.areAllRowsFlushed()); assertEquals(15, s.getLastFlushedRowNum()); FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); try { eval.evaluateFormulaCellEnum(c); fail("Evaluate shouldn't work, as reference outside the window"); } catch(SXSSFFormulaEvaluator.RowFlushedException e) { // Expected } wb.close(); } /** * If all formula cells + their references are inside the window, * then evaluation works * @throws IOException */ @Test public void testEvaluateAllInWindow() throws IOException { SXSSFWorkbook wb = new SXSSFWorkbook(5); SXSSFSheet s = wb.createSheet(); s.createRow(0).createCell(0).setCellFormula("1+2"); s.createRow(1).createCell(1).setCellFormula("A1+10"); s.createRow(2).createCell(2).setCellFormula("B2+100"); FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); eval.evaluateAll(); assertEquals(3, (int)s.getRow(0).getCell(0).getNumericCellValue()); assertEquals(13, (int)s.getRow(1).getCell(1).getNumericCellValue()); assertEquals(113, (int)s.getRow(2).getCell(2).getNumericCellValue()); wb.close(); } @Test public void testEvaluateRefInsideWindow() throws IOException { SXSSFWorkbook wb = new SXSSFWorkbook(5); SXSSFSheet s = wb.createSheet(); FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); SXSSFCell c = s.createRow(0).createCell(0); c.setCellValue(1.5); c = s.createRow(1).createCell(0); c.setCellFormula("A1*2"); assertEquals(0, (int)c.getNumericCellValue()); eval.evaluateFormulaCellEnum(c); assertEquals(3, (int)c.getNumericCellValue()); wb.close(); } @Test public void testEvaluateSimple() throws IOException { SXSSFWorkbook wb = new SXSSFWorkbook(5); SXSSFSheet s = wb.createSheet(); FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator(); SXSSFCell c = s.createRow(0).createCell(0); c.setCellFormula("1+2"); assertEquals(0, (int)c.getNumericCellValue()); eval.evaluateFormulaCellEnum(c); assertEquals(3, (int)c.getNumericCellValue()); c = s.createRow(1).createCell(0); c.setCellFormula("CONCATENATE(\"hello\",\" \",\"world\")"); eval.evaluateFormulaCellEnum(c); assertEquals("hello world", c.getStringCellValue()); wb.close(); } }