diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java index da65972ed..1b5156886 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java @@ -20,6 +20,7 @@ package org.apache.poi.xssf.usermodel.helpers; import java.util.ArrayList; import java.util.List; +import org.apache.poi.ss.formula.FormulaParseException; import org.apache.poi.ss.formula.FormulaParser; import org.apache.poi.ss.formula.FormulaRenderer; 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.Row; 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.XSSFEvaluationWorkbook; 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; /** - * @author Yegor Kozlov + * Helper for shifting rows up or down */ public final class XSSFRowShifter { + private static POILogger logger = POILogFactory.getLogger(XSSFRowShifter.class); private final XSSFSheet sheet; public XSSFRowShifter(XSSFSheet sh) { @@ -194,12 +198,19 @@ public final class XSSFRowShifter { XSSFWorkbook wb = sheet.getWorkbook(); int sheetIndex = wb.getSheetIndex(sheet); XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb); - Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex); - String shiftedFmla = null; - if (shifter.adjustFormula(ptgs, sheetIndex)) { - shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs); + + try { + Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex); + 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) { diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index 162ee4aad..f33b34591 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -1787,6 +1787,10 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { checkValue(excel, eval.getStringValue() + ".0"); } + /** + * New hyperlink with no initial cell reference, still need + * to be able to change it + */ @Test public void testBug56527() { XSSFWorkbook wb = new XSSFWorkbook(); @@ -1816,6 +1820,30 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertEquals(5, hyperlink.getLastRow()); 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) { XSSFFormulaEvaluator evaluator = new XSSFFormulaEvaluator(excel); diff --git a/test-data/spreadsheet/56502.xlsx b/test-data/spreadsheet/56502.xlsx new file mode 100644 index 000000000..72bd17333 Binary files /dev/null and b/test-data/spreadsheet/56502.xlsx differ