]> source.dussan.org Git - poi.git/commitdiff
Apply (with slight tweaks) patch from bug #48432 - Support for XSSF themes
authorNick Burch <nick@apache.org>
Wed, 19 May 2010 11:55:17 +0000 (11:55 +0000)
committerNick Burch <nick@apache.org>
Wed, 19 May 2010 11:55:17 +0000 (11:55 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@946136 13f79535-47bb-0310-9956-ffa450edef68

12 files changed:
src/documentation/content/xdocs/status.xml
src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java
src/ooxml/java/org/apache/poi/xssf/model/ThemesTable.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCellStyle.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/extensions/TestXSSFCellFill.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/helpers/TestColumnHelper.java
test-data/spreadsheet/styles.xlsx

index b80709fb2f4b8eb8a1d483816e61def97efea12c..9d34da5b1ef5633250ba6f9450c00a011c9fa0b4 100644 (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>
index 47d75efe5e05a1da2bc7661ea81e9e33e3b8857a..c0ad5f1bd1bf1f70b9bc9f6cd104f2f561e1c554 100644 (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);
        }
 
        /**
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 (file)
index 0000000..d78e310
--- /dev/null
@@ -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;
+    }
+}
index 00dc1c4a5d7a6dfe710313f123f03487fc2babcf..0bbbd5ff07f1227ee2e0849bebd456330753e988 100644 (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());
+    }
 }
index 6c63195d40dc02dfdaf481c6bd3b1f9737c42fa3..6ed2a405244a9955e18fbb6c802279e37957b46b 100644 (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();
        }
        
     /**
index d2ba007e3affa9c970c72e4ac30f20893d107cdf..f11ebd655cc0f97cab74139d69e2ecfbe6cb0da8 100644 (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",
index 20aeadb50ffc38adffffe95b538fcee540155ba9..2fef9ad5f482ad64720cb958b507042ac131b1b8 100644 (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.
index d290b4e1ced1b39d35416222570c0e9c57b95777..f6c63c96a9e38cab61980a364a8cc9f4235e422d 100644 (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() {
index 33c5eee1d9a83d49a54cf315641d051ad18f00e9..c1302812ed4af2568ff08dc1de28eec06ee54d01 100644 (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);
index 336c07dd6834c040ce4c734db06a722573c8f3a9..2ad4f5645d96b212f652a5985da2ef6925d118c4 100644 (file)
 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);
+    }
 }
index 6e3df5d583f1399dbf646eab0fd15f99a267fbdb..9a0c9a22c8b891901570d5c855342bc8f0445bb4 100644 (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));
index dbfa53cfbf5376106026e3a70b2fd0086bc214d5..2239009c2048f10850dedb7dfda7773820bcbd57 100644 (file)
Binary files a/test-data/spreadsheet/styles.xlsx and b/test-data/spreadsheet/styles.xlsx differ