<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>
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
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.
*
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();
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);
}
/**
--- /dev/null
+/* ====================================================================
+ 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;
+ }
+}
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;
private CTXf _cellStyleXf;
private XSSFFont _font;
private XSSFCellAlignment _cellAlignment;
+ private ThemesTable _theme;
/**
* Creates a Cell Style from the supplied parts
* @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;
}
/**
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;
}
/**
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;
}
/**
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());
+ }
}
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.
*/
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).
*/
* 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();
}
/**
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;
/**
*
"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",
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;
*/
private StylesTable stylesSource;
+ private ThemesTable theme;
+
/**
* TODO
*/
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
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.
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() {
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);
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;
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);
+ }
}
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));