Bug 51222 - XSSFColor.getARGBHex() returns wrong color for Excel 2007 xlsx file

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1621393 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2014-08-29 22:14:55 +00:00
parent 67fcf46d4c
commit 0cbbbfe5d5
6 changed files with 265 additions and 184 deletions

View File

@ -23,20 +23,22 @@ import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
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.apache.xmlbeans.XmlObject; import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme; import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme;
import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument; import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
/** /**
* Class that represents theme of XLSX document. The theme includes specific * Class that represents theme of XLSX document. The theme includes specific
* colors and fonts. * colors and fonts.
*
* @author Petr Udalau(Petr.Udalau at exigenservices.com) - theme colors
*/ */
public class ThemesTable extends POIXMLDocumentPart { public class ThemesTable extends POIXMLDocumentPart {
private ThemeDocument theme; private ThemeDocument theme;
/**
* Construct a ThemesTable.
* @param part A PackagePart.
* @param rel A PackageRelationship.
*/
public ThemesTable(PackagePart part, PackageRelationship rel) throws IOException { public ThemesTable(PackagePart part, PackageRelationship rel) throws IOException {
super(part, rel); super(part, rel);
@ -47,38 +49,56 @@ public class ThemesTable extends POIXMLDocumentPart {
} }
} }
/**
* Construct a ThemesTable from an existing ThemeDocument.
* @param theme A ThemeDocument.
*/
public ThemesTable(ThemeDocument theme) { public ThemesTable(ThemeDocument theme) {
this.theme = theme; this.theme = theme;
} }
/**
* Convert a theme "index" into a color.
* @param idx A theme "index"
* @return The mapped XSSFColor, or null if not mapped.
*/
public XSSFColor getThemeColor(int idx) { public XSSFColor getThemeColor(int idx) {
// Theme color references are NOT positional indices into the color scheme,
// i.e. these keys are NOT the same as the order in which theme colors appear
// in theme1.xml. They are keys to a mapped color.
CTColorScheme colorScheme = theme.getTheme().getThemeElements().getClrScheme(); CTColorScheme colorScheme = theme.getTheme().getThemeElements().getClrScheme();
CTColor ctColor = null; CTColor ctColor;
int cnt = 0; switch (idx) {
for (XmlObject obj : colorScheme.selectPath("./*")) { case 0: ctColor = colorScheme.getLt1(); break;
if (obj instanceof org.openxmlformats.schemas.drawingml.x2006.main.CTColor) { case 1: ctColor = colorScheme.getDk1(); break;
if (cnt == idx) { case 2: ctColor = colorScheme.getLt2(); break;
ctColor = (org.openxmlformats.schemas.drawingml.x2006.main.CTColor) obj; case 3: ctColor = colorScheme.getDk2(); break;
case 4: ctColor = colorScheme.getAccent1(); break;
byte[] rgb = null; case 5: ctColor = colorScheme.getAccent2(); break;
if (ctColor.getSrgbClr() != null) { case 6: ctColor = colorScheme.getAccent3(); break;
// Colour is a regular one case 7: ctColor = colorScheme.getAccent4(); break;
rgb = ctColor.getSrgbClr().getVal(); case 8: ctColor = colorScheme.getAccent5(); break;
} else if (ctColor.getSysClr() != null) { case 9: ctColor = colorScheme.getAccent6(); break;
// Colour is a tint of white or black case 10: ctColor = colorScheme.getHlink(); break;
rgb = ctColor.getSysClr().getLastClr(); case 11: ctColor = colorScheme.getFolHlink(); break;
} default: return null;
return new XSSFColor(rgb);
}
cnt++;
}
} }
return null;
byte[] rgb = null;
if (ctColor.isSetSrgbClr()) {
// Color is a regular one
rgb = ctColor.getSrgbClr().getVal();
} else if (ctColor.isSetSysClr()) {
// Color is a tint of white or black
rgb = ctColor.getSysClr().getLastClr();
} else {
return null;
}
return new XSSFColor(rgb);
} }
/** /**
* If the colour is based on a theme, then inherit * If the colour is based on a theme, then inherit
* information (currently just colours) from it as * information (currently just colours) from it as
* required. * required.
*/ */
@ -91,13 +111,13 @@ public class ThemesTable extends POIXMLDocumentPart {
// No theme set, nothing to do // No theme set, nothing to do
return; return;
} }
// Get the theme colour // Get the theme colour
XSSFColor themeColor = getThemeColor(color.getTheme()); XSSFColor themeColor = getThemeColor(color.getTheme());
// Set the raw colour, not the adjusted one // Set the raw colour, not the adjusted one
// Do a raw set, no adjusting at the XSSFColor layer either // Do a raw set, no adjusting at the XSSFColor layer either
color.getCTColor().setRgb(themeColor.getCTColor().getRgb()); color.getCTColor().setRgb(themeColor.getCTColor().getRgb());
// All done // All done
} }
} }

