git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@946136 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_7_BETA1
@@ -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> |
@@ -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); | |||
} | |||
/** |
@@ -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; | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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(); | |||
} | |||
/** |
@@ -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", |
@@ -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. |
@@ -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() { |
@@ -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); |
@@ -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); | |||
} | |||
} |
@@ -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)); |