From: Nick Burch Date: Wed, 19 May 2010 11:55:17 +0000 (+0000) Subject: Apply (with slight tweaks) patch from bug #48432 - Support for XSSF themes X-Git-Tag: REL_3_7_BETA1~74 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=daad262fbce4dde7519d1c2a9f46e4751a0668cf;p=poi.git 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 --- diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index b80709fb2f..9d34da5b1e 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,7 +34,8 @@ - 49244 -Support for data validation for OOXML format + 48432 - Support for XSSF themes + 49244 - Support for data validation for OOXML format 49066 - Worksheet/cell formatting, with view and HTML converter 49020 - Workaround Excel outputting invalid XML in button definitions by not closing BR tags 49050 - Improve performance of AbstractEscherHolderRecord when there are lots of Continue Records diff --git a/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java b/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java index 47d75efe5e..c0ad5f1bd1 100644 --- a/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java @@ -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); } /** diff --git a/src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java b/src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java new file mode 100644 index 0000000000..d78e31073f --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java index 00dc1c4a5d..0bbbd5ff07 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java @@ -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()); + } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java index 6c63195d40..6ed2a40524 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java @@ -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 collection, referencing a particular or * value expressed in the Theme part. */ - public int getTheme() { - return (int)ctColor.getTheme(); + public int getTheme() { + return (int)ctColor.getTheme(); } /** diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java index d2ba007e3a..f11ebd655c 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java @@ -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", diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index 20aeadb50f..2fef9ad5f4 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -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