Browse Source

Bug 60898 - XSSFColor's getARGB() method returns a wrong color value when a workbook has a custom indexed color

teach XSSFColor and most things that create instances about indexed colors.

Null is a valid value for IndexedColorMap instances - the existing built-in default colors are used.

Whenever a workbook style is accessible in the call hierarchy its color mappings are passed down now.

Thanks for the unit test in the issue, it now passes.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1796359 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_17_BETA1
Greg Woolsey 7 years ago
parent
commit
c844803b66
29 changed files with 426 additions and 130 deletions
  1. 16
    0
      src/java/org/apache/poi/hssf/usermodel/HSSFExtendedColor.java
  2. 29
    20
      src/java/org/apache/poi/ss/usermodel/ExtendedColor.java
  3. 10
    2
      src/java/org/apache/poi/ss/usermodel/IndexedColors.java
  4. 29
    27
      src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java
  5. 11
    1
      src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java
  6. 65
    0
      src/ooxml/java/org/apache/poi/xssf/usermodel/CustomIndexedColorMap.java
  7. 44
    0
      src/ooxml/java/org/apache/poi/xssf/usermodel/DefaultIndexedColorMap.java
  8. 31
    0
      src/ooxml/java/org/apache/poi/xssf/usermodel/IndexedColorMap.java
  9. 9
    7
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java
  10. 10
    10
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java
  11. 53
    13
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java
  12. 9
    4
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColorScaleFormatting.java
  13. 15
    10
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java
  14. 2
    1
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java
  15. 4
    2
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataBarFormatting.java
  16. 7
    4
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDxfStyleProvider.java
  17. 10
    2
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFont.java
  18. 5
    3
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java
  19. 5
    3
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java
  20. 2
    2
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
  21. 3
    2
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTableStyle.java
  22. 19
    3
      src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellBorder.java
  23. 6
    3
      src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellFill.java
  24. 1
    1
      src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java
  25. 22
    1
      src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColor.java
  26. 1
    1
      src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFont.java
  27. 4
    4
      src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java
  28. 4
    4
      src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFCellFill.java
  29. BIN
      test-data/spreadsheet/customIndexedColors.xlsx

+ 16
- 0
src/java/org/apache/poi/hssf/usermodel/HSSFExtendedColor.java View File

import static org.apache.poi.hssf.record.common.ExtendedColor.TYPE_RGB; import static org.apache.poi.hssf.record.common.ExtendedColor.TYPE_RGB;
import static org.apache.poi.hssf.record.common.ExtendedColor.TYPE_THEMED; import static org.apache.poi.hssf.record.common.ExtendedColor.TYPE_THEMED;


import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.ExtendedColor; import org.apache.poi.ss.usermodel.ExtendedColor;


