Fix bug #56502 - When shifting XSSF rows with formula cells, if the formula can't be parsed, log + leave it unchanged rather than failing
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1614916 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5f5d8f496e
commit
4bfe3c6784
@ -20,6 +20,7 @@ package org.apache.poi.xssf.usermodel.helpers;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.formula.FormulaParseException;
|
||||||
import org.apache.poi.ss.formula.FormulaParser;
|
import org.apache.poi.ss.formula.FormulaParser;
|
||||||
import org.apache.poi.ss.formula.FormulaRenderer;
|
import org.apache.poi.ss.formula.FormulaRenderer;
|
||||||
import org.apache.poi.ss.formula.FormulaShifter;
|
import org.apache.poi.ss.formula.FormulaShifter;
|
||||||
@ -30,6 +31,8 @@ import org.apache.poi.ss.formula.ptg.Ptg;
|
|||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.util.CellRangeAddress;
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFName;
|
import org.apache.poi.xssf.usermodel.XSSFName;
|
||||||
@ -43,9 +46,10 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatti
|
|||||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Yegor Kozlov
|
* Helper for shifting rows up or down
|
||||||
*/
|
*/
|
||||||
public final class XSSFRowShifter {
|
public final class XSSFRowShifter {
|
||||||
|
private static POILogger logger = POILogFactory.getLogger(XSSFRowShifter.class);
|
||||||
private final XSSFSheet sheet;
|
private final XSSFSheet sheet;
|
||||||
|
|
||||||
public XSSFRowShifter(XSSFSheet sh) {
|
public XSSFRowShifter(XSSFSheet sh) {
|
||||||
@ -194,12 +198,19 @@ public final class XSSFRowShifter {
|
|||||||
XSSFWorkbook wb = sheet.getWorkbook();
|
XSSFWorkbook wb = sheet.getWorkbook();
|
||||||
int sheetIndex = wb.getSheetIndex(sheet);
|
int sheetIndex = wb.getSheetIndex(sheet);
|
||||||
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
|
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
|
||||||
Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex);
|
|
||||||
String shiftedFmla = null;
|
try {
|
||||||
if (shifter.adjustFormula(ptgs, sheetIndex)) {
|
Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex);
|
||||||
shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
|
String shiftedFmla = null;
|
||||||
|
if (shifter.adjustFormula(ptgs, sheetIndex)) {
|
||||||
|
shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
|
||||||
|
}
|
||||||
|
return shiftedFmla;
|
||||||
|
} catch (FormulaParseException fpe) {
|
||||||
|
// Log, but don't change, rather than breaking
|
||||||
|
logger.log(POILogger.WARN, "Error shifting formula on row ", row.getRowNum(), fpe);
|
||||||
|
return formula;
|
||||||
}
|
}
|
||||||
return shiftedFmla;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateConditionalFormatting(FormulaShifter shifter) {
|
public void updateConditionalFormatting(FormulaShifter shifter) {
|
||||||
|
@ -1787,6 +1787,10 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
|
|||||||
checkValue(excel, eval.getStringValue() + ".0");
|
checkValue(excel, eval.getStringValue() + ".0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New hyperlink with no initial cell reference, still need
|
||||||
|
* to be able to change it
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testBug56527() {
|
public void testBug56527() {
|
||||||
XSSFWorkbook wb = new XSSFWorkbook();
|
XSSFWorkbook wb = new XSSFWorkbook();
|
||||||
@ -1816,6 +1820,30 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
|
|||||||
assertEquals(5, hyperlink.getLastRow());
|
assertEquals(5, hyperlink.getLastRow());
|
||||||
assertEquals(3, hyperlink.getLastColumn());
|
assertEquals(3, hyperlink.getLastColumn());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shifting rows with a formula that references a
|
||||||
|
* function in another file
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void bug56502() throws Exception {
|
||||||
|
Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56502.xlsx");
|
||||||
|
Sheet sheet = wb.getSheetAt(0);
|
||||||
|
|
||||||
|
Cell cFunc = sheet.getRow(3).getCell(0);
|
||||||
|
assertEquals("[1]!LUCANET(\"Ist\")", cFunc.getCellFormula());
|
||||||
|
Cell cRef = sheet.getRow(3).createCell(1);
|
||||||
|
cRef.setCellFormula("A3");
|
||||||
|
|
||||||
|
// Shift it down one row
|
||||||
|
sheet.shiftRows(1, sheet.getLastRowNum(), 1);
|
||||||
|
|
||||||
|
// Check the new formulas: Function won't change, Reference will
|
||||||
|
cFunc = sheet.getRow(4).getCell(0);
|
||||||
|
assertEquals("[1]!LUCANET(\"Ist\")", cFunc.getCellFormula());
|
||||||
|
cRef = sheet.getRow(4).getCell(1);
|
||||||
|
assertEquals("A4", cRef.getCellFormula());
|
||||||
|
}
|
||||||
|
|
||||||
private void checkValue(XSSFWorkbook excel, String expect) {
|
private void checkValue(XSSFWorkbook excel, String expect) {
|
||||||
XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(excel);
|
XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(excel);
|
||||||
|
BIN
test-data/spreadsheet/56502.xlsx
Normal file
BIN
test-data/spreadsheet/56502.xlsx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user