[bug-66173] add new XSSFSheet createSplitPane method to avoid bug in existing method

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1902876 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2022-07-20 13:13:28 +00:00
parent 369681f7f9
commit 590e49c143
10 changed files with 214 additions and 41 deletions

View File

@ -24,6 +24,7 @@ import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.PaneType;
import org.apache.poi.ss.usermodel.Sheet;
public class SplitAndFreezePanes {
@ -41,7 +42,7 @@ public class SplitAndFreezePanes {
// Freeze the columns and rows (forget about scrolling position of the lower right quadrant).
sheet3.createFreezePane(2, 2);
// Create a split with the lower left side being the active quadrant
sheet4.createSplitPane(2000, 2000, 0, 0, Sheet.PANE_LOWER_LEFT);
sheet4.createSplitPane(2000, 2000, 0, 0, PaneType.LOWER_LEFT);
try (FileOutputStream fileOut = new FileOutputStream("workbook.xls")) {
wb.write(fileOut);

View File

@ -20,6 +20,7 @@ package org.apache.poi.examples.xssf.usermodel;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.ss.usermodel.PaneType;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
@ -42,7 +43,7 @@ public class SplitAndFreezePanes {
// Freeze the columns and rows (forget about scrolling position of the lower right quadrant).
sheet3.createFreezePane(2, 2);
// Create a split with the lower left side being the active quadrant
sheet4.createSplitPane(2000, 2000, 0, 0, Sheet.PANE_LOWER_LEFT);
sheet4.createSplitPane(2000, 2000, 0, 0, PaneType.LOWER_LEFT);
try (FileOutputStream fileOut = new FileOutputStream("splitFreezePane.xlsx")) {
wb.write(fileOut);

View File

@ -35,6 +35,7 @@ import org.apache.poi.ss.util.PaneInformation;
import org.apache.poi.ss.util.SheetUtil;
import org.apache.poi.util.Internal;
import org.apache.poi.util.NotImplemented;
import org.apache.poi.util.Removal;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr;
@ -963,9 +964,10 @@ public class SXSSFSheet implements Sheet, OoxmlSheetExtensions {
*/
@Override
public void createFreezePane(int colSplit, int rowSplit) {
_sh.createFreezePane(colSplit,rowSplit);
_sh.createFreezePane(colSplit, rowSplit);
}
/**
* Creates a split pane. Any existing freezepane or split pane is overwritten.
* @param xSplitPos Horizontal position of split (in 1/20th of a point).
@ -973,17 +975,36 @@ public class SXSSFSheet implements Sheet, OoxmlSheetExtensions {
* @param topRow Top row visible in bottom pane
* @param leftmostColumn Left column visible in right pane.
* @param activePane Active pane. One of: PANE_LOWER_RIGHT,
* PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT
* PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT (but there is a
* <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=66173">bug</a>, so add 1)
* @see #PANE_LOWER_LEFT
* @see #PANE_LOWER_RIGHT
* @see #PANE_UPPER_LEFT
* @see #PANE_UPPER_RIGHT
* @deprecated use {@link #createSplitPane(int, int, int, int, PaneType)}
*/
@Override
@Deprecated
@Removal(version = "POI 7.0.0")
public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) {
_sh.createSplitPane(xSplitPos, ySplitPos, leftmostColumn, topRow, activePane);
}
/**
* Creates a split pane. Any existing freezepane or split pane is overwritten.
* @param xSplitPos Horizontal position of split (in 1/20th of a point).
* @param ySplitPos Vertical position of split (in 1/20th of a point).
* @param topRow Top row visible in bottom pane
* @param leftmostColumn Left column visible in right pane.
* @param activePane Active pane.
* @see PaneType
* @since POI 5.2.3
*/
@Override
public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, PaneType activePane) {
_sh.createSplitPane(xSplitPos, ySplitPos, leftmostColumn, topRow, activePane);
}
/**
* Returns the information regarding the currently configured pane (split or freeze)
*

View File

@ -55,6 +55,7 @@ import org.apache.poi.ss.util.SSCellRange;
import org.apache.poi.ss.util.SheetUtil;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
import org.apache.poi.util.Removal;
import org.apache.poi.util.Units;
import org.apache.poi.xssf.model.Comments;
import org.apache.poi.xssf.usermodel.XSSFPivotTable.PivotTableReferenceConfigurator;
@ -743,13 +744,17 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx
* @param topRow Top row visible in bottom pane
* @param leftmostColumn Left column visible in right pane.
* @param activePane Active pane. One of: PANE_LOWER_RIGHT,
* PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT
* @see Sheet#PANE_LOWER_LEFT
* @see Sheet#PANE_LOWER_RIGHT
* @see Sheet#PANE_UPPER_LEFT
* @see Sheet#PANE_UPPER_RIGHT
* PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT (but there is a
* <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=66173">bug</a>, so add 1)
* @see #PANE_LOWER_LEFT
* @see #PANE_LOWER_RIGHT
* @see #PANE_UPPER_LEFT
* @see #PANE_UPPER_RIGHT
* @deprecated use {@link #createSplitPane(int, int, int, int, PaneType)}
*/
@Override
@Deprecated
@Removal(version = "POI 7.0.0")
public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) {
createFreezePane(xSplitPos, ySplitPos, leftmostColumn, topRow);
if (xSplitPos > 0 || ySplitPos > 0) {
@ -759,6 +764,42 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet, OoxmlSheetEx
}
}
/**
* Creates a split pane. Any existing freezepane or split pane is overwritten.
* @param xSplitPos Horizontal position of split (in 1/20th of a point).
* @param ySplitPos Vertical position of split (in 1/20th of a point).
* @param topRow Top row visible in bottom pane
* @param leftmostColumn Left column visible in right pane.
* @param activePane Active pane.
* @see PaneType
* @since POI 5.2.3
*/
@Override
public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, PaneType activePane) {
createFreezePane(xSplitPos, ySplitPos, leftmostColumn, topRow);
if (xSplitPos > 0 || ySplitPos > 0) {
final CTPane pane = getPane(true);
pane.setState(STPaneState.SPLIT);
STPane.Enum stPaneEnum;
switch (activePane) {
case LOWER_RIGHT:
stPaneEnum = STPane.BOTTOM_RIGHT;
break;
case UPPER_RIGHT:
stPaneEnum = STPane.TOP_RIGHT;
break;
case LOWER_LEFT:
stPaneEnum = STPane.BOTTOM_LEFT;
break;
case UPPER_LEFT:
default:
stPaneEnum = STPane.TOP_LEFT;
break;
}
pane.setActivePane(stPaneEnum);
}
}
/**
* Return cell comment at row, column, if one exists. Otherwise returns null.
*

View File

@ -52,26 +52,13 @@ import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.ss.tests.usermodel.BaseTestXSheet;
import org.apache.poi.ss.usermodel.AutoFilter;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.FormulaError;
import org.apache.poi.ss.usermodel.IgnoredErrorType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.CellUtil;
import org.apache.poi.ss.util.PaneInformation;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.xssf.XSSFITestDataProvider;
import org.apache.poi.xssf.XSSFTestDataSamples;
@ -285,7 +272,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
}
@Test
void createFreezePane_XSSF() throws IOException {
void createFreezePane_XSSF_withBug66173() throws IOException {
try (XSSFWorkbook workbook = new XSSFWorkbook()) {
XSSFSheet sheet = workbook.createSheet();
CTWorksheet ctWorksheet = sheet.getCTWorksheet();
@ -297,12 +284,42 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertEquals(3.0, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getXSplit(), 0.0);
// assertEquals(10, sheet.getTopRow());
// assertEquals(10, sheet.getLeftCol());
sheet.createSplitPane(4, 8, 12, 12, 1);
//need to add 1 to pane type due to https://bz.apache.org/bugzilla/show_bug.cgi?id=66173
sheet.createSplitPane(4, 8, 12, 12, PaneInformation.PANE_LOWER_RIGHT + 1);
assertEquals(8.0, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getYSplit(), 0.0);
assertSame(STPane.BOTTOM_RIGHT, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getActivePane());
}
}
@Test
void createFreezePane_XSSF() throws IOException {
try (XSSFWorkbook workbook = new XSSFWorkbook()) {
XSSFSheet sheet = workbook.createSheet();
CTWorksheet ctWorksheet = sheet.getCTWorksheet();
sheet.createFreezePane(2, 4);
assertEquals(2.0, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getXSplit(), 0.0);
assertSame(STPane.BOTTOM_RIGHT, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getActivePane());
assertSame(PaneType.LOWER_RIGHT, sheet.getPaneInformation().getActivePaneType());
sheet.createFreezePane(3, 6, 10, 10);
assertEquals(3.0, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getXSplit(), 0.0);
// assertEquals(10, sheet.getTopRow());
// assertEquals(10, sheet.getLeftCol());
sheet.createSplitPane(4, 8, 12, 12, PaneType.LOWER_RIGHT);
assertEquals(8.0, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getYSplit(), 0.0);
assertSame(STPane.BOTTOM_RIGHT, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getActivePane());
}
}
@Test
void defaultActivePaneType() throws IOException {
try (XSSFWorkbook workbook = new XSSFWorkbook()) {
XSSFSheet sheet = workbook.createSheet();
assertNull(sheet.getPaneInformation());
}
}
@Test
void removeMergedRegion_lowlevel() throws IOException {
try (XSSFWorkbook workbook = new XSSFWorkbook()) {

View File

@ -40,6 +40,7 @@ import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.WorksheetProtectionBlock;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.PaneInformation;
import org.apache.poi.util.Internal;
@ -103,10 +104,10 @@ public final class InternalSheet {
/** Add an UncalcedRecord if not true indicating formulas have not been calculated */
protected boolean _isUncalced;
public static final byte PANE_LOWER_RIGHT = (byte)0;
public static final byte PANE_UPPER_RIGHT = (byte)1;
public static final byte PANE_LOWER_LEFT = (byte)2;
public static final byte PANE_UPPER_LEFT = (byte)3;
public static final byte PANE_LOWER_RIGHT = Sheet.PANE_LOWER_RIGHT;
public static final byte PANE_UPPER_RIGHT = Sheet.PANE_UPPER_RIGHT;
public static final byte PANE_LOWER_LEFT = Sheet.PANE_LOWER_LEFT;
public static final byte PANE_UPPER_LEFT = Sheet.PANE_UPPER_LEFT;
/**
* read support (offset used as starting point for search) for low level

View File

@ -69,6 +69,7 @@ import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.PaneType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
@ -83,6 +84,7 @@ import org.apache.poi.ss.util.SheetUtil;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Configurator;
import org.apache.poi.util.Internal;
import org.apache.poi.util.Removal;
import static java.lang.System.currentTimeMillis;
import static org.apache.logging.log4j.util.Unbox.box;
@ -1827,23 +1829,56 @@ public final class HSSFSheet implements Sheet {
/**
* Creates a split pane. Any existing freezepane or split pane is overwritten.
*
* @param xSplitPos Horizontal position of split (in 1/20th of a point).
* @param ySplitPos Vertical position of split (in 1/20th of a point).
* @param topRow Top row visible in bottom pane
* @param leftmostColumn Left column visible in right pane.
* @param activePane Active pane. One of: PANE_LOWER_RIGHT,
* PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT
* @param topRow Top row visible in bottom pane
* @param leftmostColumn Left column visible in right pane.
* @param activePane Active pane. One of: PANE_LOWER_RIGHT,
* PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT
* @see #PANE_LOWER_LEFT
* @see #PANE_LOWER_RIGHT
* @see #PANE_UPPER_LEFT
* @see #PANE_UPPER_RIGHT
* @deprecated use {@link #createSplitPane(int, int, int, int, PaneType)}
*/
@Override
@Deprecated
@Removal(version = "POI 7.0.0")
public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) {
getSheet().createSplitPane(xSplitPos, ySplitPos, topRow, leftmostColumn, activePane);
}
/**
* Creates a split pane. Any existing freezepane or split pane is overwritten.
* @param xSplitPos Horizontal position of split (in 1/20th of a point).
* @param ySplitPos Vertical position of split (in 1/20th of a point).
* @param topRow Top row visible in bottom pane
* @param leftmostColumn Left column visible in right pane.
* @param activePane Active pane.
* @see PaneType
* @since POI 5.2.3
*/
@Override
public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, PaneType activePane) {
byte activePaneByte;
switch (activePane) {
case LOWER_RIGHT:
activePaneByte = Sheet.PANE_LOWER_RIGHT;
break;
case UPPER_RIGHT:
activePaneByte = Sheet.PANE_UPPER_RIGHT;
break;
case LOWER_LEFT:
activePaneByte = Sheet.PANE_LOWER_LEFT;
break;
case UPPER_LEFT:
default:
activePaneByte = Sheet.PANE_UPPER_LEFT;
break;
}
getSheet().createSplitPane(xSplitPos, ySplitPos, topRow, leftmostColumn, activePaneByte);
}
/**
* Returns the information regarding the currently configured pane (split or freeze).
*

View File

@ -27,6 +27,7 @@ import java.util.Spliterators;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.PaneInformation;
import org.apache.poi.util.Removal;
/**
* High level representation of a Excel worksheet.
@ -52,13 +53,13 @@ public interface Sheet extends Iterable<Row> {
short FooterMargin = 5;
byte PANE_LOWER_RIGHT = (byte) 0;
byte PANE_LOWER_RIGHT = PaneInformation.PANE_LOWER_RIGHT;
byte PANE_UPPER_RIGHT = (byte) 1;
byte PANE_UPPER_RIGHT = PaneInformation.PANE_UPPER_RIGHT;
byte PANE_LOWER_LEFT = (byte) 2;
byte PANE_LOWER_LEFT = PaneInformation.PANE_LOWER_LEFT;
byte PANE_UPPER_LEFT = (byte) 3;
byte PANE_UPPER_LEFT = PaneInformation.PANE_UPPER_LEFT;
/**
* Create a new row within the sheet and return the high level representation
@ -777,9 +778,24 @@ public interface Sheet extends Iterable<Row> {
* @see #PANE_LOWER_RIGHT
* @see #PANE_UPPER_LEFT
* @see #PANE_UPPER_RIGHT
* @deprecated use {@link #createSplitPane(int, int, int, int, PaneType)}
*/
@Deprecated
@Removal(version = "POI 7.0.0")
void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane);
/**
* Creates a split pane. Any existing freezepane or split pane is overwritten.
* @param xSplitPos Horizontal position of split (in 1/20th of a point).
* @param ySplitPos Vertical position of split (in 1/20th of a point).
* @param topRow Top row visible in bottom pane
* @param leftmostColumn Left column visible in right pane.
* @param activePane Active pane.
* @see PaneType
* @since POI 5.2.3
*/
void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, PaneType activePane);
/**
* Returns the information regarding the currently configured pane (split or freeze)
*

View File

@ -17,6 +17,8 @@
package org.apache.poi.ss.util;
import org.apache.poi.ss.usermodel.PaneType;
import java.util.Objects;
/**
@ -50,7 +52,6 @@ public class PaneInformation
this.frozen = frozen;
}
/**
* Returns the vertical position of the split.
* @return 0 if there is no vertical spilt,
@ -88,7 +89,7 @@ public class PaneInformation
}
/**
* Returns the active pane
* Returns the active pane.
* @see #PANE_LOWER_RIGHT
* @see #PANE_UPPER_RIGHT
* @see #PANE_LOWER_LEFT
@ -99,6 +100,25 @@ public class PaneInformation
return activePane;
}
/**
* @return the active pane type - can return <code>null</code> if no active pane type is set
* @since POI 5.2.3
*/
public PaneType getActivePaneType() {
switch (activePane) {
case PANE_LOWER_RIGHT:
return PaneType.LOWER_RIGHT;
case PANE_UPPER_RIGHT:
return PaneType.UPPER_RIGHT;
case PANE_LOWER_LEFT:
return PaneType.LOWER_LEFT;
case PANE_UPPER_LEFT:
return PaneType.UPPER_LEFT;
default:
return null;
}
}
/** Returns true if this is a Freeze pane, false if it is a split pane.
*/
public boolean isFreezePane() {

View File

@ -47,10 +47,12 @@ import org.apache.poi.ss.usermodel.BaseTestSheet;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.PaneType;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.ss.util.PaneInformation;
import org.junit.jupiter.api.Test;
/**
@ -1112,4 +1114,22 @@ final class TestHSSFSheet extends BaseTestSheet {
}
}
}
@Test
void createSplitPane() throws IOException {
try (HSSFWorkbook workbook = new HSSFWorkbook()) {
HSSFSheet sheet = workbook.createSheet();
sheet.createSplitPane(4, 8, 12, 12, PaneType.LOWER_RIGHT);
assertSame(PaneType.LOWER_RIGHT, sheet.getPaneInformation().getActivePaneType());
}
}
@Test
void createSplitPaneWithPaneByte() throws IOException {
try (HSSFWorkbook workbook = new HSSFWorkbook()) {
HSSFSheet sheet = workbook.createSheet();
sheet.createSplitPane(4, 8, 12, 12, PaneInformation.PANE_LOWER_RIGHT);
assertSame(PaneType.LOWER_RIGHT, sheet.getPaneInformation().getActivePaneType());
}
}
}