From 4d4b54b7c87a60e45e7a4552719b4fd6d57c5edc Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Sun, 17 Apr 2016 07:38:15 +0000 Subject: [PATCH] bug 59342: add sheet tab color getter and setter git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1739547 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/usermodel/XSSFColor.java | 71 +++++++++++++++++- .../apache/poi/xssf/usermodel/XSSFSheet.java | 37 +++++++-- .../poi/xssf/usermodel/TestXSSFSheet.java | 38 +++++++++- test-data/spreadsheet/SheetTabColors.xlsx | Bin 0 -> 7008 bytes 4 files changed, 137 insertions(+), 9 deletions(-) create mode 100644 test-data/spreadsheet/SheetTabColors.xlsx diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java index ce142b78c..441f42fdb 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java @@ -16,8 +16,11 @@ ==================================================================== */ package org.apache.poi.xssf.usermodel; +import java.util.Arrays; + import org.apache.poi.ss.usermodel.Color; import org.apache.poi.ss.usermodel.ExtendedColor; +import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.util.Internal; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; @@ -50,6 +53,11 @@ public class XSSFColor extends ExtendedColor { this(); ctColor.setRgb(rgb); } + + public XSSFColor(IndexedColors indexedColor) { + this(); + ctColor.setIndexed(indexedColor.index); + } /** * A boolean value indicating the ctColor is automatic and system ctColor dependent. @@ -304,7 +312,17 @@ public class XSSFColor extends ExtendedColor { return ctColor; } + /** + * Checked type cast color to an XSSFColor. + * + * @param color the color to type cast + * @return the type casted color + * @throws IllegalArgumentException if color is null or is not an instance of XSSFColor + */ public static XSSFColor toXSSFColor(Color color) { + // FIXME: this method would be more useful if it could convert any Color to an XSSFColor + // Currently the only benefit of this method is to throw an IllegalArgumentException + // instead of a ClassCastException. if (color != null && !(color instanceof XSSFColor)) { throw new IllegalArgumentException("Only XSSFColor objects are supported"); } @@ -316,13 +334,62 @@ public class XSSFColor extends ExtendedColor { return ctColor.toString().hashCode(); } + // Helper methods for {@link #equals(Object)} + private boolean sameIndexed(XSSFColor other) { + if (isIndexed() == other.isIndexed()) { + if (isIndexed()) { + return getIndexed() == other.getIndexed(); + } + return true; + } + return false; + } + private boolean sameARGB(XSSFColor other) { + if (isRGB() == other.isRGB()) { + if (isRGB()) { + return Arrays.equals(getARGB(), other.getARGB()); + } + return true; + } + return false; + } + private boolean sameTheme(XSSFColor other) { + if (isThemed() == other.isThemed()) { + if (isThemed()) { + return getTheme() == other.getTheme(); + } + return true; + } + return false; + } + private boolean sameTint(XSSFColor other) { + if (hasTint() == other.hasTint()) { + if (hasTint()) { + return getTint() == other.getTint(); + } + return true; + } + return false; + } + private boolean sameAuto(XSSFColor other) { + return isAuto() == other.isAuto(); + } + @Override public boolean equals(Object o){ if(!(o instanceof XSSFColor)) { return false; } - XSSFColor cf = (XSSFColor)o; - return ctColor.toString().equals(cf.getCTColor().toString()); + XSSFColor other = (XSSFColor)o; + + // Compare each field in ctColor. + // Cannot compare ctColor's XML string representation because equivalent + // colors may have different relation namespace URI's + return sameARGB(other) + && sameTheme(other) + && sameIndexed(other) + && sameTint(other) + && sameAuto(other); } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index 501f6f507..98d7f6c1c 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -63,6 +63,7 @@ import org.apache.poi.ss.usermodel.DataValidationHelper; import org.apache.poi.ss.usermodel.Footer; import org.apache.poi.ss.usermodel.Header; 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.util.AreaReference; @@ -3846,21 +3847,45 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { public XSSFSheetConditionalFormatting getSheetConditionalFormatting(){ return new XSSFSheetConditionalFormatting(this); } + + /** + * Get background color of the sheet tab. + * Returns null if no sheet tab color is set. + * + * @return the background color of the sheet tab + */ + public XSSFColor getTabColor() { + CTSheetPr pr = worksheet.getSheetPr(); + if(pr == null) pr = worksheet.addNewSheetPr(); + if (!pr.isSetTabColor()) { + return null; + } + return new XSSFColor(pr.getTabColor()); + } /** * Set background color of the sheet tab * - * @param colorIndex the indexed color to set, must be a constant from {@link IndexedColors} + * @param colorIndex the indexed color to set, must be a constant from {@link org.apache.poi.ss.usermodel.IndexedColors} + * @deprecated 3.15-beta2. Removed in 3.17. Use {@link #setTabColor(XSSFColor)}. */ - public void setTabColor(int colorIndex){ + public void setTabColor(int colorIndex) { + IndexedColors indexedColor = IndexedColors.fromInt(colorIndex); + XSSFColor color = new XSSFColor(indexedColor); + setTabColor(color); + } + + /** + * Set background color of the sheet tab + * + * @param color the color to set + */ + public void setTabColor(XSSFColor color) { CTSheetPr pr = worksheet.getSheetPr(); if(pr == null) pr = worksheet.addNewSheetPr(); - CTColor color = CTColor.Factory.newInstance(); - color.setIndexed(colorIndex); - pr.setTabColor(color); + pr.setTabColor(color.getCTColor()); } - @Override public CellRangeAddress getRepeatingRows() { return getRepeatingRowsOrColums(true); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java index 7bcd67835..1e641c64e 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java @@ -1911,7 +1911,7 @@ public final class TestXSSFSheet extends BaseTestSheet { try { XSSFSheet sh = wb.createSheet(); assertTrue(sh.getCTWorksheet().getSheetPr() == null || !sh.getCTWorksheet().getSheetPr().isSetTabColor()); - sh.setTabColor(IndexedColors.RED); + sh.setTabColor(new XSSFColor(IndexedColors.RED)); assertTrue(sh.getCTWorksheet().getSheetPr().isSetTabColor()); assertEquals(IndexedColors.RED.index, sh.getCTWorksheet().getSheetPr().getTabColor().getIndexed()); @@ -1919,4 +1919,40 @@ public final class TestXSSFSheet extends BaseTestSheet { wb.close(); } } + + @Test + public void getTabColor() throws IOException { + XSSFWorkbook wb = new XSSFWorkbook(); + try { + XSSFSheet sh = wb.createSheet(); + assertTrue(sh.getCTWorksheet().getSheetPr() == null || !sh.getCTWorksheet().getSheetPr().isSetTabColor()); + assertNull(sh.getTabColor()); + sh.setTabColor(new XSSFColor(IndexedColors.RED)); + XSSFColor expected = new XSSFColor(IndexedColors.RED); + assertEquals(expected, sh.getTabColor()); + } finally { + wb.close(); + } + } + + // Test using an existing workbook saved by Excel + @Test + public void tabColor() throws IOException { + XSSFWorkbook wb = openSampleWorkbook("SheetTabColors.xlsx"); + try { + // non-colored sheets do not have a color + assertNull(wb.getSheet("default").getTabColor()); + + // test indexed-colored sheet + XSSFColor expected = new XSSFColor(IndexedColors.RED); + assertEquals(expected, wb.getSheet("indexedRed").getTabColor()); + + // test regular-colored (non-indexed, ARGB) sheet + expected = new XSSFColor(); + expected.setARGBHex("FF7F2700"); + assertEquals(expected, wb.getSheet("customOrange").getTabColor()); + } finally { + wb.close(); + } + } } diff --git a/test-data/spreadsheet/SheetTabColors.xlsx b/test-data/spreadsheet/SheetTabColors.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..1894f69ea32a99137d34650a34a358ec57bc0ab8 GIT binary patch literal 7008 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 N0gkYDZ_m@ue*mQL4F&)J literal 0 HcmV?d00001