diff --git a/src/java/org/apache/poi/ss/usermodel/Table.java b/src/java/org/apache/poi/ss/usermodel/Table.java index 4d8aba1d3..ef7fe3379 100644 --- a/src/java/org/apache/poi/ss/usermodel/Table.java +++ b/src/java/org/apache/poi/ss/usermodel/Table.java @@ -19,6 +19,8 @@ package org.apache.poi.ss.usermodel; import java.util.regex.Pattern; +import org.apache.poi.ss.util.CellReference; + /** * XSSF Only! * High level abstraction of table in a workbook. @@ -116,6 +118,18 @@ public interface Table { * @param cell * @return true if the table and cell are on the same sheet and the cell is within the table range. * @since 3.17 beta 1 + * @see #contains(CellReference) (prefered, faster execution and handles undefined cells) */ - boolean contains(Cell cell); + default boolean contains(Cell cell) { + if (cell == null) return false; + return contains(new CellReference(cell.getSheet().getSheetName(), cell.getRowIndex(), cell.getColumnIndex(), true, true)); + } + + /** + * checks if the given cell is part of the table. Includes checking that they are on the same sheet. + * @param cell reference to a possibly undefined cell location + * @return true if the table and cell are on the same sheet and the cell is within the table range. + * @since 3.17 beta 1 + */ + boolean contains(CellReference cell); } diff --git a/src/java/org/apache/poi/ss/usermodel/TableStyleType.java b/src/java/org/apache/poi/ss/usermodel/TableStyleType.java index c34744b34..0bf5a0b56 100644 --- a/src/java/org/apache/poi/ss/usermodel/TableStyleType.java +++ b/src/java/org/apache/poi/ss/usermodel/TableStyleType.java @@ -19,6 +19,7 @@ package org.apache.poi.ss.usermodel; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddressBase; +import org.apache.poi.ss.util.CellReference; /** * Ordered list of table style elements, for both data tables and pivot tables. @@ -38,7 +39,7 @@ import org.apache.poi.ss.util.CellRangeAddressBase; public enum TableStyleType { /***/ wholeTable { - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { return new CellRangeAddress(table.getStartRowIndex(), table.getEndRowIndex(), table.getStartColIndex(), table.getEndColIndex()); } }, @@ -48,7 +49,7 @@ public enum TableStyleType { pageFieldValues, // pivot only /***/ firstColumnStripe{ - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { TableStyleInfo info = table.getStyle(); if (! info.isShowColumnStripes()) return null; DifferentialStyleProvider c1Style = info.getStyle().getStyle(firstColumnStripe); @@ -58,7 +59,7 @@ public enum TableStyleType { int firstStart = table.getStartColIndex(); int secondStart = firstStart + c1Stripe; - int c = cell.getColumnIndex(); + int c = cell.getCol(); // look for the stripe containing c, accounting for the style element stripe size // could do fancy math, but tables can't be that wide, a simple loop is fine @@ -74,7 +75,7 @@ public enum TableStyleType { }, /***/ secondColumnStripe{ - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { TableStyleInfo info = table.getStyle(); if (! info.isShowColumnStripes()) return null; @@ -85,7 +86,7 @@ public enum TableStyleType { int firstStart = table.getStartColIndex(); int secondStart = firstStart + c1Stripe; - int c = cell.getColumnIndex(); + int c = cell.getCol(); // look for the stripe containing c, accounting for the style element stripe size // could do fancy math, but tables can't be that wide, a simple loop is fine @@ -101,7 +102,7 @@ public enum TableStyleType { }, /***/ firstRowStripe { - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { TableStyleInfo info = table.getStyle(); if (! info.isShowRowStripes()) return null; @@ -112,7 +113,7 @@ public enum TableStyleType { int firstStart = table.getStartRowIndex() + table.getHeaderRowCount(); int secondStart = firstStart + c1Stripe; - int c = cell.getRowIndex(); + int c = cell.getRow(); // look for the stripe containing c, accounting for the style element stripe size // could do fancy math, but tables can't be that wide, a simple loop is fine @@ -128,7 +129,7 @@ public enum TableStyleType { }, /***/ secondRowStripe{ - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { TableStyleInfo info = table.getStyle(); if (! info.isShowRowStripes()) return null; @@ -139,7 +140,7 @@ public enum TableStyleType { int firstStart = table.getStartRowIndex() + table.getHeaderRowCount(); int secondStart = firstStart + c1Stripe; - int c = cell.getRowIndex(); + int c = cell.getRow(); // look for the stripe containing c, accounting for the style element stripe size // could do fancy math, but tables can't be that wide, a simple loop is fine @@ -155,56 +156,56 @@ public enum TableStyleType { }, /***/ lastColumn { - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { if (! table.getStyle().isShowLastColumn()) return null; return new CellRangeAddress(table.getStartRowIndex(), table.getEndRowIndex(), table.getEndColIndex(), table.getEndColIndex()); } }, /***/ firstColumn { - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { if (! table.getStyle().isShowFirstColumn()) return null; return new CellRangeAddress(table.getStartRowIndex(), table.getEndRowIndex(), table.getStartColIndex(), table.getStartColIndex()); } }, /***/ headerRow { - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { if (table.getHeaderRowCount() < 1) return null; return new CellRangeAddress(table.getStartRowIndex(), table.getStartRowIndex() + table.getHeaderRowCount() -1, table.getStartColIndex(), table.getEndColIndex()); } }, /***/ totalRow { - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { if (table.getTotalsRowCount() < 1) return null; return new CellRangeAddress(table.getEndRowIndex() - table.getTotalsRowCount() +1, table.getEndRowIndex(), table.getStartColIndex(), table.getEndColIndex()); } }, /***/ firstHeaderCell { - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { if (table.getHeaderRowCount() < 1) return null; return new CellRangeAddress(table.getStartRowIndex(), table.getStartRowIndex(), table.getStartColIndex(), table.getStartColIndex()); } }, /***/ lastHeaderCell { - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { if (table.getHeaderRowCount() < 1) return null; return new CellRangeAddress(table.getStartRowIndex(), table.getStartRowIndex(), table.getEndColIndex(), table.getEndColIndex()); } }, /***/ firstTotalCell { - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { if (table.getTotalsRowCount() < 1) return null; return new CellRangeAddress(table.getEndRowIndex() - table.getTotalsRowCount() +1, table.getEndRowIndex(), table.getStartColIndex(), table.getStartColIndex()); } }, /***/ lastTotalCell { - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { if (table.getTotalsRowCount() < 1) return null; return new CellRangeAddress(table.getEndRowIndex() - table.getTotalsRowCount() +1, table.getEndRowIndex(), table.getEndColIndex(), table.getEndColIndex()); } @@ -257,22 +258,58 @@ public enum TableStyleType { * Stripe style types return only the stripe range containing the given cell, or null. */ public CellRangeAddressBase appliesTo(Table table, Cell cell) { + if (cell == null) return null; + return appliesTo(table, new CellReference(cell.getSheet().getSheetName(), cell.getRowIndex(), cell.getColumnIndex(), true, true)); + } + + /** + * A range is returned only for the part of the table matching this enum instance and containing the given cell reference. + * Null is returned for all other cases, such as: + * + * The returned range can be used to determine how style options may or may not apply to this cell. + * For example, {@link #wholeTable} borders only apply to the outer boundary of a table, while the + * rest of the styling, such as font and color, could apply to all the interior cells as well. + * + * @param table table to evaluate + * @param cell CellReference to evaluate + * @return range in the table representing this class of cells, if it contains the given cell, or null if not applicable. + * Stripe style types return only the stripe range containing the given cell, or null. + */ + public CellRangeAddressBase appliesTo(Table table, CellReference cell) { if (table == null || cell == null) return null; - if ( ! cell.getSheet().getSheetName().equals(table.getSheetName())) return null; + if ( ! cell.getSheetName().equals(table.getSheetName())) return null; if ( ! table.contains(cell)) return null; final CellRangeAddressBase range = getRange(table, cell); - if (range != null && range.isInRange(cell.getRowIndex(), cell.getColumnIndex())) return range; + if (range != null && range.isInRange(cell.getRow(), cell.getCol())) return range; // else return null; } /** + * Calls {@link #getRange(Table, CellReference)}. Use that instead for performance. + * @param table + * @param cell + * @return default is unimplemented/null + * @see #getRange(Table, CellReference) + */ + public final CellRangeAddressBase getRange(Table table, Cell cell) { + if (cell == null) return null; + return getRange(table, new CellReference(cell.getSheet().getSheetName(), cell.getRowIndex(), cell.getColumnIndex(), true, true)); + } + + /** + * * @param table * @param cell * @return default is unimplemented/null */ - CellRangeAddressBase getRange(Table table, Cell cell) { + public CellRangeAddressBase getRange(Table table, CellReference cell) { return null; } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java index 0fbd8d333..68e1bdd0c 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java @@ -32,7 +32,6 @@ import java.util.Locale; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.ss.SpreadsheetVersion; -import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.DataFormatter; import org.apache.poi.ss.usermodel.Table; @@ -951,15 +950,15 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { * @see org.apache.poi.ss.usermodel.Table#contains(org.apache.poi.ss.usermodel.Cell) * @since 3.17 beta 1 */ - public boolean contains(Cell cell) { + public boolean contains(CellReference cell) { if (cell == null) return false; // check if cell is on the same sheet as the table - if ( ! getSheetName().equals(cell.getSheet().getSheetName())) return false; + if ( ! getSheetName().equals(cell.getSheetName())) return false; // check if the cell is inside the table - if (cell.getRowIndex() >= getStartRowIndex() - && cell.getRowIndex() <= getEndRowIndex() - && cell.getColumnIndex() >= getStartColIndex() - && cell.getColumnIndex() <= getEndColIndex()) { + if (cell.getRow() >= getStartRowIndex() + && cell.getRow() <= getEndRowIndex() + && cell.getCol() >= getStartColIndex() + && cell.getCol() <= getEndColIndex()) { return true; } return false;