mirror of https://github.com/apache/poi.git
Bug 64460: Fix invalid moving of merged regions
Also fix and enable two tests ignored previously git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1883037 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1bd3ddaa75
commit
232d734941
|
@ -103,7 +103,6 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
|
||||||
* contain text, numbers, dates, and formulas. Cells can also be formatted.
|
* contain text, numbers, dates, and formulas. Cells can also be formatted.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
||||||
private static final POILogger logger = POILogFactory.getLogger(XSSFSheet.class);
|
private static final POILogger logger = POILogFactory.getLogger(XSSFSheet.class);
|
||||||
|
|
||||||
|
@ -136,7 +135,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
||||||
private Map<Integer, CTCellFormula> sharedFormulas;
|
private Map<Integer, CTCellFormula> sharedFormulas;
|
||||||
private SortedMap<String,XSSFTable> tables;
|
private SortedMap<String,XSSFTable> tables;
|
||||||
private List<CellRangeAddress> arrayFormulas;
|
private List<CellRangeAddress> arrayFormulas;
|
||||||
private XSSFDataValidationHelper dataValidationHelper;
|
private final XSSFDataValidationHelper dataValidationHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new XSSFSheet - called by XSSFWorkbook to create a sheet from scratch.
|
* Creates new XSSFSheet - called by XSSFWorkbook to create a sheet from scratch.
|
||||||
|
@ -3027,7 +3026,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
||||||
FormulaShifter formulaShifter = FormulaShifter.createForColumnShift(this.getWorkbook().getSheetIndex(this), this.getSheetName(), startColumn, endColumn, n, SpreadsheetVersion.EXCEL2007);
|
FormulaShifter formulaShifter = FormulaShifter.createForColumnShift(this.getWorkbook().getSheetIndex(this), this.getSheetName(), startColumn, endColumn, n, SpreadsheetVersion.EXCEL2007);
|
||||||
XSSFColumnShifter columnShifter = new XSSFColumnShifter(this);
|
XSSFColumnShifter columnShifter = new XSSFColumnShifter(this);
|
||||||
columnShifter.shiftColumns(startColumn, endColumn, n);
|
columnShifter.shiftColumns(startColumn, endColumn, n);
|
||||||
columnShifter.shiftMergedRegions(startColumn, startColumn, n);
|
columnShifter.shiftMergedRegions(startColumn, endColumn, n);
|
||||||
columnShifter.updateFormulas(formulaShifter);
|
columnShifter.updateFormulas(formulaShifter);
|
||||||
columnShifter.updateConditionalFormatting(formulaShifter);
|
columnShifter.updateConditionalFormatting(formulaShifter);
|
||||||
columnShifter.updateHyperlinks(formulaShifter);
|
columnShifter.updateHyperlinks(formulaShifter);
|
||||||
|
|
|
@ -22,7 +22,6 @@ import org.apache.poi.ss.util.CellAddress;
|
||||||
import org.apache.poi.ss.util.CellRangeAddress;
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
|
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
|
||||||
|
|
||||||
|
@ -33,23 +32,28 @@ import java.io.OutputStream;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class TestXSSFSheetShiftRowsAndColumns {
|
public class TestXSSFSheetShiftRowsAndColumns {
|
||||||
final File resultDir=new File("build/custom-reports-test");
|
private static final File resultDir = new File("build/custom-reports-test");
|
||||||
XSSFWorkbook workbook=null;
|
|
||||||
XSSFSheet sheet=null;
|
private static final int numRows = 4;
|
||||||
String fileName=null;
|
private static final int numCols = 4;
|
||||||
final int numRows=4;
|
|
||||||
final int numCols=4;
|
private static final int INSERT_ROW = 1;
|
||||||
final int INSERT_ROW=1;
|
private static final int INSERT_COLUMN = 1;
|
||||||
final int INSERT_COLUMN=1;
|
private static final int FIRST_MERGE_ROW = INSERT_ROW+1;
|
||||||
final int FIRST_MERGE_ROW=INSERT_ROW+1;
|
private static final int LAST_MERGE_ROW = numRows-1;
|
||||||
final int LAST_MERGE_ROW=numRows-1;
|
private static final int FIRST_MERGE_COL = INSERT_COLUMN+1;
|
||||||
final int FIRST_MERGE_COL=INSERT_COLUMN+1;
|
private static final int LAST_MERGE_COL = numCols-1;
|
||||||
final int LAST_MERGE_COL=numCols-1;
|
|
||||||
|
private XSSFWorkbook workbook = null;
|
||||||
|
private XSSFSheet sheet = null;
|
||||||
|
private String fileName = null;
|
||||||
|
|
||||||
public TestXSSFSheetShiftRowsAndColumns() {
|
public TestXSSFSheetShiftRowsAndColumns() {
|
||||||
resultDir.mkdirs();
|
assertTrue("Failed to create directory " + resultDir,
|
||||||
|
resultDir.exists() || resultDir.mkdirs());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,8 +61,10 @@ public class TestXSSFSheetShiftRowsAndColumns {
|
||||||
* 0 to numCols-1.
|
* 0 to numCols-1.
|
||||||
*/
|
*/
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() throws IOException {
|
||||||
final String procName="TestXSSFSheetShiftRowsAndColumns.setup";
|
final String procName = "TestXSSFSheetShiftRowsAndColumns.setup";
|
||||||
|
fileName = procName+".xlsx";
|
||||||
|
|
||||||
workbook = new XSSFWorkbook();
|
workbook = new XSSFWorkbook();
|
||||||
sheet = workbook.createSheet();
|
sheet = workbook.createSheet();
|
||||||
|
|
||||||
|
@ -73,10 +79,11 @@ public class TestXSSFSheetShiftRowsAndColumns {
|
||||||
/*
|
/*
|
||||||
* Add a merge area
|
* Add a merge area
|
||||||
*/
|
*/
|
||||||
final CellRangeAddress range=new CellRangeAddress(FIRST_MERGE_ROW,LAST_MERGE_ROW,FIRST_MERGE_COL,LAST_MERGE_COL);
|
final CellRangeAddress range = new CellRangeAddress(FIRST_MERGE_ROW,LAST_MERGE_ROW,FIRST_MERGE_COL,LAST_MERGE_COL);
|
||||||
sheet.addMergedRegion(range);
|
sheet.addMergedRegion(range);
|
||||||
System.out.println(String.format(Locale.US, "\n%s: mergeArea=%s", procName,range));
|
System.out.println(String.format(Locale.US, "\n%s: mergeArea=%s", procName,range));
|
||||||
|
|
||||||
|
writeFile(procName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,31 +91,28 @@ public class TestXSSFSheetShiftRowsAndColumns {
|
||||||
* This method writes the workbook to resultDir/fileName.
|
* This method writes the workbook to resultDir/fileName.
|
||||||
*/
|
*/
|
||||||
@After
|
@After
|
||||||
public void cleanup() {
|
public void cleanup() throws IOException {
|
||||||
final String procName="TestXSSFSheetRemoveTable.cleanup";
|
final String procName = "TestXSSFSheetRemoveTable.cleanup";
|
||||||
if (workbook == null) {
|
if (workbook == null) {
|
||||||
System.out.println(String.format(Locale.ROOT,"%s: workbook==null",procName));
|
System.out.println(String.format(Locale.ROOT,"%s: workbook==null",procName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fileName==null) {
|
if(fileName == null) {
|
||||||
System.out.println(String.format(Locale.ROOT, "%s: fileName==null",procName));
|
System.out.println(String.format(Locale.ROOT, "%s: fileName==null",procName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final File file=new File(resultDir,fileName);
|
writeFile(procName);
|
||||||
|
|
||||||
|
workbook.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeFile(String procName) throws IOException {
|
||||||
|
final File file = new File(resultDir,fileName);
|
||||||
try (OutputStream fileOut = new FileOutputStream(file)) {
|
try (OutputStream fileOut = new FileOutputStream(file)) {
|
||||||
workbook.write(fileOut);
|
workbook.write(fileOut);
|
||||||
System.out.println(String.format(Locale.ROOT, "%s: test file written to %s",procName,file.getAbsolutePath()));
|
System.out.println(String.format(Locale.ROOT, "%s: test file written to %s",procName,file.getAbsolutePath()));
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println(e.getMessage());
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
workbook.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,8 +121,8 @@ public class TestXSSFSheetShiftRowsAndColumns {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNoShift() {
|
public void testNoShift() {
|
||||||
final String procName="testNoShift";
|
final String procName = "testNoShift";
|
||||||
fileName=procName+".xlsx";
|
fileName = procName+".xlsx";
|
||||||
|
|
||||||
testCellAddresses(procName,0,0);
|
testCellAddresses(procName,0,0);
|
||||||
testMergeRegion(procName,0,0);
|
testMergeRegion(procName,0,0);
|
||||||
|
@ -128,21 +132,20 @@ public class TestXSSFSheetShiftRowsAndColumns {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShiftOneRowAndTestAddresses() {
|
public void testShiftOneRowAndTestAddresses() {
|
||||||
final String procName="testShiftOneRowAndTestAddresses";
|
final String procName = "testShiftOneRowAndTestAddresses";
|
||||||
fileName=procName+".xlsx";
|
fileName = procName+".xlsx";
|
||||||
final int nRowsToShift=1;
|
final int nRowsToShift = 1;
|
||||||
|
|
||||||
sheet.shiftRows(INSERT_ROW, numRows-1, nRowsToShift);
|
sheet.shiftRows(INSERT_ROW, numRows-1, nRowsToShift);
|
||||||
testCellAddresses(procName,nRowsToShift,0);
|
testCellAddresses(procName,nRowsToShift,0);
|
||||||
System.out.println(String.format(Locale.US, "%s: finished without error", procName));
|
System.out.println(String.format(Locale.US, "%s: finished without error", procName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("currently fails")
|
|
||||||
@Test
|
@Test
|
||||||
public void testShiftOneRowAndTestMergeRegion() {
|
public void testShiftOneRowAndTestMergeRegion() {
|
||||||
final String procName="testShiftOneRowAndTestMergeRegion";
|
final String procName = "testShiftOneRowAndTestMergeRegion";
|
||||||
fileName=procName+".xlsx";
|
fileName = procName+".xlsx";
|
||||||
final int nRowsToShift=1;
|
final int nRowsToShift = 1;
|
||||||
|
|
||||||
sheet.shiftRows(INSERT_ROW, numRows-1, nRowsToShift);
|
sheet.shiftRows(INSERT_ROW, numRows-1, nRowsToShift);
|
||||||
testMergeRegion(procName,nRowsToShift,0);
|
testMergeRegion(procName,nRowsToShift,0);
|
||||||
|
@ -151,24 +154,23 @@ public class TestXSSFSheetShiftRowsAndColumns {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShiftOneColumnAndTestAddresses() {
|
public void testShiftOneColumnAndTestAddresses() {
|
||||||
final String procName="testShiftOneColumnAndTestAddresses";
|
final String procName = "testShiftOneColumnAndTestAddresses";
|
||||||
fileName=procName+".xlsx";
|
fileName = procName+".xlsx";
|
||||||
final int nShift=1;
|
final int nShift = 1;
|
||||||
|
|
||||||
sheet.shiftColumns(INSERT_COLUMN, numCols-1, nShift);
|
sheet.shiftColumns(INSERT_COLUMN, numCols-1, nShift);
|
||||||
testCellAddresses(procName,0,nShift);
|
testCellAddresses(procName,0,nShift);
|
||||||
System.out.println(String.format(Locale.US, "%s: finished without error", procName));
|
System.out.println(String.format(Locale.US, "%s: finished without error", procName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("currently fails")
|
|
||||||
@Test
|
@Test
|
||||||
public void testShiftOneColumnAndTestMergeRegion() {
|
public void testShiftOneColumnAndTestMergeRegion() {
|
||||||
final String procName="testShiftOneColumnAndTestMergeRegion";
|
final String procName = "testShiftOneColumnAndTestMergeRegion";
|
||||||
fileName=procName+".xlsx";
|
fileName = procName+".xlsx";
|
||||||
final int nShift=1;
|
final int nShift = 1;
|
||||||
|
|
||||||
sheet.shiftColumns(INSERT_COLUMN, numCols-1, nShift);
|
sheet.shiftColumns(INSERT_COLUMN, numCols-1, nShift);
|
||||||
testMergeRegion(procName,0,nShift);
|
testMergeRegion(procName,0, nShift);
|
||||||
System.out.println(String.format(Locale.US, "%s: finished without error", procName));
|
System.out.println(String.format(Locale.US, "%s: finished without error", procName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,26 +178,26 @@ public class TestXSSFSheetShiftRowsAndColumns {
|
||||||
* Verify that the cell addresses are consistent
|
* Verify that the cell addresses are consistent
|
||||||
*/
|
*/
|
||||||
private void testCellAddresses(String procName,int nRowsToShift,int nColsToShift) {
|
private void testCellAddresses(String procName,int nRowsToShift,int nColsToShift) {
|
||||||
final int nNumRows=nRowsToShift+this.numCols;
|
final int nNumRows = nRowsToShift+ numCols;
|
||||||
final int nNumCols=nColsToShift+this.numCols;
|
final int nNumCols = nColsToShift+ numCols;
|
||||||
for(int nRow=0;nRow<nNumRows;++nRow) {
|
for(int nRow = 0;nRow<nNumRows;++nRow) {
|
||||||
final XSSFRow row=sheet.getRow(nRow);
|
final XSSFRow row = sheet.getRow(nRow);
|
||||||
if(row==null) {
|
if(row == null) {
|
||||||
System.out.println(String.format(Locale.US, "%s: Row %d is empty", procName,nRow));
|
System.out.println(String.format(Locale.US, "%s: Row %d is empty", procName,nRow));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for(int nCol=0;nCol<nNumCols;++nCol) {
|
for(int nCol = 0;nCol<nNumCols;++nCol) {
|
||||||
final String address=new CellAddress(nRow,nCol).formatAsString();
|
final String address = new CellAddress(nRow,nCol).formatAsString();
|
||||||
final XSSFCell cell=row.getCell(nCol);
|
final XSSFCell cell = row.getCell(nCol);
|
||||||
if(cell==null) {
|
if(cell == null) {
|
||||||
System.out.println(String.format(Locale.US, "%s: Cell %s is empty", procName,address));
|
System.out.println(String.format(Locale.US, "%s: Cell %s is empty", procName,address));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final CTCell ctCell=cell.getCTCell();
|
final CTCell ctCell = cell.getCTCell();
|
||||||
final Object cellAddress=cell.getAddress().formatAsString();
|
final Object cellAddress = cell.getAddress().formatAsString();
|
||||||
final Object r=ctCell.getR();
|
final Object r = ctCell.getR();
|
||||||
|
|
||||||
if(nCol==0 || nRow==0) {
|
if(nCol == 0 || nRow == 0) {
|
||||||
System.out.println(String.format(Locale.US, "%s: Row %d col %d address=%s cell.address=%s cell.getR=%s", procName, nRow,
|
System.out.println(String.format(Locale.US, "%s: Row %d col %d address=%s cell.address=%s cell.getR=%s", procName, nRow,
|
||||||
nCol, address, cellAddress, ctCell.getR()));
|
nCol, address, cellAddress, ctCell.getR()));
|
||||||
}
|
}
|
||||||
|
@ -210,9 +212,10 @@ public class TestXSSFSheetShiftRowsAndColumns {
|
||||||
* Verify that the merge area is consistent
|
* Verify that the merge area is consistent
|
||||||
*/
|
*/
|
||||||
private void testMergeRegion(String procName,int nRowsToShift,int nColsToShift) {
|
private void testMergeRegion(String procName,int nRowsToShift,int nColsToShift) {
|
||||||
final CellRangeAddress range=sheet.getMergedRegion(0);
|
final CellRangeAddress range = sheet.getMergedRegion(0);
|
||||||
assertEquals(String.format(Locale.US, "%s: Testing merge area %s",procName,range),range,
|
assertEquals(String.format(Locale.US, "%s: Testing merge area %s", procName, range),
|
||||||
new CellRangeAddress(FIRST_MERGE_ROW,LAST_MERGE_ROW+nRowsToShift,FIRST_MERGE_COL,LAST_MERGE_COL+nColsToShift));
|
new CellRangeAddress(FIRST_MERGE_ROW + nRowsToShift, LAST_MERGE_ROW + nRowsToShift,
|
||||||
|
FIRST_MERGE_COL + nColsToShift, LAST_MERGE_COL + nColsToShift),
|
||||||
|
range);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -95,6 +95,7 @@ public abstract class BaseTestSheetShiftColumns {
|
||||||
style.setVerticalAlignment(VerticalAlignment.BOTTOM);
|
style.setVerticalAlignment(VerticalAlignment.BOTTOM);
|
||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShiftOneColumnRight() {
|
public void testShiftOneColumnRight() {
|
||||||
sheet1.shiftColumns(1, 2, 1);
|
sheet1.shiftColumns(1, 2, 1);
|
||||||
|
|
Loading…
Reference in New Issue