View File

@ -25,16 +25,16 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;
* Represents a color in SpreadsheetML * Represents a color in SpreadsheetML
*/ */
public class XSSFColor implements Color { public class XSSFColor implements Color {
private CTColor ctColor; private CTColor ctColor;
/** /**
* Create an instance of XSSFColor from the supplied XML bean * Create an instance of XSSFColor from the supplied XML bean
*/ */
public XSSFColor(CTColor color) { public XSSFColor(CTColor color) {
this.ctColor = color; this.ctColor = color;
} }
/** /**
* Create an new instance of XSSFColor * Create an new instance of XSSFColor
*/ */
@ -56,50 +56,29 @@ public class XSSFColor implements Color {
* A boolean value indicating the ctColor is automatic and system ctColor dependent. * A boolean value indicating the ctColor is automatic and system ctColor dependent.
*/ */
public boolean isAuto() { public boolean isAuto() {
return ctColor.getAuto(); return ctColor.getAuto();
} }
/** /**
* A boolean value indicating the ctColor is automatic and system ctColor dependent. * A boolean value indicating the ctColor is automatic and system ctColor dependent.
*/ */
public void setAuto(boolean auto) { public void setAuto(boolean auto) {
ctColor.setAuto(auto); ctColor.setAuto(auto);
} }
/** /**
* 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.
*/ */
public short getIndexed() { public short getIndexed() {
return (short)ctColor.getIndexed(); return (short)ctColor.getIndexed();
} }
/** /**
* 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.
*/ */
public void setIndexed(int indexed) { public void setIndexed(int indexed) {
ctColor.setIndexed(indexed); ctColor.setIndexed(indexed);
} }
/**
* For RGB colours, but not ARGB (we think...)
* Excel gets black and white the wrong way around, so switch them
*/
private byte[] correctRGB(byte[] rgb) {
if(rgb.length == 4) {
// Excel doesn't appear to get these wrong
// Nothing to change
return rgb;
} else {
// Excel gets black and white the wrong way around, so switch them
if (rgb[0] == 0 && rgb[1] == 0 && rgb[2] == 0) {
rgb = new byte[] {-1, -1, -1};
}
else if (rgb[0] == -1 && rgb[1] == -1 && rgb[2] == -1) {
rgb = new byte[] {0, 0, 0};
}
return rgb;
}
}
/** /**
* Standard Red Green Blue ctColor value (RGB). * Standard Red Green Blue ctColor value (RGB).
@ -108,7 +87,7 @@ public class XSSFColor implements Color {
public byte[] getRgb() { public byte[] getRgb() {
byte[] rgb = getRGBOrARGB(); byte[] rgb = getRGBOrARGB();
if(rgb == null) return null; if(rgb == null) return null;
if(rgb.length == 4) { if(rgb.length == 4) {
// Need to trim off the alpha // Need to trim off the alpha
byte[] tmp = new byte[3]; byte[] tmp = new byte[3];
@ -125,7 +104,7 @@ public class XSSFColor implements Color {
public byte[] getARgb() { public byte[] getARgb() {
byte[] rgb = getRGBOrARGB(); byte[] rgb = getRGBOrARGB();
if(rgb == null) return null; if(rgb == null) return null;
if(rgb.length == 3) { if(rgb.length == 3) {
// Pad with the default Alpha // Pad with the default Alpha
byte[] tmp = new byte[4]; byte[] tmp = new byte[4];
@ -136,7 +115,7 @@ public class XSSFColor implements Color {
return rgb; return rgb;
} }
} }
private byte[] getRGBOrARGB() { private byte[] getRGBOrARGB() {
byte[] rgb = null; byte[] rgb = null;
@ -150,7 +129,7 @@ public class XSSFColor implements Color {
return rgb; return rgb;
} }
} }
if (!ctColor.isSetRgb()) { if (!ctColor.isSetRgb()) {
// No colour is available, sorry // No colour is available, sorry
return null; return null;
@ -158,9 +137,7 @@ public class XSSFColor implements Color {
// Grab the colour // Grab the colour
rgb = ctColor.getRgb(); rgb = ctColor.getRgb();
return rgb;
// Correct it as needed, and return
return correctRGB(rgb);
} }
/** /**
@ -181,64 +158,63 @@ public class XSSFColor implements Color {
} }
return rgb; return rgb;
} }
/** /**
* Return the ARGB value in hex format, eg FF00FF00. * Return the ARGB value in hex format, eg FF00FF00.
* Works for both regular and indexed colours. * Works for both regular and indexed colours.
*/ */
public String getARGBHex() { public String getARGBHex() {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
byte[] rgb = getARgb(); byte[] rgb = getARgb();
if(rgb == null) { if(rgb == null) {
return null; return null;
} }
for(byte c : rgb) { for(byte c : rgb) {
int i = (int)c; int i = (int)c;
if(i < 0) { if(i < 0) {
i += 256; i += 256;
} }
String cs = Integer.toHexString(i); String cs = Integer.toHexString(i);
if(cs.length() == 1) { if(cs.length() == 1) {
sb.append('0'); sb.append('0');
} }
sb.append(cs); sb.append(cs);
} }
return sb.toString().toUpperCase(); return sb.toString().toUpperCase();
} }
private static byte applyTint(int lum, double tint){ private static byte applyTint(int lum, double tint){
if(tint > 0){ if(tint > 0){
return (byte)(lum * (1.0-tint) + (255 - 255 * (1.0-tint))); return (byte)(lum * (1.0-tint) + (255 - 255 * (1.0-tint)));
} else if (tint < 0){ } else if (tint < 0){
return (byte)(lum*(1+tint)); return (byte)(lum*(1+tint));
} else { } else {
return (byte)lum; return (byte)lum;
} }
} }
/** /**
* Standard Alpha Red Green Blue ctColor value (ARGB). * Standard Alpha Red Green Blue ctColor value (ARGB).
*/ */
public void setRgb(byte[] rgb) { public void setRgb(byte[] rgb) {
// Correct it and save ctColor.setRgb(rgb);
ctColor.setRgb(correctRGB(rgb)); }
}
/** /**
* 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.
*/ */
public int getTheme() { public int getTheme() {
return (int)ctColor.getTheme(); return (int)ctColor.getTheme();
} }
/** /**
* 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.
*/ */
public void setTheme(int theme) { public void setTheme(int theme) {
ctColor.setTheme(theme); ctColor.setTheme(theme);
} }
/** /**
* Specifies the tint value applied to the ctColor. * Specifies the tint value applied to the ctColor.
@ -282,9 +258,9 @@ public class XSSFColor implements Color {
* @return the tint value * @return the tint value
*/ */
public double getTint() { public double getTint() {
return ctColor.getTint(); return ctColor.getTint();
} }
/** /**
* Specifies the tint value applied to the ctColor. * Specifies the tint value applied to the ctColor.
* *
@ -326,9 +302,9 @@ public class XSSFColor implements Color {
* *
* @param tint the tint value * @param tint the tint value
*/ */
public void setTint(double tint) { public void setTint(double tint) {
ctColor.setTint(tint); ctColor.setTint(tint);
} }
/** /**
* Returns the underlying XML bean * Returns the underlying XML bean
@ -339,7 +315,7 @@ public class XSSFColor implements Color {
public CTColor getCTColor(){ public CTColor getCTColor(){
return ctColor; return ctColor;
} }
public int hashCode(){ public int hashCode(){
return ctColor.toString().hashCode(); return ctColor.toString().hashCode();
} }

View File

@ -0,0 +1,78 @@
/* ====================================================================
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.model;
import static org.junit.Assert.assertEquals;
import java.io.FileOutputStream;
import org.apache.commons.codec.binary.Hex;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;
public class TestThemesTable {
private String testFile = "Themes.xlsx";
@Test
public void testThemesTableColors() throws Exception {
XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook(testFile);
String rgbExpected[] = {
"ffffff", // Lt1
"000000", // Dk1
"eeece1", // Lt2
"1f497d", // DK2
"4f81bd", // Accent1
"c0504d", // Accent2
"9bbb59", // Accent3
"8064a2", // Accent4
"4bacc6", // Accent5
"f79646", // Accent6
"0000ff", // Hlink
"800080" // FolHlink
};
boolean createFile = false;
int i=0;
for (Row row : workbook.getSheetAt(0)) {
XSSFFont font = ((XSSFRow)row).getCell(0).getCellStyle().getFont();
XSSFColor color = font.getXSSFColor();
assertEquals("Failed color theme "+i, rgbExpected[i], Hex.encodeHexString(color.getRgb()));
long themeIdx = font.getCTFont().getColorArray(0).getTheme();
assertEquals("Failed color theme "+i, i, themeIdx);
if (createFile) {
XSSFCellStyle cs = (XSSFCellStyle)row.getSheet().getWorkbook().createCellStyle();
cs.setFillForegroundColor(color);
cs.setFillPattern(CellStyle.SOLID_FOREGROUND);
row.createCell(1).setCellStyle(cs);
}
i++;
}
if (createFile) {
FileOutputStream fos = new FileOutputStream("foobaa.xlsx");
workbook.write(fos);
fos.close();
}
}
}

View File

@ -24,49 +24,49 @@ import org.apache.poi.xssf.XSSFTestDataSamples;
public final class TestXSSFColor extends TestCase { public final class TestXSSFColor extends TestCase {
public void testIndexedColour() throws Exception { public void testIndexedColour() throws Exception {
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx"); XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx");
// Check the CTColor is as expected // Check the CTColor is as expected
XSSFColor indexed = wb.getCellStyleAt((short)1).getFillBackgroundXSSFColor(); XSSFColor indexed = wb.getCellStyleAt((short)1).getFillBackgroundXSSFColor();
assertEquals(true, indexed.getCTColor().isSetIndexed()); assertEquals(true, indexed.getCTColor().isSetIndexed());
assertEquals(64, indexed.getCTColor().getIndexed()); assertEquals(64, indexed.getCTColor().getIndexed());
assertEquals(false, indexed.getCTColor().isSetRgb()); assertEquals(false, indexed.getCTColor().isSetRgb());
assertEquals(null, indexed.getCTColor().getRgb()); assertEquals(null, indexed.getCTColor().getRgb());
// Now check the XSSFColor // Now check the XSSFColor
// Note - 64 is a special "auto" one with no rgb equiv // Note - 64 is a special "auto" one with no rgb equiv
assertEquals(64, indexed.getIndexed()); assertEquals(64, indexed.getIndexed());
assertEquals(null, indexed.getRgb()); assertEquals(null, indexed.getRgb());
assertEquals(null, indexed.getRgbWithTint()); assertEquals(null, indexed.getRgbWithTint());
assertEquals(null, indexed.getARGBHex()); assertEquals(null, indexed.getARGBHex());
// Now move to one with indexed rgb values // Now move to one with indexed rgb values
indexed.setIndexed(59); indexed.setIndexed(59);
assertEquals(true, indexed.getCTColor().isSetIndexed()); assertEquals(true, indexed.getCTColor().isSetIndexed());
assertEquals(59, indexed.getCTColor().getIndexed()); assertEquals(59, indexed.getCTColor().getIndexed());
assertEquals(false, indexed.getCTColor().isSetRgb()); assertEquals(false, indexed.getCTColor().isSetRgb());
assertEquals(null, indexed.getCTColor().getRgb()); assertEquals(null, indexed.getCTColor().getRgb());
assertEquals(59, indexed.getIndexed()); assertEquals(59, indexed.getIndexed());
assertEquals("FF333300", indexed.getARGBHex()); assertEquals("FF333300", indexed.getARGBHex());
assertEquals(3, indexed.getRgb().length); assertEquals(3, indexed.getRgb().length);
assertEquals(0x33, indexed.getRgb()[0]); assertEquals(0x33, indexed.getRgb()[0]);
assertEquals(0x33, indexed.getRgb()[1]); assertEquals(0x33, indexed.getRgb()[1]);
assertEquals(0x00, indexed.getRgb()[2]); assertEquals(0x00, indexed.getRgb()[2]);
assertEquals(4, indexed.getARgb().length); assertEquals(4, indexed.getARgb().length);
assertEquals(-1, indexed.getARgb()[0]); assertEquals(-1, indexed.getARgb()[0]);
assertEquals(0x33, indexed.getARgb()[1]); assertEquals(0x33, indexed.getARgb()[1]);
assertEquals(0x33, indexed.getARgb()[2]); assertEquals(0x33, indexed.getARgb()[2]);
assertEquals(0x00, indexed.getARgb()[3]); assertEquals(0x00, indexed.getARgb()[3]);
// You don't get tinted indexed colours, sorry... // You don't get tinted indexed colours, sorry...
assertEquals(null, indexed.getRgbWithTint()); assertEquals(null, indexed.getRgbWithTint());
} }
public void testRGBColour() throws Exception { public void testRGBColour() throws Exception {
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50299.xlsx"); XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50299.xlsx");
// Check the CTColor is as expected // Check the CTColor is as expected
XSSFColor rgb3 = wb.getCellStyleAt((short)25).getFillForegroundXSSFColor(); XSSFColor rgb3 = wb.getCellStyleAt((short)25).getFillForegroundXSSFColor();
assertEquals(false, rgb3.getCTColor().isSetIndexed()); assertEquals(false, rgb3.getCTColor().isSetIndexed());
@ -75,37 +75,39 @@ public final class TestXSSFColor extends TestCase {
assertEquals(-0.34999, rgb3.getCTColor().getTint(), 0.00001); assertEquals(-0.34999, rgb3.getCTColor().getTint(), 0.00001);
assertEquals(true, rgb3.getCTColor().isSetRgb()); assertEquals(true, rgb3.getCTColor().isSetRgb());
assertEquals(3, rgb3.getCTColor().getRgb().length); assertEquals(3, rgb3.getCTColor().getRgb().length);
// Now check the XSSFColor // Now check the XSSFColor
assertEquals(0, rgb3.getIndexed()); assertEquals(0, rgb3.getIndexed());
assertEquals(-0.34999, rgb3.getTint(), 0.00001); assertEquals(-0.34999, rgb3.getTint(), 0.00001);
assertEquals("FFFFFFFF", rgb3.getARGBHex()); assertEquals("FFFFFFFF", rgb3.getARGBHex());
assertEquals(3, rgb3.getRgb().length); assertEquals(3, rgb3.getRgb().length);
assertEquals(-1, rgb3.getRgb()[0]); assertEquals(-1, rgb3.getRgb()[0]);
assertEquals(-1, rgb3.getRgb()[1]); assertEquals(-1, rgb3.getRgb()[1]);
assertEquals(-1, rgb3.getRgb()[2]); assertEquals(-1, rgb3.getRgb()[2]);
assertEquals(4, rgb3.getARgb().length); assertEquals(4, rgb3.getARgb().length);
assertEquals(-1, rgb3.getARgb()[0]); assertEquals(-1, rgb3.getARgb()[0]);
assertEquals(-1, rgb3.getARgb()[1]); assertEquals(-1, rgb3.getARgb()[1]);
assertEquals(-1, rgb3.getARgb()[2]); assertEquals(-1, rgb3.getARgb()[2]);
assertEquals(-1, rgb3.getARgb()[3]); assertEquals(-1, rgb3.getARgb()[3]);
// Tint doesn't have the alpha // Tint doesn't have the alpha
// tint = -0.34999
// 255 * (1 + tint) = 165 truncated
// or (byte) -91 (which is 165 - 256)
assertEquals(3, rgb3.getRgbWithTint().length); assertEquals(3, rgb3.getRgbWithTint().length);
assertEquals(0, rgb3.getRgbWithTint()[0]); assertEquals(-91, rgb3.getRgbWithTint()[0]);
assertEquals(0, rgb3.getRgbWithTint()[1]); assertEquals(-91, rgb3.getRgbWithTint()[1]);
assertEquals(0, rgb3.getRgbWithTint()[2]); assertEquals(-91, rgb3.getRgbWithTint()[2]);
// Set the colour to black, will get translated internally // Set the color to black (no theme).
// (Excel stores 3 colour white and black wrong!) rgb3.setRgb(new byte[] {0, 0, 0});
rgb3.setRgb(new byte[] {-1,-1,-1}); assertEquals("FF000000", rgb3.getARGBHex());
assertEquals("FFFFFFFF", rgb3.getARGBHex());
assertEquals(0, rgb3.getCTColor().getRgb()[0]); assertEquals(0, rgb3.getCTColor().getRgb()[0]);
assertEquals(0, rgb3.getCTColor().getRgb()[1]); assertEquals(0, rgb3.getCTColor().getRgb()[1]);
assertEquals(0, rgb3.getCTColor().getRgb()[2]); assertEquals(0, rgb3.getCTColor().getRgb()[2]);
// Set another, is fine // Set another, is fine
rgb3.setRgb(new byte[] {16,17,18}); rgb3.setRgb(new byte[] {16,17,18});
assertEquals("FF101112", rgb3.getARGBHex()); assertEquals("FF101112", rgb3.getARGBHex());
@ -113,45 +115,45 @@ public final class TestXSSFColor extends TestCase {
assertEquals(0x11, rgb3.getCTColor().getRgb()[1]); assertEquals(0x11, rgb3.getCTColor().getRgb()[1]);
assertEquals(0x12, rgb3.getCTColor().getRgb()[2]); assertEquals(0x12, rgb3.getCTColor().getRgb()[2]);
} }
public void testARGBColour() throws Exception { public void testARGBColour() throws Exception {
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx"); XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx");
// Check the CTColor is as expected // Check the CTColor is as expected
XSSFColor rgb4 = wb.getCellStyleAt((short)1).getFillForegroundXSSFColor(); XSSFColor rgb4 = wb.getCellStyleAt((short)1).getFillForegroundXSSFColor();
assertEquals(false, rgb4.getCTColor().isSetIndexed()); assertEquals(false, rgb4.getCTColor().isSetIndexed());
assertEquals(0, rgb4.getCTColor().getIndexed()); assertEquals(0, rgb4.getCTColor().getIndexed());
assertEquals(true, rgb4.getCTColor().isSetRgb()); assertEquals(true, rgb4.getCTColor().isSetRgb());
assertEquals(4, rgb4.getCTColor().getRgb().length); assertEquals(4, rgb4.getCTColor().getRgb().length);
// Now check the XSSFColor // Now check the XSSFColor
assertEquals(0, rgb4.getIndexed()); assertEquals(0, rgb4.getIndexed());
assertEquals(0.0, rgb4.getTint()); assertEquals(0.0, rgb4.getTint());
assertEquals("FFFF0000", rgb4.getARGBHex()); assertEquals("FFFF0000", rgb4.getARGBHex());
assertEquals(3, rgb4.getRgb().length); assertEquals(3, rgb4.getRgb().length);
assertEquals(-1, rgb4.getRgb()[0]); assertEquals(-1, rgb4.getRgb()[0]);
assertEquals(0, rgb4.getRgb()[1]); assertEquals(0, rgb4.getRgb()[1]);
assertEquals(0, rgb4.getRgb()[2]); assertEquals(0, rgb4.getRgb()[2]);
assertEquals(4, rgb4.getARgb().length); assertEquals(4, rgb4.getARgb().length);
assertEquals(-1, rgb4.getARgb()[0]); assertEquals(-1, rgb4.getARgb()[0]);
assertEquals(-1, rgb4.getARgb()[1]); assertEquals(-1, rgb4.getARgb()[1]);
assertEquals(0, rgb4.getARgb()[2]); assertEquals(0, rgb4.getARgb()[2]);
assertEquals(0, rgb4.getARgb()[3]); assertEquals(0, rgb4.getARgb()[3]);
// Tint doesn't have the alpha // Tint doesn't have the alpha
assertEquals(3, rgb4.getRgbWithTint().length); assertEquals(3, rgb4.getRgbWithTint().length);
assertEquals(-1, rgb4.getRgbWithTint()[0]); assertEquals(-1, rgb4.getRgbWithTint()[0]);
assertEquals(0, rgb4.getRgbWithTint()[1]); assertEquals(0, rgb4.getRgbWithTint()[1]);
assertEquals(0, rgb4.getRgbWithTint()[2]); assertEquals(0, rgb4.getRgbWithTint()[2]);
// Turn on tinting, and check it behaves // Turn on tinting, and check it behaves
// TODO These values are suspected to be wrong... // TODO These values are suspected to be wrong...
rgb4.setTint(0.4); rgb4.setTint(0.4);
assertEquals(0.4, rgb4.getTint()); assertEquals(0.4, rgb4.getTint());
assertEquals(3, rgb4.getRgbWithTint().length); assertEquals(3, rgb4.getRgbWithTint().length);
assertEquals(-1, rgb4.getRgbWithTint()[0]); assertEquals(-1, rgb4.getRgbWithTint()[0]);
assertEquals(102, rgb4.getRgbWithTint()[1]); assertEquals(102, rgb4.getRgbWithTint()[1]);

View File

@ -31,34 +31,34 @@ import junit.framework.TestCase;
public class TestXSSFCellFill extends TestCase { public class TestXSSFCellFill extends TestCase {
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);
CTPatternFill ctPatternFill = ctFill.addNewPatternFill(); CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
CTColor bgColor = ctPatternFill.addNewBgColor(); CTColor bgColor = ctPatternFill.addNewBgColor();
assertNotNull(cellFill.getFillBackgroundColor()); assertNotNull(cellFill.getFillBackgroundColor());
bgColor.setIndexed(2); bgColor.setIndexed(2);
assertEquals(2, cellFill.getFillBackgroundColor().getIndexed()); assertEquals(2, cellFill.getFillBackgroundColor().getIndexed());
} }
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);
CTPatternFill ctPatternFill = ctFill.addNewPatternFill(); CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
CTColor fgColor = ctPatternFill.addNewFgColor(); CTColor fgColor = ctPatternFill.addNewFgColor();
assertNotNull(cellFill.getFillForegroundColor()); assertNotNull(cellFill.getFillForegroundColor());
fgColor.setIndexed(8); fgColor.setIndexed(8);
assertEquals(8, cellFill.getFillForegroundColor().getIndexed()); assertEquals(8, cellFill.getFillForegroundColor().getIndexed());
} }
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);
CTPatternFill ctPatternFill = ctFill.addNewPatternFill(); CTPatternFill ctPatternFill = ctFill.addNewPatternFill();
ctPatternFill.setPatternType(STPatternType.SOLID); ctPatternFill.setPatternType(STPatternType.SOLID);
//assertEquals(FillPatternType.SOLID_FOREGROUND.ordinal(), cellFill.getPatternType().ordinal()); //assertEquals(FillPatternType.SOLID_FOREGROUND.ordinal(), cellFill.getPatternType().ordinal());
} }
public void testGetNotModifies() { public void testGetNotModifies() {
CTFill ctFill = CTFill.Factory.newInstance(); CTFill ctFill = CTFill.Factory.newInstance();
@ -75,11 +75,16 @@ public class TestXSSFCellFill extends TestCase {
XSSFColor foregroundColor = cellWithThemeColor.getCellStyle().getFillForegroundXSSFColor(); XSSFColor foregroundColor = cellWithThemeColor.getCellStyle().getFillForegroundXSSFColor();
byte[] rgb = foregroundColor.getRgb(); byte[] rgb = foregroundColor.getRgb();
byte[] rgbWithTint = foregroundColor.getRgbWithTint(); byte[] rgbWithTint = foregroundColor.getRgbWithTint();
assertEquals(rgb[0],-18); // Dk2
assertEquals(rgb[1],-20); assertEquals(rgb[0],31);
assertEquals(rgb[2],-31); assertEquals(rgb[1],73);
assertEquals(rgbWithTint[0],-12); assertEquals(rgb[2],125);
assertEquals(rgbWithTint[1],-13); // Dk2, lighter 40% (tint is about 0.39998)
assertEquals(rgbWithTint[2],-20); // 31 * (1.0 - 0.39998) + (255 - 255 * (1.0 - 0.39998)) = 120.59552 => 120 (byte)
// 73 * (1.0 - 0.39998) + (255 - 255 * (1.0 - 0.39998)) = 145.79636 => -111 (byte)
// 125 * (1.0 - 0.39998) + (255 - 255 * (1.0 - 0.39998)) = 176.99740 => -80 (byte)
assertEquals(rgbWithTint[0],120);
assertEquals(rgbWithTint[1],-111);
assertEquals(rgbWithTint[2],-80);
} }
} }

Binary file not shown.