[bug-65464] fix issue where shared formulas can be corrupted

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1891849 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2021-07-28 09:36:37 +00:00
parent 1603235a46
commit 3aa03459a7
3 changed files with 36 additions and 18 deletions

View File

@ -4619,18 +4619,21 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
DONE:
for(int i = cell.getRowIndex(); i <= ref.getLastRow(); i++){
XSSFRow row = getRow(i);
if(row != null) for(int j = cell.getColumnIndex(); j <= ref.getLastColumn(); j++){
XSSFCell nextCell = row.getCell(j);
if(nextCell != null && nextCell != cell && nextCell.getCellType() == CellType.FORMULA){
CTCellFormula nextF = nextCell.getCTCell().getF();
nextF.setStringValue(nextCell.getCellFormula(evalWb));
CellRangeAddress nextRef = new CellRangeAddress(
nextCell.getRowIndex(), ref.getLastRow(),
nextCell.getColumnIndex(), ref.getLastColumn());
nextF.setRef(nextRef.formatAsString());
if(row != null) {
for(int j = cell.getColumnIndex(); j <= ref.getLastColumn(); j++){
XSSFCell nextCell = row.getCell(j);
if(nextCell != null && nextCell != cell && nextCell.getCellType() == CellType.FORMULA) {
CTCellFormula nextF = nextCell.getCTCell().getF();
nextF.setStringValue(nextCell.getCellFormula(evalWb));
nextF.setT(STCellFormulaType.SHARED); //https://bz.apache.org/bugzilla/show_bug.cgi?id=65464
CellRangeAddress nextRef = new CellRangeAddress(
nextCell.getRowIndex(), ref.getLastRow(),
nextCell.getColumnIndex(), ref.getLastColumn());
nextF.setRef(nextRef.formatAsString());
sharedFormulas.put(Math.toIntExact(nextF.getSi()), nextF);
break DONE;
sharedFormulas.put(Math.toIntExact(nextF.getSi()), nextF);
break DONE;
}
}
}
}

View File

@ -117,13 +117,7 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedNames;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTFontImpl;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;
@ -3544,4 +3538,25 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
assertEquals(HorizontalAlignment.LEFT, cellLeft.getCellStyle().getAlignment());
}
}
@Test
void test65464() throws IOException {
try (XSSFWorkbook wb = openSampleWorkbook("bug65464.xlsx")) {
XSSFSheet sheet = wb.getSheet("SheetWithSharedFormula");
XSSFCell v15 = sheet.getRow(14).getCell(21);
XSSFCell v16 = sheet.getRow(15).getCell(21);
assertEquals("U15/R15", v15.getCellFormula());
assertEquals(STCellFormulaType.SHARED, v15.getCTCell().getF().getT());
assertEquals("U16/R16", v16.getCellFormula());
assertEquals(STCellFormulaType.NORMAL, v16.getCTCell().getF().getT()); //anomaly in original file
int calcChainSize = wb.getCalculationChain().getCTCalcChain().sizeOfCArray();
v15.removeFormula();
assertEquals(CellType.NUMERIC, v15.getCellType(), "V15 is no longer a function");
assertNull(v15.getCTCell().getF(), "V15 xmlbeans function removed");
assertEquals("U16/R16", v16.getCellFormula());
assertEquals(STCellFormulaType.SHARED, v16.getCTCell().getF().getT());
assertEquals(calcChainSize - 1, wb.getCalculationChain().getCTCalcChain().sizeOfCArray());
}
}
}

Binary file not shown.