/** /**
public void setTint(double tint) { public void setTint(double tint) {
color.setTint(tint); color.setTint(tint);
} }
protected byte[] getIndexedRGB() {
if (isIndexed() && getIndex() > 0) {
int indexNum = getIndex();
HSSFColor indexed = HSSFColor.getIndexHash().get(indexNum);
if (indexed != null) {
byte[] rgb = new byte[3];
rgb[0] = (byte) indexed.getTriplet()[0];
rgb[1] = (byte) indexed.getTriplet()[1];
rgb[2] = (byte) indexed.getTriplet()[2];
return rgb;
}
} // else
return null;
}
} }

+ 29
- 20
src/java/org/apache/poi/ss/usermodel/ExtendedColor.java View File



import java.util.Locale; import java.util.Locale;


import org.apache.poi.hssf.util.HSSFColor;

/** /**
* Represents a XSSF-style color (based on either a * Represents a XSSF-style color (based on either a
* {@link org.apache.poi.xssf.usermodel.XSSFColor} or a * {@link org.apache.poi.xssf.usermodel.XSSFColor} or a
* {@link org.apache.poi.hssf.record.common.ExtendedColor} * {@link org.apache.poi.hssf.record.common.ExtendedColor}
*/ */
public abstract class ExtendedColor implements Color { public abstract class ExtendedColor implements Color {

/**
*
* @param clr awt Color to set
*/
protected void setColor(java.awt.Color clr) { protected void setColor(java.awt.Color clr) {
setRGB(new byte[]{(byte)clr.getRed(), (byte)clr.getGreen(), (byte)clr.getBlue()}); setRGB(new byte[]{(byte)clr.getRed(), (byte)clr.getGreen(), (byte)clr.getBlue()});
} }


/** /**
* A boolean value indicating the color is automatic
* @return true if the color is automatic
*/ */
public abstract boolean isAuto(); public abstract boolean isAuto();


/** /**
* A boolean value indicating the color is indexed
* @return true if the color is indexed
*/ */
public abstract boolean isIndexed(); public abstract boolean isIndexed();


/** /**
* A boolean value indicating the color is RGB / ARGB
* @return true if the color is RGB / ARGB
*/ */
public abstract boolean isRGB(); public abstract boolean isRGB();
/** /**
* A boolean value indicating the color is from a Theme
* @return true if the color is from a Theme
*/ */
public abstract boolean isThemed(); public abstract boolean isThemed();
/** /**
* Indexed Color value, if {@link #isIndexed()} is true
* @return Indexed Color index value, if {@link #isIndexed()} is true
*/ */
public abstract short getIndex(); public abstract short getIndex();
/** /**
* Index of Theme color, if {@link #isThemed()} is true
* @return Index of Theme color, if {@link #isThemed()} is true
*/ */
public abstract int getTheme(); public abstract int getTheme();


/** /**
* Standard Red Green Blue ctColor value (RGB).
* @return Standard Red Green Blue ctColor value (RGB) bytes.
* If there was an A (Alpha) value, it will be stripped. * If there was an A (Alpha) value, it will be stripped.
*/ */
public abstract byte[] getRGB(); public abstract byte[] getRGB();

/** /**
* Standard Alpha Red Green Blue ctColor value (ARGB).
* @return Standard Alpha Red Green Blue ctColor value (ARGB) bytes.
*/ */
public abstract byte[] getARGB(); public abstract byte[] getARGB();


/** /**
* RGB or ARGB or null
* @return RGB or ARGB bytes or null
*/ */
protected abstract byte[] getStoredRBG(); protected abstract byte[] getStoredRBG();
/** /**
* Sets the Red Green Blue or Alpha Red Green Blue * Sets the Red Green Blue or Alpha Red Green Blue
* @param rgb bytes
*/ */
public abstract void setRGB(byte[] rgb); public abstract void setRGB(byte[] rgb);


/**
* @return RGB or ARGB bytes, either stored or by index
*/
protected byte[] getRGBOrARGB() { protected byte[] getRGBOrARGB() {
if (isIndexed() && getIndex() > 0) { if (isIndexed() && getIndex() > 0) {
int indexNum = getIndex();
HSSFColor indexed = HSSFColor.getIndexHash().get(indexNum);
if (indexed != null) {
byte[] rgb = new byte[3];
rgb[0] = (byte) indexed.getTriplet()[0];
rgb[1] = (byte) indexed.getTriplet()[1];
rgb[2] = (byte) indexed.getTriplet()[2];
byte[] rgb = getIndexedRGB();
if (rgb != null) {
return rgb; return rgb;
} }
} }
// Grab the colour // Grab the colour
return getStoredRBG(); return getStoredRBG();
} }
/**
* @return index color RGB bytes, if {@link #isIndexed()} == true, null if not indexed or index is invalid
*/
protected abstract byte[] getIndexedRGB();


/** /**
* Standard Red Green Blue ctColor value (RGB) with applied tint.
* @return Standard Red Green Blue ctColor value (RGB) bytes with applied tint.
* Alpha values are ignored. * Alpha values are ignored.
*/ */
public byte[] getRGBWithTint() { public byte[] getRGBWithTint() {
} }


/** /**
* Return the ARGB value in hex format, eg FF00FF00.
* @return the ARGB value in hex string format, eg FF00FF00.
* Works for both regular and indexed colours. * Works for both regular and indexed colours.
*/ */
public String getARGBHex() { public String getARGBHex() {
/** /**
* Sets the ARGB value from hex format, eg FF0077FF. * Sets the ARGB value from hex format, eg FF0077FF.
* Only works for regular (non-indexed) colours * Only works for regular (non-indexed) colours
* @param argb color ARGB hex string
*/ */
public void setARGBHex(String argb) { public void setARGBHex(String argb) {
if (argb.length() == 6 || argb.length() == 8) { if (argb.length() == 6 || argb.length() == 8) {

+ 10
- 2
src/java/org/apache/poi/ss/usermodel/IndexedColors.java View File

*/ */
public enum IndexedColors { public enum IndexedColors {


// 0-7?
// 0-7 duplicates of 8-15 for compatibility (OOXML spec pt.1 sec. 18.8.27)
BLACK1(0),
WHITE1(1),
RED1(2),
BRIGHT_GREEN1(3),
BLUE1(4),
YELLOW1(5),
PINK1(6),
TURQUOISE1(7),
BLACK(8), BLACK(8),
WHITE(9), WHITE(9),
RED(10), RED(10),
CORNFLOWER_BLUE(24), CORNFLOWER_BLUE(24),
MAROON(25), MAROON(25),
LEMON_CHIFFON(26), LEMON_CHIFFON(26),
// 27?
LIGHT_TURQUOISE1(27),
ORCHID(28), ORCHID(28),
CORAL(29), CORAL(29),
ROYAL_BLUE(30), ROYAL_BLUE(30),

+ 29
- 27
src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java View File

import org.apache.poi.ss.usermodel.FontScheme; import org.apache.poi.ss.usermodel.FontScheme;
import org.apache.poi.ss.usermodel.TableStyle; import org.apache.poi.ss.usermodel.TableStyle;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.poi.xssf.usermodel.CustomIndexedColorMap;
import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;
import org.apache.poi.xssf.usermodel.IndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFBuiltinTableStyle; import org.apache.poi.xssf.usermodel.XSSFBuiltinTableStyle;
import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFactory; import org.apache.poi.xssf.usermodel.XSSFFactory;
import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder; import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder;
import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill; import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorders;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellStyleXfs;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellXfs;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxf;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxfs;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFills;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFonts;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTNumFmt;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTNumFmts;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTStylesheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyle;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyles;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.StyleSheetDocument;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;


/** /**
* Table of styles shared across all sheets in a workbook. * Table of styles shared across all sheets in a workbook.


private final List<CTDxf> dxfs = new ArrayList<CTDxf>(); private final List<CTDxf> dxfs = new ArrayList<CTDxf>();
private final Map<String, TableStyle> tableStyles = new HashMap<String, TableStyle>(); private final Map<String, TableStyle> tableStyles = new HashMap<String, TableStyle>();

private IndexedColorMap indexedColors = new DefaultIndexedColorMap();
/** /**
* The first style id available for use as a custom style * The first style id available for use as a custom style
*/ */
public void setTheme(ThemesTable theme) { public void setTheme(ThemesTable theme) {
this.theme = theme; this.theme = theme;


if (theme != null) theme.setColorMap(getIndexedColors());
// Pass the themes table along to things which need to // Pass the themes table along to things which need to
// know about it, but have already been created by now // know about it, but have already been created by now
for(XSSFFont font : fonts) { for(XSSFFont font : fonts) {
public void ensureThemesTable() { public void ensureThemesTable() {
if (theme != null) return; if (theme != null) return;


theme = (ThemesTable)workbook.createRelationship(XSSFRelation.THEME, XSSFFactory.getInstance());
setTheme((ThemesTable)workbook.createRelationship(XSSFRelation.THEME, XSSFFactory.getInstance()));
} }


/** /**
CTStylesheet styleSheet = doc.getStyleSheet(); CTStylesheet styleSheet = doc.getStyleSheet();


// Grab all the different bits we care about // Grab all the different bits we care about
// keep this first, as some constructors below want it
IndexedColorMap customColors = CustomIndexedColorMap.fromColors(styleSheet.getColors());
if (customColors != null) indexedColors = customColors;
CTNumFmts ctfmts = styleSheet.getNumFmts(); CTNumFmts ctfmts = styleSheet.getNumFmts();
if( ctfmts != null){ if( ctfmts != null){
for (CTNumFmt nfmt : ctfmts.getNumFmtArray()) { for (CTNumFmt nfmt : ctfmts.getNumFmtArray()) {
int idx = 0; int idx = 0;
for (CTFont font : ctfonts.getFontArray()) { for (CTFont font : ctfonts.getFontArray()) {
// Create the font and save it. Themes Table supplied later // Create the font and save it. Themes Table supplied later
XSSFFont f = new XSSFFont(font, idx);
XSSFFont f = new XSSFFont(font, idx, indexedColors);
fonts.add(f); fonts.add(f);
idx++; idx++;
} }
CTFills ctfills = styleSheet.getFills(); CTFills ctfills = styleSheet.getFills();
if(ctfills != null){ if(ctfills != null){
for (CTFill fill : ctfills.getFillArray()) { for (CTFill fill : ctfills.getFillArray()) {
fills.add(new XSSFCellFill(fill));
fills.add(new XSSFCellFill(fill, indexedColors));
} }
} }


CTBorders ctborders = styleSheet.getBorders(); CTBorders ctborders = styleSheet.getBorders();
if(ctborders != null) { if(ctborders != null) {
for (CTBorder border : ctborders.getBorderArray()) { for (CTBorder border : ctborders.getBorderArray()) {
borders.add(new XSSFCellBorder(border));
borders.add(new XSSFCellBorder(border, indexedColors));
} }
} }


if (ctTableStyles != null) { if (ctTableStyles != null) {
int idx = 0; int idx = 0;
for (CTTableStyle style : Arrays.asList(ctTableStyles.getTableStyleArray())) { for (CTTableStyle style : Arrays.asList(ctTableStyles.getTableStyleArray())) {
tableStyles.put(style.getName(), new XSSFTableStyle(idx, styleDxfs, style));
tableStyles.put(style.getName(), new XSSFTableStyle(idx, styleDxfs, style, indexedColors));
idx++; idx++;
} }
} }
fonts.add(xssfFont); fonts.add(xssfFont);


CTFill[] ctFill = createDefaultFills(); CTFill[] ctFill = createDefaultFills();
fills.add(new XSSFCellFill(ctFill[0]));
fills.add(new XSSFCellFill(ctFill[1]));
fills.add(new XSSFCellFill(ctFill[0], indexedColors));
fills.add(new XSSFCellFill(ctFill[1], indexedColors));


CTBorder ctBorder = createDefaultBorder(); CTBorder ctBorder = createDefaultBorder();
borders.add(new XSSFCellBorder(ctBorder)); borders.add(new XSSFCellBorder(ctBorder));


private static XSSFFont createDefaultFont() { private static XSSFFont createDefaultFont() {
CTFont ctFont = CTFont.Factory.newInstance(); CTFont ctFont = CTFont.Factory.newInstance();
XSSFFont xssfFont=new XSSFFont(ctFont, 0);
XSSFFont xssfFont=new XSSFFont(ctFont, 0, null);
xssfFont.setFontHeightInPoints(XSSFFont.DEFAULT_FONT_SIZE); xssfFont.setFontHeightInPoints(XSSFFont.DEFAULT_FONT_SIZE);
xssfFont.setColor(XSSFFont.DEFAULT_FONT_COLOR);//setTheme xssfFont.setColor(XSSFFont.DEFAULT_FONT_COLOR);//setTheme
xssfFont.setFontName(XSSFFont.DEFAULT_FONT_NAME); xssfFont.setFontName(XSSFFont.DEFAULT_FONT_NAME);
} }
return null; return null;
} }
/**
* @return default or custom indexed color to RGB mapping
*/
public IndexedColorMap getIndexedColors() {
return indexedColors;
}
} }

+ 11
- 1
src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java View File



import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xssf.usermodel.IndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFColor; import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
public final String name; public final String name;
} }


private IndexedColorMap colorMap;
private ThemeDocument theme; private ThemeDocument theme;


/** /**
this.theme = theme; this.theme = theme;
} }


/**
* called from {@link StylesTable} when setting theme, used to adjust colors if a custom indexed mapping is defined
* @param colorMap
*/
protected void setColorMap(IndexedColorMap colorMap) {
this.colorMap = colorMap;
}
/** /**
* Convert a theme "index" (as used by fonts etc) into a color. * Convert a theme "index" (as used by fonts etc) into a color.
* @param idx A theme "index" * @param idx A theme "index"
} else { } else {
return null; return null;
} }
return new XSSFColor(rgb);
return new XSSFColor(rgb, colorMap);
} }
/** /**

+ 65
- 0
src/ooxml/java/org/apache/poi/xssf/usermodel/CustomIndexedColorMap.java View File

/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.xssf.usermodel;

import java.util.List;

import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColors;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRgbColor;

/**
* custom index color map, i.e. from the styles.xml definition
*/
public class CustomIndexedColorMap implements IndexedColorMap {

private final byte[][] colorIndex;
/**
* @param colors array of RGB triplets indexed by color index
*/
private CustomIndexedColorMap(byte [][] colors) {
this.colorIndex = colors;
}
public byte[] getRGB(int index) {
if (colorIndex == null || index < 0 || index >= colorIndex.length) return null;
return colorIndex[index];
}

/**
* OOXML spec says if this exists it must have all indexes.
* <p/>
* From the OOXML Spec, Part 1, section 18.8.27:
* <p/><i>
* This element contains a sequence of RGB color values that correspond to color indexes (zero-based). When
* using the default indexed color palette, the values are not written out, but instead are implied. When the color
* palette has been modified from default, then the entire color palette is written out.
* </i>
* @param colors CTColors from styles.xml possibly defining a custom color indexing scheme
* @return custom indexed color map or null if none defined in the document
*/
public static CustomIndexedColorMap fromColors(CTColors colors) {
if (colors == null || ! colors.isSetIndexedColors()) return null;

List<CTRgbColor> rgbColorList = colors.getIndexedColors().getRgbColorList();
byte[][] customColorIndex = new byte[rgbColorList.size()][3];
for (int i=0; i < rgbColorList.size(); i++) {
customColorIndex[i] = rgbColorList.get(i).getRgb();
}
return new CustomIndexedColorMap(customColorIndex);
}
}

+ 44
- 0
src/ooxml/java/org/apache/poi/xssf/usermodel/DefaultIndexedColorMap.java View File

/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.xssf.usermodel;

import org.apache.poi.hssf.util.HSSFColor;

/**
* Uses the legacy colors defined in HSSF for index lookups
*/
public class DefaultIndexedColorMap implements IndexedColorMap {

/**
* @see org.apache.poi.xssf.usermodel.IndexedColorMap#getRGB(int)
*/
public byte[] getRGB(int index) {
return getDefaultRGB(index);
}

/**
* @param index
* @return RGB bytes from HSSF default color by index
*/
public static byte[] getDefaultRGB(int index) {
HSSFColor hssfColor = HSSFColor.getIndexHash().get(index);
if (hssfColor == null) return null;
short[] rgbShort = hssfColor.getTriplet();
return new byte[] {(byte) rgbShort[0], (byte) rgbShort[1], (byte) rgbShort[2]};
}

}

+ 31
- 0
src/ooxml/java/org/apache/poi/xssf/usermodel/IndexedColorMap.java View File

/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.xssf.usermodel;

/**
* Interface for color index to RGB mappings.
* May be either the default, built-in mappings
* or custom mappings defined in the document.
*/
public interface IndexedColorMap {

/**
* @param index color index to look up
* @return the RGB array for the index, or null if the index is invalid/undefined
*/
byte[] getRGB(int index);
}

+ 9
- 7
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBorderFormatting.java View File

import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Color; import org.apache.poi.ss.usermodel.Color;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STBorderStyle;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorderPr; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorderPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STBorderStyle;


/** /**
* XSSF high level representation for Border Formatting component * XSSF high level representation for Border Formatting component
* of Conditional Formatting settings * of Conditional Formatting settings
*/ */
public class XSSFBorderFormatting implements BorderFormatting { public class XSSFBorderFormatting implements BorderFormatting {
IndexedColorMap _colorMap;
CTBorder _border; CTBorder _border;


/*package*/ XSSFBorderFormatting(CTBorder border) {
/*package*/ XSSFBorderFormatting(CTBorder border, IndexedColorMap colorMap) {
_border = border; _border = border;
_colorMap = colorMap;
} }


/** /**
if(!_border.isSetBottom()) return null; if(!_border.isSetBottom()) return null;


CTBorderPr pr = _border.getBottom(); CTBorderPr pr = _border.getBottom();
return new XSSFColor(pr.getColor());
return new XSSFColor(pr.getColor(), _colorMap);
} }
@Override @Override
public short getBottomBorderColor() { public short getBottomBorderColor() {
if(!_border.isSetDiagonal()) return null; if(!_border.isSetDiagonal()) return null;


CTBorderPr pr = _border.getDiagonal(); CTBorderPr pr = _border.getDiagonal();
return new XSSFColor(pr.getColor());
return new XSSFColor(pr.getColor(), _colorMap);
} }
@Override @Override
public short getDiagonalBorderColor() { public short getDiagonalBorderColor() {
if(!_border.isSetLeft()) return null; if(!_border.isSetLeft()) return null;


CTBorderPr pr = _border.getLeft(); CTBorderPr pr = _border.getLeft();
return new XSSFColor(pr.getColor());
return new XSSFColor(pr.getColor(), _colorMap);
} }
@Override @Override
public short getLeftBorderColor() { public short getLeftBorderColor() {
if(!_border.isSetRight()) return null; if(!_border.isSetRight()) return null;


CTBorderPr pr = _border.getRight(); CTBorderPr pr = _border.getRight();
return new XSSFColor(pr.getColor());
return new XSSFColor(pr.getColor(), _colorMap);
} }
@Override @Override
public short getRightBorderColor() { public short getRightBorderColor() {
if(!_border.isSetTop()) return null; if(!_border.isSetTop()) return null;


CTBorderPr pr = _border.getTop(); CTBorderPr pr = _border.getTop();
return new XSSFColor(pr.getColor());
return new XSSFColor(pr.getColor(), _colorMap);
} }
@Override @Override
public short getTopBorderColor() { public short getTopBorderColor() {

+ 10
- 10
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java View File

} }


private void addFill(CTFill fill) { private void addFill(CTFill fill) {
int idx = _stylesSource.putFill(new XSSFCellFill(fill));
int idx = _stylesSource.putFill(new XSSFCellFill(fill,_stylesSource.getIndexedColors()));


_cellXf.setFillId(idx); _cellXf.setFillId(idx);
_cellXf.setApplyFill(true); _cellXf.setApplyFill(true);
} }
private void addBorder(CTBorder border) { private void addBorder(CTBorder border) {
int idx = _stylesSource.putBorder(new XSSFCellBorder(border, _theme));
int idx = _stylesSource.putBorder(new XSSFCellBorder(border, _theme,_stylesSource.getIndexedColors()));


_cellXf.setBorderId(idx); _cellXf.setBorderId(idx);
_cellXf.setApplyBorder(true); _cellXf.setApplyBorder(true);
if(border == BorderStyle.NONE) ct.unsetBottom(); if(border == BorderStyle.NONE) ct.unsetBottom();
else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1));


int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme));
int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme, _stylesSource.getIndexedColors()));


_cellXf.setBorderId(idx); _cellXf.setBorderId(idx);
_cellXf.setApplyBorder(true); _cellXf.setApplyBorder(true);
if(border == BorderStyle.NONE) ct.unsetLeft(); if(border == BorderStyle.NONE) ct.unsetLeft();
else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1));


int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme));
int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme, _stylesSource.getIndexedColors()));


_cellXf.setBorderId(idx); _cellXf.setBorderId(idx);
_cellXf.setApplyBorder(true); _cellXf.setApplyBorder(true);
if(border == BorderStyle.NONE) ct.unsetRight(); if(border == BorderStyle.NONE) ct.unsetRight();
else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1));


int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme));
int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme,_stylesSource.getIndexedColors()));


_cellXf.setBorderId(idx); _cellXf.setBorderId(idx);
_cellXf.setApplyBorder(true); _cellXf.setApplyBorder(true);
if(border == BorderStyle.NONE) ct.unsetTop(); if(border == BorderStyle.NONE) ct.unsetTop();
else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1)); else pr.setStyle(STBorderStyle.Enum.forInt(border.getCode() + 1));


int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme));
int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme,_stylesSource.getIndexedColors()));


_cellXf.setBorderId(idx); _cellXf.setBorderId(idx);
_cellXf.setApplyBorder(true); _cellXf.setApplyBorder(true);
if(color != null) pr.setColor(color.getCTColor()); if(color != null) pr.setColor(color.getCTColor());
else pr.unsetColor(); else pr.unsetColor();


int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme));
int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme,_stylesSource.getIndexedColors()));


_cellXf.setBorderId(idx); _cellXf.setBorderId(idx);
_cellXf.setApplyBorder(true); _cellXf.setApplyBorder(true);
if(color != null) pr.setColor(color.getCTColor()); if(color != null) pr.setColor(color.getCTColor());
else pr.unsetColor(); else pr.unsetColor();


int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme));
int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme,_stylesSource.getIndexedColors()));


_cellXf.setBorderId(idx); _cellXf.setBorderId(idx);
_cellXf.setApplyBorder(true); _cellXf.setApplyBorder(true);
if(color != null) pr.setColor(color.getCTColor()); if(color != null) pr.setColor(color.getCTColor());
else pr.unsetColor(); else pr.unsetColor();


int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme));
int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme,_stylesSource.getIndexedColors()));


_cellXf.setBorderId(idx); _cellXf.setBorderId(idx);
_cellXf.setApplyBorder(true); _cellXf.setApplyBorder(true);
if(color != null) pr.setColor(color.getCTColor()); if(color != null) pr.setColor(color.getCTColor());
else pr.unsetColor(); else pr.unsetColor();


int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme));
int idx = _stylesSource.putBorder(new XSSFCellBorder(ct, _theme,_stylesSource.getIndexedColors()));


_cellXf.setBorderId(idx); _cellXf.setBorderId(idx);
_cellXf.setApplyBorder(true); _cellXf.setApplyBorder(true);

+ 53
- 13
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java View File

import org.apache.poi.ss.usermodel.ExtendedColor; import org.apache.poi.ss.usermodel.ExtendedColor;
import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.poi.util.Removal;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;


/** /**
*/ */
public class XSSFColor extends ExtendedColor { public class XSSFColor extends ExtendedColor {
private final CTColor ctColor; private final CTColor ctColor;
private final IndexedColorMap indexedColorMap;


/** /**
* Create an instance of XSSFColor from the supplied XML bean
* Create an instance of XSSFColor from the supplied XML bean, with default color indexes
* @param color
* @deprecated 3.17 beta 1 - pass the workbook styles indexed color map, if any
*/ */
@Deprecated
@Removal(version="3.19")
public XSSFColor(CTColor color) { public XSSFColor(CTColor color) {
this(color, new DefaultIndexedColorMap());
}
/**
* Create an instance of XSSFColor from the supplied XML bean, with the given color indexes
* @param color
* @param map
*/
public XSSFColor(CTColor color, IndexedColorMap map) {
this.ctColor = color; this.ctColor = color;
this.indexedColorMap = map;
} }


/** /**
* Create an new instance of XSSFColor
* Create an new instance of XSSFColor, without knowledge of any custom indexed colors.
* This is OK for just transiently setting indexes, etc. but is discouraged in read/get uses
*/ */
public XSSFColor() { public XSSFColor() {
this.ctColor = CTColor.Factory.newInstance();
this(CTColor.Factory.newInstance(), null);
} }


/**
* TEST ONLY - does not know about custom indexed colors
* @param clr awt Color
*/
public XSSFColor(java.awt.Color clr) { public XSSFColor(java.awt.Color clr) {
this(); this();
setColor(clr); setColor(clr);
} }


public XSSFColor(byte[] rgb) {
this();
/**
*
* @param rgb bytes
* @param colorMap
*/
public XSSFColor(byte[] rgb, IndexedColorMap colorMap) {
this(CTColor.Factory.newInstance(), colorMap);
ctColor.setRgb(rgb); ctColor.setRgb(rgb);
} }
public XSSFColor(IndexedColors indexedColor) {
this();
/**
* @param indexedColor color index (Enum named for default colors)
* @param colorMap
*/
public XSSFColor(IndexedColors indexedColor, IndexedColorMap colorMap) {
this(CTColor.Factory.newInstance(), colorMap);
ctColor.setIndexed(indexedColor.index); ctColor.setIndexed(indexedColor.index);
} }


return ctColor.getAuto(); return ctColor.getAuto();
} }
/** /**
* A boolean value indicating the ctColor is automatic and system ctColor dependent.
* @param auto true if the ctColor is automatic and system ctColor dependent.
*/ */
public void setAuto(boolean auto) { public void setAuto(boolean auto) {
ctColor.setAuto(auto); ctColor.setAuto(auto);
} }


/** /**
* A boolean value indicating the ctColor is RGB or ARGB based
* @return true if the ctColor is RGB or ARGB based
*/ */
@Override @Override
public boolean isRGB() { public boolean isRGB() {
} }


/** /**
* A boolean value indicating the ctColor is Theme based
* @return true if the ctColor is Theme based
*/ */
@Override @Override
public boolean isThemed() { public boolean isThemed() {
} }
/** /**
* A boolean value indicating if the ctColor has a alpha or not
* @return true if the ctColor has a alpha
*/ */
public boolean hasAlpha() { public boolean hasAlpha() {
if (! ctColor.isSetRgb()) { if (! ctColor.isSetRgb()) {
} }


/** /**
* A boolean value indicating if the ctColor has a tint or not
* @return true if the ctColor has a tint
*/ */
public boolean hasTint() { public boolean hasTint() {
if (!ctColor.isSetTint()) { if (!ctColor.isSetTint()) {
return (short)ctColor.getIndexed(); return (short)ctColor.getIndexed();
} }
/** /**
* Indexed ctColor value. Only used for backwards compatibility. References a ctColor in indexedColors.
* @return Indexed ctColor value. Only used for backwards compatibility. References a ctColor in indexedColors.
*/ */
public short getIndexed() { public short getIndexed() {
return getIndex(); return getIndex();


/** /**
* Indexed ctColor value. Only used for backwards compatibility. References a ctColor in indexedColors. * Indexed ctColor value. Only used for backwards compatibility. References a ctColor in indexedColors.
* @param indexed color index
*/ */
public void setIndexed(int indexed) { public void setIndexed(int indexed) {
ctColor.setIndexed(indexed); ctColor.setIndexed(indexed);
return ctColor.getRgb(); return ctColor.getRgb();
} }


protected byte[] getIndexedRGB() {
if (isIndexed()) {
if (indexedColorMap != null) return indexedColorMap.getRGB(getIndex());
return DefaultIndexedColorMap.getDefaultRGB(getIndex());
}
return null;
}
/** /**
* Standard Alpha Red Green Blue ctColor value (ARGB). * Standard Alpha Red Green Blue ctColor value (ARGB).
*/ */
/** /**
* Index into the <clrScheme> collection, referencing a particular <sysClr> or * Index into the <clrScheme> collection, referencing a particular <sysClr> or
* <srgbClr> value expressed in the Theme part. * <srgbClr> value expressed in the Theme part.
* @param theme index
*/ */
public void setTheme(int theme) { public void setTheme(int theme) {
ctColor.setTheme(theme); ctColor.setTheme(theme);

+ 9
- 4
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColorScaleFormatting.java View File

* component of Conditional Formatting settings * component of Conditional Formatting settings
*/ */
public class XSSFColorScaleFormatting implements ColorScaleFormatting { public class XSSFColorScaleFormatting implements ColorScaleFormatting {
CTColorScale _scale;
private CTColorScale _scale;
private IndexedColorMap _indexedColorMap;


/*package*/ XSSFColorScaleFormatting(CTColorScale scale){
/*package*/ XSSFColorScaleFormatting(CTColorScale scale, IndexedColorMap colorMap){
_scale = scale; _scale = scale;
_indexedColorMap = colorMap;
} }
public int getNumControlPoints() { public int getNumControlPoints() {
CTColor[] ctcols = _scale.getColorArray(); CTColor[] ctcols = _scale.getColorArray();
XSSFColor[] c = new XSSFColor[ctcols.length]; XSSFColor[] c = new XSSFColor[ctcols.length];
for (int i=0; i<ctcols.length; i++) { for (int i=0; i<ctcols.length; i++) {
c[i] = new XSSFColor(ctcols[i]);
c[i] = new XSSFColor(ctcols[i], _indexedColorMap);
} }
return c; return c;
} }
_scale.setCfvoArray(cfvos); _scale.setCfvoArray(cfvos);
} }
/**
* @return color from scale
*/
public XSSFColor createColor() { public XSSFColor createColor() {
return new XSSFColor(_scale.addNewColor());
return new XSSFColor(_scale.addNewColor(), _indexedColorMap);
} }
public XSSFConditionalFormattingThreshold createThreshold() { public XSSFConditionalFormattingThreshold createThreshold() {
return new XSSFConditionalFormattingThreshold(_scale.addNewCfvo()); return new XSSFConditionalFormattingThreshold(_scale.addNewCfvo());

+ 15
- 10
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java View File

border = dxf.getBorder(); border = dxf.getBorder();
} }


return new XSSFBorderFormatting(border);
return new XSSFBorderFormatting(border, _sh.getWorkbook().getStylesSource().getIndexedColors());
} }


/** /**
CTDxf dxf = getDxf(false); CTDxf dxf = getDxf(false);
if(dxf == null || !dxf.isSetBorder()) return null; if(dxf == null || !dxf.isSetBorder()) return null;


return new XSSFBorderFormatting(dxf.getBorder());
return new XSSFBorderFormatting(dxf.getBorder(), _sh.getWorkbook().getStylesSource().getIndexedColors());
} }


/** /**
font = dxf.getFont(); font = dxf.getFont();
} }


return new XSSFFontFormatting(font);
return new XSSFFontFormatting(font, _sh.getWorkbook().getStylesSource().getIndexedColors());
} }


/** /**
CTDxf dxf = getDxf(false); CTDxf dxf = getDxf(false);
if(dxf == null || !dxf.isSetFont()) return null; if(dxf == null || !dxf.isSetFont()) return null;


return new XSSFFontFormatting(dxf.getFont());
return new XSSFFontFormatting(dxf.getFont(), _sh.getWorkbook().getStylesSource().getIndexedColors());
} }


/** /**
fill = dxf.getFill(); fill = dxf.getFill();
} }


return new XSSFPatternFormatting(fill);
return new XSSFPatternFormatting(fill, _sh.getWorkbook().getStylesSource().getIndexedColors());
} }


/** /**
CTDxf dxf = getDxf(false); CTDxf dxf = getDxf(false);
if(dxf == null || !dxf.isSetFill()) return null; if(dxf == null || !dxf.isSetFill()) return null;


return new XSSFPatternFormatting(dxf.getFill());
return new XSSFPatternFormatting(dxf.getFill(), _sh.getWorkbook().getStylesSource().getIndexedColors());
} }
/**
*
* @param color
* @return data bar formatting
*/
public XSSFDataBarFormatting createDataBarFormatting(XSSFColor color) { public XSSFDataBarFormatting createDataBarFormatting(XSSFColor color) {
// Is it already there? // Is it already there?
if (_cfRule.isSetDataBar() && _cfRule.getType() == STCfType.DATA_BAR) if (_cfRule.isSetDataBar() && _cfRule.getType() == STCfType.DATA_BAR)
max.setType(STCfvoType.Enum.forString(RangeType.MAX.name)); max.setType(STCfvoType.Enum.forString(RangeType.MAX.name));
// Wrap and return // Wrap and return
return new XSSFDataBarFormatting(bar);
return new XSSFDataBarFormatting(bar, _sh.getWorkbook().getStylesSource().getIndexedColors());
} }
public XSSFDataBarFormatting getDataBarFormatting() { public XSSFDataBarFormatting getDataBarFormatting() {
if (_cfRule.isSetDataBar()) { if (_cfRule.isSetDataBar()) {
CTDataBar bar = _cfRule.getDataBar(); CTDataBar bar = _cfRule.getDataBar();
return new XSSFDataBarFormatting(bar);
return new XSSFDataBarFormatting(bar, _sh.getWorkbook().getStylesSource().getIndexedColors());
} else { } else {
return null; return null;
} }
} }
// Wrap and return // Wrap and return
return new XSSFColorScaleFormatting(scale);
return new XSSFColorScaleFormatting(scale, _sh.getWorkbook().getStylesSource().getIndexedColors());
} }
public XSSFColorScaleFormatting getColorScaleFormatting() { public XSSFColorScaleFormatting getColorScaleFormatting() {
if (_cfRule.isSetColorScale()) { if (_cfRule.isSetColorScale()) {
CTColorScale scale = _cfRule.getColorScale(); CTColorScale scale = _cfRule.getColorScale();
return new XSSFColorScaleFormatting(scale);
return new XSSFColorScaleFormatting(scale, _sh.getWorkbook().getStylesSource().getIndexedColors());
} else { } else {
return null; return null;
} }

+ 2
- 1
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java View File

import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.poi.util.Removal; import org.apache.poi.util.Removal;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;


public class XSSFCreationHelper implements CreationHelper { public class XSSFCreationHelper implements CreationHelper {
private final XSSFWorkbook workbook; private final XSSFWorkbook workbook;


@Override @Override
public XSSFColor createExtendedColor() { public XSSFColor createExtendedColor() {
return new XSSFColor();
return new XSSFColor(CTColor.Factory.newInstance(), workbook.getStylesSource().getIndexedColors());
} }


/** /**

+ 4
- 2
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDataBarFormatting.java View File

* component of Conditional Formatting settings * component of Conditional Formatting settings
*/ */
public class XSSFDataBarFormatting implements DataBarFormatting { public class XSSFDataBarFormatting implements DataBarFormatting {
IndexedColorMap _colorMap;
CTDataBar _databar; CTDataBar _databar;


/*package*/ XSSFDataBarFormatting(CTDataBar databar){
/*package*/ XSSFDataBarFormatting(CTDataBar databar, IndexedColorMap colorMap){
_databar = databar; _databar = databar;
_colorMap = colorMap;
} }


public boolean isIconOnly() { public boolean isIconOnly() {
} }


public XSSFColor getColor() { public XSSFColor getColor() {
return new XSSFColor(_databar.getColor());
return new XSSFColor(_databar.getColor(), _colorMap);
} }
public void setColor(Color color) { public void setColor(Color color) {
_databar.setColor( ((XSSFColor)color).getCTColor() ); _databar.setColor( ((XSSFColor)color).getCTColor() );

+ 7
- 4
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDxfStyleProvider.java View File

*/ */
public class XSSFDxfStyleProvider implements DifferentialStyleProvider { public class XSSFDxfStyleProvider implements DifferentialStyleProvider {
private final IndexedColorMap colorMap;
private final BorderFormatting border; private final BorderFormatting border;
private final FontFormatting font; private final FontFormatting font;
private final ExcelNumberFormat number; private final ExcelNumberFormat number;
/** /**
* @param dxf * @param dxf
* @param stripeSize 0 for non-stripe styles, > 1 for stripes * @param stripeSize 0 for non-stripe styles, > 1 for stripes
* @param colorMap
*/ */
public XSSFDxfStyleProvider(CTDxf dxf, int stripeSize) {
public XSSFDxfStyleProvider(CTDxf dxf, int stripeSize, IndexedColorMap colorMap) {
this.stripeSize = stripeSize; this.stripeSize = stripeSize;
this.colorMap = colorMap;
if (dxf == null) { if (dxf == null) {
border = null; border = null;
font = null; font = null;
number = null; number = null;
fill = null; fill = null;
} else { } else {
border = dxf.isSetBorder() ? new XSSFBorderFormatting(dxf.getBorder()) : null;
font = dxf.isSetFont() ? new XSSFFontFormatting(dxf.getFont()) : null;
border = dxf.isSetBorder() ? new XSSFBorderFormatting(dxf.getBorder(), colorMap) : null;
font = dxf.isSetFont() ? new XSSFFontFormatting(dxf.getFont(), colorMap) : null;
if (dxf.isSetNumFmt()) { if (dxf.isSetNumFmt()) {
CTNumFmt numFmt = dxf.getNumFmt(); CTNumFmt numFmt = dxf.getNumFmt();
number = new ExcelNumberFormat((int) numFmt.getNumFmtId(), numFmt.getFormatCode()); number = new ExcelNumberFormat((int) numFmt.getNumFmtId(), numFmt.getFormatCode());
} else { } else {
number = null; number = null;
} }
fill = dxf.isSetFill() ? new XSSFPatternFormatting(dxf.getFill()) : null;
fill = dxf.isSetFill() ? new XSSFPatternFormatting(dxf.getFill(), colorMap) : null;
} }
} }



+ 10
- 2
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFont.java View File

*/ */
public static final short DEFAULT_FONT_COLOR = IndexedColors.BLACK.getIndex(); public static final short DEFAULT_FONT_COLOR = IndexedColors.BLACK.getIndex();


private IndexedColorMap _indexedColorMap;
private ThemesTable _themes; private ThemesTable _themes;
private CTFont _ctFont; private CTFont _ctFont;
private short _index; private short _index;
_index = 0; _index = 0;
} }


public XSSFFont(CTFont font, int index) {
/**
* Called from parsing styles.xml
* @param font CTFont
* @param index font index
* @param colorMap for default or custom indexed colors
*/
public XSSFFont(CTFont font, int index, IndexedColorMap colorMap) {
_ctFont = font; _ctFont = font;
_index = (short)index; _index = (short)index;
_indexedColorMap = colorMap;
} }


/** /**
public XSSFColor getXSSFColor() { public XSSFColor getXSSFColor() {
CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0); CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0);
if(ctColor != null) { if(ctColor != null) {
XSSFColor color = new XSSFColor(ctColor);
XSSFColor color = new XSSFColor(ctColor, _indexedColorMap);
if(_themes != null) { if(_themes != null) {
_themes.inheritFromThemeAsRequired(color); _themes.inheritFromThemeAsRequired(color);
} }

+ 5
- 3
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFontFormatting.java View File

* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public class XSSFFontFormatting implements FontFormatting { public class XSSFFontFormatting implements FontFormatting {
CTFont _font;
private IndexedColorMap _colorMap;
private CTFont _font;


/*package*/ XSSFFontFormatting(CTFont font){
/*package*/ XSSFFontFormatting(CTFont font, IndexedColorMap colorMap) {
_font = font; _font = font;
_colorMap = colorMap;
} }


/** /**
public XSSFColor getFontColor() { public XSSFColor getFontColor() {
if(_font.sizeOfColorArray() == 0) return null; if(_font.sizeOfColorArray() == 0) return null;


return new XSSFColor(_font.getColorArray(0));
return new XSSFColor(_font.getColorArray(0), _colorMap);
} }


@Override @Override

+ 5
- 3
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPatternFormatting.java View File

* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public class XSSFPatternFormatting implements PatternFormatting { public class XSSFPatternFormatting implements PatternFormatting {
IndexedColorMap _colorMap;
CTFill _fill; CTFill _fill;


XSSFPatternFormatting(CTFill fill){
XSSFPatternFormatting(CTFill fill, IndexedColorMap colorMap) {
_fill = fill; _fill = fill;
_colorMap = colorMap;
} }


public XSSFColor getFillBackgroundColorColor() { public XSSFColor getFillBackgroundColorColor() {
if(!_fill.isSetPatternFill()) return null; if(!_fill.isSetPatternFill()) return null;
return new XSSFColor(_fill.getPatternFill().getBgColor());
return new XSSFColor(_fill.getPatternFill().getBgColor(), _colorMap);
} }
public XSSFColor getFillForegroundColorColor() { public XSSFColor getFillForegroundColorColor() {
if(!_fill.isSetPatternFill() || ! _fill.getPatternFill().isSetFgColor()) if(!_fill.isSetPatternFill() || ! _fill.getPatternFill().isSetFgColor())
return null; return null;
return new XSSFColor(_fill.getPatternFill().getFgColor());
return new XSSFColor(_fill.getPatternFill().getFgColor(), _colorMap);
} }


public short getFillPattern() { public short getFillPattern() {

+ 2
- 2
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java View File

if (!pr.isSetTabColor()) { if (!pr.isSetTabColor()) {
return null; return null;
} }
return new XSSFColor(pr.getTabColor());
return new XSSFColor(pr.getTabColor(), getWorkbook().getStylesSource().getIndexedColors());
} }


/** /**
@Removal(version="3.17") @Removal(version="3.17")
public void setTabColor(int colorIndex) { public void setTabColor(int colorIndex) {
IndexedColors indexedColor = IndexedColors.fromInt(colorIndex); IndexedColors indexedColor = IndexedColors.fromInt(colorIndex);
XSSFColor color = new XSSFColor(indexedColor);
XSSFColor color = new XSSFColor(indexedColor, getWorkbook().getStylesSource().getIndexedColors());
setTabColor(color); setTabColor(color);
} }

+ 3
- 2
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTableStyle.java View File

* @param index style definition index or built-in ordinal depending on use * @param index style definition index or built-in ordinal depending on use
* @param dxfs * @param dxfs
* @param tableStyle * @param tableStyle
* @param colorMap indexed color map - default or custom
* @see TableStyle#getIndex() * @see TableStyle#getIndex()
*/ */
public XSSFTableStyle(int index, CTDxfs dxfs, CTTableStyle tableStyle) {
public XSSFTableStyle(int index, CTDxfs dxfs, CTTableStyle tableStyle, IndexedColorMap colorMap) {
this.name = tableStyle.getName(); this.name = tableStyle.getName();
this.index = index; this.index = index;
for (CTTableStyleElement element : tableStyle.getTableStyleElementList()) { for (CTTableStyleElement element : tableStyle.getTableStyleElementList()) {
} }
int stripeSize = 0; int stripeSize = 0;
if (element.isSetSize()) stripeSize = (int) element.getSize(); if (element.isSetSize()) stripeSize = (int) element.getSize();
if (dxf != null) dstyle = new XSSFDxfStyleProvider(dxf, stripeSize);
if (dxf != null) dstyle = new XSSFDxfStyleProvider(dxf, stripeSize, colorMap);
} }
elementMap.put(type, dstyle); elementMap.put(type, dstyle);
} }

+ 19
- 3
src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellBorder.java View File



import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.xssf.model.ThemesTable; import org.apache.poi.xssf.model.ThemesTable;
import org.apache.poi.xssf.usermodel.IndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFColor; import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder;
* Color is optional. * Color is optional.
*/ */
public class XSSFCellBorder { public class XSSFCellBorder {
private IndexedColorMap _indexedColorMap;
private ThemesTable _theme; private ThemesTable _theme;
private CTBorder border; private CTBorder border;


/** /**
* Creates a Cell Border from the supplied XML definition * Creates a Cell Border from the supplied XML definition
* @param border
* @param theme
* @param colorMap
*/ */
public XSSFCellBorder(CTBorder border, ThemesTable theme) {
this(border);
public XSSFCellBorder(CTBorder border, ThemesTable theme, IndexedColorMap colorMap) {
this(border, colorMap);
this._theme = theme; this._theme = theme;
} }


/** /**
* Creates a Cell Border from the supplied XML definition * Creates a Cell Border from the supplied XML definition
* @param border
*/ */
public XSSFCellBorder(CTBorder border) { public XSSFCellBorder(CTBorder border) {
this(border, null);
}
/**
*
* @param border
* @param colorMap
*/
public XSSFCellBorder(CTBorder border, IndexedColorMap colorMap) {
this.border = border; this.border = border;
this._indexedColorMap = colorMap;
} }


/** /**
CTBorderPr borderPr = getBorder(side); CTBorderPr borderPr = getBorder(side);
if(borderPr != null && borderPr.isSetColor()) { if(borderPr != null && borderPr.isSetColor()) {
XSSFColor clr = new XSSFColor(borderPr.getColor());
XSSFColor clr = new XSSFColor(borderPr.getColor(), _indexedColorMap);
if(_theme != null) { if(_theme != null) {
_theme.inheritFromThemeAsRequired(clr); _theme.inheritFromThemeAsRequired(clr);
} }

+ 6
- 3
src/ooxml/java/org/apache/poi/xssf/usermodel/extensions/XSSFCellFill.java View File

import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPatternFill; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPatternFill;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType;
import org.apache.poi.xssf.usermodel.IndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFColor; import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;


*/ */
public final class XSSFCellFill { public final class XSSFCellFill {


private IndexedColorMap _indexedColorMap;
private CTFill _fill; private CTFill _fill;


/** /**
* *
* @param fill - fill * @param fill - fill
*/ */
public XSSFCellFill(CTFill fill) {
public XSSFCellFill(CTFill fill, IndexedColorMap colorMap) {
_fill = fill; _fill = fill;
_indexedColorMap = colorMap;
} }


/** /**
if (ptrn == null) return null; if (ptrn == null) return null;


CTColor ctColor = ptrn.getBgColor(); CTColor ctColor = ptrn.getBgColor();
return ctColor == null ? null : new XSSFColor(ctColor);
return ctColor == null ? null : new XSSFColor(ctColor, _indexedColorMap);
} }


/** /**
if (ptrn == null) return null; if (ptrn == null) return null;


CTColor ctColor = ptrn.getFgColor(); CTColor ctColor = ptrn.getFgColor();
return ctColor == null ? null : new XSSFColor(ctColor);
return ctColor == null ? null : new XSSFColor(ctColor, _indexedColorMap);
} }


/** /**

+ 1
- 1
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java View File

assertEquals(1, stylesTable.putBorder(borderB)); assertEquals(1, stylesTable.putBorder(borderB));


ctFill = CTFill.Factory.newInstance(); ctFill = CTFill.Factory.newInstance();
XSSFCellFill fill = new XSSFCellFill(ctFill);
XSSFCellFill fill = new XSSFCellFill(ctFill, null);
long fillId = stylesTable.putFill(fill); long fillId = stylesTable.putFill(fill);
assertEquals(2, fillId); assertEquals(2, fillId);



+ 22
- 1
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColor.java View File



package org.apache.poi.xssf.usermodel; package org.apache.poi.xssf.usermodel;


import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;


import java.io.IOException; import java.io.IOException;


import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.XSSFTestDataSamples;
import org.junit.Test; import org.junit.Test;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColors;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRgbColor;


public final class TestXSSFColor { public final class TestXSSFColor {
wb.close(); wb.close();
} }
@Test
public void testCustomIndexedColour() throws Exception {
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("customIndexedColors.xlsx");
XSSFCell cell = wb.getSheetAt(1).getRow(0).getCell(0);
XSSFColor color = cell.getCellStyle().getFillForegroundColorColor();
CTColors ctColors = wb.getStylesSource().getCTStylesheet().getColors();

CTRgbColor ctRgbColor = ctColors.getIndexedColors()
.getRgbColorList()
.get(color.getIndex());

String hexRgb = ctRgbColor.getDomNode().getAttributes().getNamedItem("rgb").getNodeValue();

assertEquals(hexRgb, color.getARGBHex());
}
} }

+ 1
- 1
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFont.java View File

byte[] bytes = Integer.toHexString(0xF1F1F1).getBytes(LocaleUtil.CHARSET_1252); byte[] bytes = Integer.toHexString(0xF1F1F1).getBytes(LocaleUtil.CHARSET_1252);
color.setRgb(bytes); color.setRgb(bytes);
XSSFColor newColor=new XSSFColor(color);
XSSFColor newColor=new XSSFColor(color, null);
xssfFont.setColor(newColor); xssfFont.setColor(newColor);
assertEquals(ctFont.getColorArray(0).getRgb()[2],newColor.getRGB()[2]); assertEquals(ctFont.getColorArray(0).getRgb()[2],newColor.getRGB()[2]);

+ 4
- 4
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java View File

try { try {
XSSFSheet sh = wb.createSheet(); XSSFSheet sh = wb.createSheet();
assertTrue(sh.getCTWorksheet().getSheetPr() == null || !sh.getCTWorksheet().getSheetPr().isSetTabColor()); assertTrue(sh.getCTWorksheet().getSheetPr() == null || !sh.getCTWorksheet().getSheetPr().isSetTabColor());
sh.setTabColor(new XSSFColor(IndexedColors.RED));
sh.setTabColor(new XSSFColor(IndexedColors.RED, null));
assertTrue(sh.getCTWorksheet().getSheetPr().isSetTabColor()); assertTrue(sh.getCTWorksheet().getSheetPr().isSetTabColor());
assertEquals(IndexedColors.RED.index, assertEquals(IndexedColors.RED.index,
sh.getCTWorksheet().getSheetPr().getTabColor().getIndexed()); sh.getCTWorksheet().getSheetPr().getTabColor().getIndexed());
XSSFSheet sh = wb.createSheet(); XSSFSheet sh = wb.createSheet();
assertTrue(sh.getCTWorksheet().getSheetPr() == null || !sh.getCTWorksheet().getSheetPr().isSetTabColor()); assertTrue(sh.getCTWorksheet().getSheetPr() == null || !sh.getCTWorksheet().getSheetPr().isSetTabColor());
assertNull(sh.getTabColor()); assertNull(sh.getTabColor());
sh.setTabColor(new XSSFColor(IndexedColors.RED));
XSSFColor expected = new XSSFColor(IndexedColors.RED);
sh.setTabColor(new XSSFColor(IndexedColors.RED, null));
XSSFColor expected = new XSSFColor(IndexedColors.RED, null);
assertEquals(expected, sh.getTabColor()); assertEquals(expected, sh.getTabColor());
} finally { } finally {
wb.close(); wb.close();
assertNull(wb.getSheet("default").getTabColor()); assertNull(wb.getSheet("default").getTabColor());
// test indexed-colored sheet // test indexed-colored sheet
XSSFColor expected = new XSSFColor(IndexedColors.RED);
XSSFColor expected = new XSSFColor(IndexedColors.RED, null);
assertEquals(expected, wb.getSheet("indexedRed").getTabColor()); assertEquals(expected, wb.getSheet("indexedRed").getTabColor());
// test regular-colored (non-indexed, ARGB) sheet // test regular-colored (non-indexed, ARGB) sheet

+ 4
- 4
src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFCellFill.java View File

@Test @Test
public void testGetFillBackgroundColor() { public void testGetFillBackgroundColor() {
CTFill ctFill = CTFill.Factory.newInstance(); CTFill ctFill = CTFill.Factory.newInstance();
XSSFCellFill cellFill = new XSSFCellFill(ctFill);
XSSFCellFill cellFill = new XSSFCellFill(ctFill, null);
CTPatternFill ctPatternFill = ctFill.addNewPatternFill(); CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
CTColor bgColor = ctPatternFill.addNewBgColor(); CTColor bgColor = ctPatternFill.addNewBgColor();
assertNotNull(cellFill.getFillBackgroundColor()); assertNotNull(cellFill.getFillBackgroundColor());
@Test @Test
public void testGetFillForegroundColor() { public void testGetFillForegroundColor() {
CTFill ctFill = CTFill.Factory.newInstance(); CTFill ctFill = CTFill.Factory.newInstance();
XSSFCellFill cellFill = new XSSFCellFill(ctFill);
XSSFCellFill cellFill = new XSSFCellFill(ctFill, null);
CTPatternFill ctPatternFill = ctFill.addNewPatternFill(); CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
CTColor fgColor = ctPatternFill.addNewFgColor(); CTColor fgColor = ctPatternFill.addNewFgColor();
assertNotNull(cellFill.getFillForegroundColor()); assertNotNull(cellFill.getFillForegroundColor());
@Test @Test
public void testGetSetPatternType() { public void testGetSetPatternType() {
CTFill ctFill = CTFill.Factory.newInstance(); CTFill ctFill = CTFill.Factory.newInstance();
XSSFCellFill cellFill = new XSSFCellFill(ctFill);
XSSFCellFill cellFill = new XSSFCellFill(ctFill, null);
CTPatternFill ctPatternFill = ctFill.addNewPatternFill(); CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
ctPatternFill.setPatternType(STPatternType.SOLID); ctPatternFill.setPatternType(STPatternType.SOLID);
assertEquals(FillPatternType.SOLID_FOREGROUND.ordinal(), cellFill.getPatternType().intValue()-1); assertEquals(FillPatternType.SOLID_FOREGROUND.ordinal(), cellFill.getPatternType().intValue()-1);
@Test @Test
public void testGetNotModifies() { public void testGetNotModifies() {
CTFill ctFill = CTFill.Factory.newInstance(); CTFill ctFill = CTFill.Factory.newInstance();
XSSFCellFill cellFill = new XSSFCellFill(ctFill);
XSSFCellFill cellFill = new XSSFCellFill(ctFill, null);
CTPatternFill ctPatternFill = ctFill.addNewPatternFill(); CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
ctPatternFill.setPatternType(STPatternType.DARK_DOWN); ctPatternFill.setPatternType(STPatternType.DARK_DOWN);
assertEquals(8, cellFill.getPatternType().intValue()); assertEquals(8, cellFill.getPatternType().intValue());

BIN
test-data/spreadsheet/customIndexedColors.xlsx View File


Loading…
Cancel
Save