Apply (with slight tweaks) patch from bug #48432 - Support for XSSF themes

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@946136 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2010-05-19 11:55:17 +00:00
parent afe2ad7d38
commit daad262fbc
12 changed files with 161 additions and 13 deletions

View File

@ -34,7 +34,8 @@
<changes>
<release version="3.7-SNAPSHOT" date="2010-??-??">
<action dev="POI-DEVELOPERS" type="add">49244 -Support for data validation for OOXML format</action>
<action dev="POI-DEVELOPERS" type="add">48432 - Support for XSSF themes</action>
<action dev="POI-DEVELOPERS" type="add">49244 - Support for data validation for OOXML format</action>
<action dev="POI-DEVELOPERS" type="add">49066 - Worksheet/cell formatting, with view and HTML converter</action>
<action dev="POI-DEVELOPERS" type="fix">49020 - Workaround Excel outputting invalid XML in button definitions by not closing BR tags</action>
<action dev="POI-DEVELOPERS" type="fix">49050 - Improve performance of AbstractEscherHolderRecord when there are lots of Continue Records</action>

View File

@ -74,6 +74,7 @@ public class StylesTable extends POIXMLDocumentPart {
public static final int FIRST_CUSTOM_STYLE_ID = BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX + 1;
private StyleSheetDocument doc;
private ThemesTable theme;
/**
* Create a new, empty StylesTable
@ -91,6 +92,14 @@ public class StylesTable extends POIXMLDocumentPart {
readFrom(part.getInputStream());
}
public ThemesTable getTheme() {
return theme;
}
public void setTheme(ThemesTable theme) {
this.theme = theme;
}
/**
* Read this shared styles table from an XML file.
*
@ -184,7 +193,7 @@ public class StylesTable extends POIXMLDocumentPart {
styleXfId = (int) xfs.get(idx).getXfId();
}
return new XSSFCellStyle(idx, styleXfId, this);
return new XSSFCellStyle(idx, styleXfId, this, theme);
}
public int putStyle(XSSFCellStyle style) {
CTXf mainXF = style.getCoreXf();
@ -455,7 +464,7 @@ public class StylesTable extends POIXMLDocumentPart {
xf.setXfId(0);
int xfSize = styleXfs.size();
int indexXf = putCellXf(xf);
return new XSSFCellStyle(indexXf - 1, xfSize - 1, this);
return new XSSFCellStyle(indexXf - 1, xfSize - 1, this, theme);
}
/**

View File

@ -0,0 +1,61 @@
/* ====================================================================
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 org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme;
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
* colors and fonts.
*
* @author Petr Udalau(Petr.Udalau at exigenservices.com) - theme colors
*/
public class ThemesTable extends POIXMLDocumentPart {
private ThemeDocument theme;
public ThemesTable(PackagePart part, PackageRelationship rel) throws Exception {
super(part, rel);
theme = ThemeDocument.Factory.parse(part.getInputStream());
}
public ThemesTable(ThemeDocument theme) {
this.theme = theme;
}
public XSSFColor getThemeColor(int idx) {
CTColorScheme colorScheme = theme.getTheme().getThemeElements().getClrScheme();
CTColor ctColor = null;
int cnt = 0;
for (XmlObject obj : colorScheme.selectPath("./*")) {
if (obj instanceof org.openxmlformats.schemas.drawingml.x2006.main.CTColor) {
if (cnt == idx) {
ctColor = (org.openxmlformats.schemas.drawingml.x2006.main.CTColor) obj;
return new XSSFColor(ctColor.getSrgbClr().getVal());
}
cnt++;
}
}
return null;
}
}

View File

@ -25,6 +25,7 @@ import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.ThemesTable;
import org.apache.poi.xssf.usermodel.extensions.XSSFCellAlignment;
import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder;
import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill;
@ -58,6 +59,7 @@ public class XSSFCellStyle implements CellStyle {
private CTXf _cellStyleXf;
private XSSFFont _font;
private XSSFCellAlignment _cellAlignment;
private ThemesTable _theme;
/**
* Creates a Cell Style from the supplied parts
@ -65,11 +67,12 @@ public class XSSFCellStyle implements CellStyle {
* @param cellStyleXfId Optional, style xf
* @param stylesSource Styles Source to work off
*/
public XSSFCellStyle(int cellXfId, int cellStyleXfId, StylesTable stylesSource) {
public XSSFCellStyle(int cellXfId, int cellStyleXfId, StylesTable stylesSource, ThemesTable theme) {
_cellXfId = cellXfId;
_stylesSource = stylesSource;
_cellXf = stylesSource.getCellXfAt(this._cellXfId);
_cellStyleXf = stylesSource.getCellStyleXfAt(cellStyleXfId);
_theme = theme;
}
/**
@ -394,7 +397,11 @@ public class XSSFCellStyle implements CellStyle {
int fillIndex = (int)_cellXf.getFillId();
XSSFCellFill fg = _stylesSource.getFillAt(fillIndex);
return fg.getFillBackgroundColor();
XSSFColor fillBackgroundColor = fg.getFillBackgroundColor();
if (fillBackgroundColor != null && fillBackgroundColor.getCTColor().isSetTheme() && _theme != null) {
extractColorFromTheme(fillBackgroundColor);
}
return fillBackgroundColor;
}
/**
@ -422,7 +429,11 @@ public class XSSFCellStyle implements CellStyle {
int fillIndex = (int)_cellXf.getFillId();
XSSFCellFill fg = _stylesSource.getFillAt(fillIndex);
return fg.getFillForegroundColor();
XSSFColor fillForegroundColor = fg.getFillForegroundColor();
if (fillForegroundColor != null && fillForegroundColor.getCTColor().isSetTheme() && _theme != null) {
extractColorFromTheme(fillForegroundColor);
}
return fillForegroundColor;
}
/**
@ -1385,7 +1396,15 @@ public class XSSFCellStyle implements CellStyle {
int xfSize = _stylesSource._getStyleXfsSize();
int indexXf = _stylesSource.putCellXf(xf);
return new XSSFCellStyle(indexXf-1, xfSize-1, _stylesSource);
return new XSSFCellStyle(indexXf-1, xfSize-1, _stylesSource, _theme);
}
/**
* Extracts RGB form theme color.
* @param originalColor Color that refers to theme.
*/
private void extractColorFromTheme(XSSFColor originalColor){
XSSFColor themeColor = _theme.getThemeColor(originalColor.getTheme());
originalColor.setRgb(themeColor.getRgb());
}
}

View File

@ -45,6 +45,11 @@ public class XSSFColor {
ctColor.setRgb(new byte[]{(byte)clr.getRed(), (byte)clr.getGreen(), (byte)clr.getBlue()});
}
public XSSFColor(byte[] rgb) {
this();
ctColor.setRgb(rgb);
}
/**
* A boolean value indicating the ctColor is automatic and system ctColor dependent.
*/
@ -80,6 +85,27 @@ public class XSSFColor {
return ctColor.getRgb();
}
/**
* Standard Alpha Red Green Blue ctColor value (ARGB) with applied tint.
*/
public byte[] getRgbWithTint() {
byte[] rgb =ctColor.getRgb();
for(int i = 0; i < rgb.length; i++){
rgb[i] = applyTint(rgb[i] & 0xFF, ctColor.getTint());
}
return rgb;
}
private static byte applyTint(int lum, double tint){
if(tint > 0){
return (byte)(lum * (1.0-tint) + (255 - 255 * (1.0-tint)));
} else if (tint < 0){
return (byte)(lum*(1+tint));
} else {
return (byte)lum;
}
}
/**
* Standard Alpha Red Green Blue ctColor value (ARGB).
*/
@ -91,8 +117,8 @@ public class XSSFColor {
* Index into the <clrScheme> collection, referencing a particular <sysClr> or
* <srgbClr> value expressed in the Theme part.
*/
public int getTheme() {
return (int)ctColor.getTheme();
public int getTheme() {
return (int)ctColor.getTheme();
}
/**

View File

@ -40,6 +40,7 @@ import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.SingleXmlCells;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.Table;
import org.apache.poi.xssf.model.ThemesTable;
/**
*
@ -232,7 +233,7 @@ public final class XSSFRelation extends POIXMLRelation {
"application/vnd.openxmlformats-officedocument.theme+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
"/xl/theme/theme#.xml",
null
ThemesTable.class
);
public static final XSSFRelation CALC_CHAIN = new XSSFRelation(
"application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml",

View File

@ -56,6 +56,7 @@ import org.apache.poi.xssf.model.CalculationChain;
import org.apache.poi.xssf.model.MapInfo;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.ThemesTable;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
@ -113,6 +114,8 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
*/
private StylesTable stylesSource;
private ThemesTable theme;
/**
* TODO
*/
@ -198,12 +201,14 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
for(POIXMLDocumentPart p : getRelations()){
if(p instanceof SharedStringsTable) sharedStringSource = (SharedStringsTable)p;
else if(p instanceof StylesTable) stylesSource = (StylesTable)p;
else if(p instanceof ThemesTable) theme = (ThemesTable)p;
else if(p instanceof CalculationChain) calcChain = (CalculationChain)p;
else if(p instanceof MapInfo) mapInfo = (MapInfo)p;
else if (p instanceof XSSFSheet) {
shIdMap.put(p.getPackageRelationship().getId(), (XSSFSheet)p);
}
}
stylesSource.setTheme(theme);
if(sharedStringSource == null) {
//Create SST if it is missing
@ -1191,6 +1196,13 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
return this.stylesSource;
}
/**
* Returns the Theme of current workbook.
*/
public ThemesTable getTheme() {
return theme;
}
/**
* Returns an object that handles instantiating concrete
* classes of the various instances for XSSF.

View File

@ -80,7 +80,7 @@ public class TestXSSFCellStyle extends TestCase {
cellXf.setFontId(1);
stylesTable.putCellStyleXf(cellStyleXf);
stylesTable.putCellXf(cellXf);
cellStyle = new XSSFCellStyle(1, 1, stylesTable);
cellStyle = new XSSFCellStyle(1, 1, stylesTable, null);
}
public void testGetSetBorderBottom() {

View File

@ -273,7 +273,7 @@ public final class TestXSSFSheet extends BaseTestSheet {
CTXf cellXf = CTXf.Factory.newInstance();
cellXf.setXfId(1);
stylesTable.putCellXf(cellXf);
XSSFCellStyle cellStyle = new XSSFCellStyle(1, 1, stylesTable);
XSSFCellStyle cellStyle = new XSSFCellStyle(1, 1, stylesTable, null);
assertEquals(1, cellStyle.getFontIndex());
sheet.setDefaultColumnStyle(3, cellStyle);

View File

@ -18,6 +18,10 @@
package org.apache.poi.xssf.usermodel.extensions;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPatternFill;
@ -63,4 +67,19 @@ public class TestXSSFCellFill extends TestCase {
ctPatternFill.setPatternType(STPatternType.DARK_DOWN);
assertEquals(8, cellFill.getPatternType().intValue());
}
public void testColorFromTheme() {
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("styles.xlsx");
XSSFCell cellWithThemeColor = wb.getSheetAt(0).getRow(10).getCell(0);
//color RGB will be extracted from theme
XSSFColor foregroundColor = cellWithThemeColor.getCellStyle().getFillForegroundXSSFColor();
byte[] rgb = foregroundColor.getRgb();
byte[] rgbWithTint = foregroundColor.getRgbWithTint();
assertEquals(rgb[0],-18);
assertEquals(rgb[1],-20);
assertEquals(rgb[2],-31);
assertEquals(rgbWithTint[0],-12);
assertEquals(rgbWithTint[1],-13);
assertEquals(rgbWithTint[2],-20);
}
}

View File

@ -283,7 +283,7 @@ public final class TestColumnHelper extends TestCase {
col_2.setMax(12);
col_2.setStyle(1);
assertEquals(1, columnHelper.getColDefaultStyle(11));
XSSFCellStyle cellStyle = new XSSFCellStyle(0, 0, stylesTable);
XSSFCellStyle cellStyle = new XSSFCellStyle(0, 0, stylesTable, null);
columnHelper.setColDefaultStyle(11, cellStyle);
assertEquals(0, col_2.getStyle());
assertEquals(1, columnHelper.getColDefaultStyle(10));

Binary file not shown.