git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@946136 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_7_BETA1
<changes> | <changes> | ||||
<release version="3.7-SNAPSHOT" date="2010-??-??"> | <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="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">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> | <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; | public static final int FIRST_CUSTOM_STYLE_ID = BuiltinFormats.FIRST_USER_DEFINED_FORMAT_INDEX + 1; | ||||
private StyleSheetDocument doc; | private StyleSheetDocument doc; | ||||
private ThemesTable theme; | |||||
/** | /** | ||||
* Create a new, empty StylesTable | * Create a new, empty StylesTable | ||||
readFrom(part.getInputStream()); | 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. | * Read this shared styles table from an XML file. | ||||
* | * | ||||
styleXfId = (int) xfs.get(idx).getXfId(); | styleXfId = (int) xfs.get(idx).getXfId(); | ||||
} | } | ||||
return new XSSFCellStyle(idx, styleXfId, this); | |||||
return new XSSFCellStyle(idx, styleXfId, this, theme); | |||||
} | } | ||||
public int putStyle(XSSFCellStyle style) { | public int putStyle(XSSFCellStyle style) { | ||||
CTXf mainXF = style.getCoreXf(); | CTXf mainXF = style.getCoreXf(); | ||||
xf.setXfId(0); | xf.setXfId(0); | ||||
int xfSize = styleXfs.size(); | int xfSize = styleXfs.size(); | ||||
int indexXf = putCellXf(xf); | int indexXf = putCellXf(xf); | ||||
return new XSSFCellStyle(indexXf - 1, xfSize - 1, this); | |||||
return new XSSFCellStyle(indexXf - 1, xfSize - 1, this, theme); | |||||
} | } | ||||
/** | /** |
/* ==================================================================== | |||||
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.IndexedColors; | ||||
import org.apache.poi.ss.usermodel.VerticalAlignment; | import org.apache.poi.ss.usermodel.VerticalAlignment; | ||||
import org.apache.poi.xssf.model.StylesTable; | 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.XSSFCellAlignment; | ||||
import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder; | import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder; | ||||
import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill; | import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill; | ||||
private CTXf _cellStyleXf; | private CTXf _cellStyleXf; | ||||
private XSSFFont _font; | private XSSFFont _font; | ||||
private XSSFCellAlignment _cellAlignment; | private XSSFCellAlignment _cellAlignment; | ||||
private ThemesTable _theme; | |||||
/** | /** | ||||
* Creates a Cell Style from the supplied parts | * Creates a Cell Style from the supplied parts | ||||
* @param cellStyleXfId Optional, style xf | * @param cellStyleXfId Optional, style xf | ||||
* @param stylesSource Styles Source to work off | * @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; | _cellXfId = cellXfId; | ||||
_stylesSource = stylesSource; | _stylesSource = stylesSource; | ||||
_cellXf = stylesSource.getCellXfAt(this._cellXfId); | _cellXf = stylesSource.getCellXfAt(this._cellXfId); | ||||
_cellStyleXf = stylesSource.getCellStyleXfAt(cellStyleXfId); | _cellStyleXf = stylesSource.getCellStyleXfAt(cellStyleXfId); | ||||
_theme = theme; | |||||
} | } | ||||
/** | /** | ||||
int fillIndex = (int)_cellXf.getFillId(); | int fillIndex = (int)_cellXf.getFillId(); | ||||
XSSFCellFill fg = _stylesSource.getFillAt(fillIndex); | 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(); | int fillIndex = (int)_cellXf.getFillId(); | ||||
XSSFCellFill fg = _stylesSource.getFillAt(fillIndex); | 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 xfSize = _stylesSource._getStyleXfsSize(); | ||||
int indexXf = _stylesSource.putCellXf(xf); | 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()}); | 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. | * A boolean value indicating the ctColor is automatic and system ctColor dependent. | ||||
*/ | */ | ||||
return ctColor.getRgb(); | 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). | * Standard Alpha Red Green Blue ctColor value (ARGB). | ||||
*/ | */ | ||||
* 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() { | |||||
return (int)ctColor.getTheme(); | |||||
public int getTheme() { | |||||
return (int)ctColor.getTheme(); | |||||
} | } | ||||
/** | /** |
import org.apache.poi.xssf.model.SingleXmlCells; | import org.apache.poi.xssf.model.SingleXmlCells; | ||||
import org.apache.poi.xssf.model.StylesTable; | import org.apache.poi.xssf.model.StylesTable; | ||||
import org.apache.poi.xssf.model.Table; | import org.apache.poi.xssf.model.Table; | ||||
import org.apache.poi.xssf.model.ThemesTable; | |||||
/** | /** | ||||
* | * | ||||
"application/vnd.openxmlformats-officedocument.theme+xml", | "application/vnd.openxmlformats-officedocument.theme+xml", | ||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", | "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", | ||||
"/xl/theme/theme#.xml", | "/xl/theme/theme#.xml", | ||||
null | |||||
ThemesTable.class | |||||
); | ); | ||||
public static final XSSFRelation CALC_CHAIN = new XSSFRelation( | public static final XSSFRelation CALC_CHAIN = new XSSFRelation( | ||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml", | "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml", |
import org.apache.poi.xssf.model.MapInfo; | import org.apache.poi.xssf.model.MapInfo; | ||||
import org.apache.poi.xssf.model.SharedStringsTable; | import org.apache.poi.xssf.model.SharedStringsTable; | ||||
import org.apache.poi.xssf.model.StylesTable; | import org.apache.poi.xssf.model.StylesTable; | ||||
import org.apache.poi.xssf.model.ThemesTable; | |||||
import org.apache.xmlbeans.XmlException; | import org.apache.xmlbeans.XmlException; | ||||
import org.apache.xmlbeans.XmlObject; | import org.apache.xmlbeans.XmlObject; | ||||
import org.apache.xmlbeans.XmlOptions; | import org.apache.xmlbeans.XmlOptions; | ||||
*/ | */ | ||||
private StylesTable stylesSource; | private StylesTable stylesSource; | ||||
private ThemesTable theme; | |||||
/** | /** | ||||
* TODO | * TODO | ||||
*/ | */ | ||||
for(POIXMLDocumentPart p : getRelations()){ | for(POIXMLDocumentPart p : getRelations()){ | ||||
if(p instanceof SharedStringsTable) sharedStringSource = (SharedStringsTable)p; | if(p instanceof SharedStringsTable) sharedStringSource = (SharedStringsTable)p; | ||||
else if(p instanceof StylesTable) stylesSource = (StylesTable)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 CalculationChain) calcChain = (CalculationChain)p; | ||||
else if(p instanceof MapInfo) mapInfo = (MapInfo)p; | else if(p instanceof MapInfo) mapInfo = (MapInfo)p; | ||||
else if (p instanceof XSSFSheet) { | else if (p instanceof XSSFSheet) { | ||||
shIdMap.put(p.getPackageRelationship().getId(), (XSSFSheet)p); | shIdMap.put(p.getPackageRelationship().getId(), (XSSFSheet)p); | ||||
} | } | ||||
} | } | ||||
stylesSource.setTheme(theme); | |||||
if(sharedStringSource == null) { | if(sharedStringSource == null) { | ||||
//Create SST if it is missing | //Create SST if it is missing | ||||
return this.stylesSource; | return this.stylesSource; | ||||
} | } | ||||
/** | |||||
* Returns the Theme of current workbook. | |||||
*/ | |||||
public ThemesTable getTheme() { | |||||
return theme; | |||||
} | |||||
/** | /** | ||||
* Returns an object that handles instantiating concrete | * Returns an object that handles instantiating concrete | ||||
* classes of the various instances for XSSF. | * classes of the various instances for XSSF. |
cellXf.setFontId(1); | cellXf.setFontId(1); | ||||
stylesTable.putCellStyleXf(cellStyleXf); | stylesTable.putCellStyleXf(cellStyleXf); | ||||
stylesTable.putCellXf(cellXf); | stylesTable.putCellXf(cellXf); | ||||
cellStyle = new XSSFCellStyle(1, 1, stylesTable); | |||||
cellStyle = new XSSFCellStyle(1, 1, stylesTable, null); | |||||
} | } | ||||
public void testGetSetBorderBottom() { | public void testGetSetBorderBottom() { |
CTXf cellXf = CTXf.Factory.newInstance(); | CTXf cellXf = CTXf.Factory.newInstance(); | ||||
cellXf.setXfId(1); | cellXf.setXfId(1); | ||||
stylesTable.putCellXf(cellXf); | stylesTable.putCellXf(cellXf); | ||||
XSSFCellStyle cellStyle = new XSSFCellStyle(1, 1, stylesTable); | |||||
XSSFCellStyle cellStyle = new XSSFCellStyle(1, 1, stylesTable, null); | |||||
assertEquals(1, cellStyle.getFontIndex()); | assertEquals(1, cellStyle.getFontIndex()); | ||||
sheet.setDefaultColumnStyle(3, cellStyle); | sheet.setDefaultColumnStyle(3, cellStyle); |
package org.apache.poi.xssf.usermodel.extensions; | 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.CTColor; | ||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill; | import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill; | ||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPatternFill; | import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPatternFill; | ||||
ctPatternFill.setPatternType(STPatternType.DARK_DOWN); | ctPatternFill.setPatternType(STPatternType.DARK_DOWN); | ||||
assertEquals(8, cellFill.getPatternType().intValue()); | 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.setMax(12); | ||||
col_2.setStyle(1); | col_2.setStyle(1); | ||||
assertEquals(1, columnHelper.getColDefaultStyle(11)); | assertEquals(1, columnHelper.getColDefaultStyle(11)); | ||||
XSSFCellStyle cellStyle = new XSSFCellStyle(0, 0, stylesTable); | |||||
XSSFCellStyle cellStyle = new XSSFCellStyle(0, 0, stylesTable, null); | |||||
columnHelper.setColDefaultStyle(11, cellStyle); | columnHelper.setColDefaultStyle(11, cellStyle); | ||||
assertEquals(0, col_2.getStyle()); | assertEquals(0, col_2.getStyle()); | ||||
assertEquals(1, columnHelper.getColDefaultStyle(10)); | assertEquals(1, columnHelper.getColDefaultStyle(10)); |