]> source.dussan.org Git - poi.git/commitdiff
bug 58633: Set multiple CellStyle properties at once. Patch from Mark Murphy.
authorJaven O'Neal <onealj@apache.org>
Sat, 2 Jan 2016 04:29:30 +0000 (04:29 +0000)
committerJaven O'Neal <onealj@apache.org>
Sat, 2 Jan 2016 04:29:30 +0000 (04:29 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1722607 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
src/java/org/apache/poi/ss/usermodel/Cell.java
src/java/org/apache/poi/ss/util/CellUtil.java
src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
src/testcases/org/apache/poi/ss/util/TestCellUtil.java [new file with mode: 0644]

index 2009c2f7743ea58548a444b55c93e509f3434d8a..571d0863166124035ce3d0f8ef70e1b405d4f8cb 100644 (file)
@@ -880,8 +880,11 @@ public class HSSFCell implements Cell {
     }
 
     /**
-     * set the style for the cell.  The style should be an HSSFCellStyle created/retreived from
-     * the HSSFWorkbook.
+     * <p>Set the style for the cell.  The style should be an HSSFCellStyle created/retreived from
+     * the HSSFWorkbook.</p>
+     * 
+     * <p>To change the style of a cell without affecting other cells that use the same style,
+     * use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperties(Cell, Map<String, Object>)}</p>
      *
      * @param style  reference contained in the workbook
      * @see org.apache.poi.hssf.usermodel.HSSFWorkbook#createCellStyle()
index 2fd501bd16c4b72a67cb402da930991594bf6287..fa866bb4fa16843b3ef0e75fd9f3958bdb0428cb 100644 (file)
@@ -327,8 +327,11 @@ public interface Cell {
     byte getErrorCellValue();
 
     /**
-     * Set the style for the cell.  The style should be an CellStyle created/retreived from
-     * the Workbook.
+     * <p>Set the style for the cell.  The style should be an CellStyle created/retreived from
+     * the Workbook.</p>
+     * 
+     * <p>To change the style of a cell without affecting other cells that use the same style,
+     * use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperties(Cell, Map<String, Object>)}</p>
      *
      * @param style  reference contained in the workbook.
      * If the value is null then the style information is removed causing the cell to used the default workbook style.
index cc07b483f6da0e08160fedaa81f1b69913d84220..2af1430e888107c17b074f90fac449471c4bffc9 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.ss.util;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
@@ -170,22 +171,36 @@ public final class CellUtil {
        }
 
        /**
-        * This method attempt to find an already existing CellStyle that matches what you want the
-        * style to be. If it does not find the style, then it creates a new one. If it does create a
-        * new one, then it applies the propertyName and propertyValue to the style. This is necessary
-        * because Excel has an upper limit on the number of Styles that it supports.
+        * <p>This method attempts to find an existing CellStyle that matches the <code>cell</code>'s 
+        * current style plus styles properties in <code>properties</code>. A new style is created if the
+        * workbook does not contain a matching style.</p>
+        * 
+        * <p>Modifies the cell style of <code>cell</code> without affecting other cells that use the
+        * same style.</p>
+        * 
+        * <p>This is necessary because Excel has an upper limit on the number of styles that it supports.</p>
+        * 
+        * <p>This function is more efficient than multiple calls to
+        * {@link #setCellStyleProperty(org.apache.poi.ss.usermodel.Cell, org.apache.poi.ss.usermodel.Workbook, String, Object)}
+        * if adding multiple cell styles.</p>
+        * 
+        * <p>For performance reasons, if this is the only cell in a workbook that uses a cell style,
+        * this method does NOT remove the old style from the workbook.
+        * <!-- NOT IMPLEMENTED: Unused styles should be
+        * pruned from the workbook with {@link #removeUnusedCellStyles(Workbook)} or
+        * {@link #removeStyleFromWorkbookIfUnused(CellStyle, Workbook)}. -->
+        * </p>
         *
-        *@param workbook The workbook that is being worked with.
-        *@param propertyName The name of the property that is to be changed.
-        *@param propertyValue The value of the property that is to be changed.
-        *@param cell The cell that needs it's style changes
+        * @param cell The cell to change the style of
+        * @param properties The properties to be added to a cell style, as {propertyName: propertyValue}.
+        * @since POI 3.14 beta 2
         */
-       public static void setCellStyleProperty(Cell cell, Workbook workbook, String propertyName,
-                       Object propertyValue) {
+       public static void setCellStyleProperties(Cell cell, Map<String, Object> properties) {
+               Workbook workbook = cell.getSheet().getWorkbook();
                CellStyle originalStyle = cell.getCellStyle();
                CellStyle newStyle = null;
                Map<String, Object> values = getFormatProperties(originalStyle);
-               values.put(propertyName, propertyValue);
+               values.putAll(properties);
 
                // index seems like what index the cellstyle is in the list of styles for a workbook.
                // not good to compare on!
@@ -195,12 +210,14 @@ public final class CellUtil {
                        CellStyle wbStyle = workbook.getCellStyleAt(i);
                        Map<String, Object> wbStyleMap = getFormatProperties(wbStyle);
 
+                       // the desired style already exists in the workbook. Use the existing style.
                        if (wbStyleMap.equals(values)) {
                                newStyle = wbStyle;
                                break;
                        }
                }
 
+               // the desired style does not exist in the workbook. Create a new style with desired properties.
                if (newStyle == null) {
                        newStyle = workbook.createCellStyle();
                        setFormatProperties(newStyle, workbook, values);
@@ -209,8 +226,39 @@ public final class CellUtil {
                cell.setCellStyle(newStyle);
        }
 
+       /**
+        * <p>This method attempts to find an existing CellStyle that matches the <code>cell</code>'s
+        * current style plus a single style property <code>propertyName</code> with value
+        * <code>propertyValue<code>.
+        * A new style is created if the workbook does not contain a matching style.</p>
+        * 
+        * <p>Modifies the cell style of <code>cell</code> without affecting other cells that use the
+        * same style.</p>
+        * 
+        * <p>If setting more than one cell style property on a cell, use
+        * {@link #setCellStyleProperties(org.apache.poi.ss.usermodel.Cell, Map<String, Object>)},
+        * which is faster and does not add unnecessary intermediate CellStyles to the workbook.</p>
+        * 
+        * @param workbook The workbook that is being worked with.
+        * @param propertyName The name of the property that is to be changed.
+        * @param propertyValue The value of the property that is to be changed.
+        * @param cell The cell that needs it's style changes
+        */
+       public static void setCellStyleProperty(Cell cell, Workbook workbook, String propertyName,
+                       Object propertyValue) {
+               if (cell.getSheet().getWorkbook() != workbook) {
+                       throw new IllegalArgumentException("Cannot set cell style property. Cell does not belong to workbook");
+               }
+
+               Map<String, Object> values = Collections.singletonMap(propertyName, propertyValue);
+               setCellStyleProperties(cell, values);
+       }
+
        /**
         * Returns a map containing the format properties of the given cell style.
+         * The returned map is not tied to <code>style</code>, so subsequent changes
+         * to <code>style</code> will not modify the map, and changes to the returned
+         * map will not modify the cell style. The returned map is mutable.
         *
         * @param style cell style
         * @return map of format properties (String -> Object)
index 90840df9fc6693e941aef8e30a38a7bd93e15a9c..744b91f70b6e4d3a8e8ced525dcaa811d4a4f1be 100644 (file)
@@ -541,9 +541,12 @@ public class SXSSFCell implements Cell {
     }
 
     /**
-     * Set the style for the cell.  The style should be an CellStyle created/retreived from
-     * the Workbook.
-     *
+     * <p>Set the style for the cell.  The style should be an CellStyle created/retreived from
+     * the Workbook.</p>
+     * 
+     * <p>To change the style of a cell without affecting other cells that use the same style,
+     * use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperties(Cell, Map<String, Object>)}</p>
+     * 
      * @param style  reference contained in the workbook.
      * If the value is null then the style information is removed causing the cell to used the default workbook style.
      * @see org.apache.poi.ss.usermodel.Workbook#createCellStyle()
index b4a17688bf50d9cb58288942756a2a851d8de575..15c7134010123b80828cf93a17dd4dc5cd0cb47a 100644 (file)
@@ -615,9 +615,12 @@ public final class XSSFCell implements Cell {
     }
 
     /**
-     * Set the style for the cell.  The style should be an XSSFCellStyle created/retreived from
-     * the XSSFWorkbook.
+     * <p>Set the style for the cell.  The style should be an XSSFCellStyle created/retreived from
+     * the XSSFWorkbook.</p>
      *
+     * <p>To change the style of a cell without affecting other cells that use the same style,
+     * use {@link org.apache.poi.ss.util.CellUtil#setCellStyleProperties(Cell, Map<String, Object>)}</p>
+     * 
      * @param style  reference contained in the workbook.
      * If the value is null then the style information is removed causing the cell to used the default workbook style.
      * @throws IllegalArgumentException if style belongs to a different styles source (most likely because style is from a different Workbook)
diff --git a/src/testcases/org/apache/poi/ss/util/TestCellUtil.java b/src/testcases/org/apache/poi/ss/util/TestCellUtil.java
new file mode 100644 (file)
index 0000000..6ea3bdb
--- /dev/null
@@ -0,0 +1,88 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+   \r
+   http://www.apache.org/licenses/LICENSE-2.0\r
+   \r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+   ==================================================================== */\r
+\r
+package org.apache.poi.ss.util;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;\r
+import org.apache.poi.ss.usermodel.Cell;\r
+import org.apache.poi.ss.usermodel.CellStyle;\r
+import org.apache.poi.ss.usermodel.Row;\r
+import org.apache.poi.ss.usermodel.Sheet;\r
+import org.apache.poi.ss.usermodel.Workbook;\r
+\r
+import org.junit.Test;\r
+\r
+/**\r
+ * Tests Spreadsheet CellUtil\r
+ *\r
+ * @see org.apache.poi.ss.util.CellUtil\r
+ */\r
+public final class TestCellUtil {\r
+    @Test\r
+    public void testSetCellStyleProperty() throws Exception {\r
+        Workbook wb = new HSSFWorkbook();\r
+        Sheet s = wb.createSheet();\r
+        Row r = s.createRow(0);\r
+        Cell c = r.createCell(0);\r
+\r
+        // Add a border should create a new style\r
+        int styCnt1 = wb.getNumCellStyles();\r
+        CellUtil.setCellStyleProperty(c, wb, CellUtil.BORDER_BOTTOM, CellStyle.BORDER_THIN);\r
+        int styCnt2 = wb.getNumCellStyles();\r
+        assertEquals(styCnt2, styCnt1+1);\r
+\r
+        // Add same border to another cell, should not create another style\r
+        c = r.createCell(1);\r
+        CellUtil.setCellStyleProperty(c, wb, CellUtil.BORDER_BOTTOM, CellStyle.BORDER_THIN);\r
+        int styCnt3 = wb.getNumCellStyles();\r
+        assertEquals(styCnt3, styCnt2);\r
+\r
+        wb.close();\r
+    }\r
+\r
+    @Test\r
+    public void testSetCellStyleProperties() throws Exception {\r
+        Workbook wb = new HSSFWorkbook();\r
+        Sheet s = wb.createSheet();\r
+        Row r = s.createRow(0);\r
+        Cell c = r.createCell(0);\r
+\r
+        // Add multiple border properties to cell should create a single new style\r
+        int styCnt1 = wb.getNumCellStyles();\r
+        Map<String, Object> props = new HashMap<String, Object>();\r
+        props.put(CellUtil.BORDER_TOP, CellStyle.BORDER_THIN);\r
+        props.put(CellUtil.BORDER_BOTTOM, CellStyle.BORDER_THIN);\r
+        props.put(CellUtil.BORDER_LEFT, CellStyle.BORDER_THIN);\r
+        props.put(CellUtil.BORDER_RIGHT, CellStyle.BORDER_THIN);\r
+        CellUtil.setCellStyleProperties(c, props);\r
+        int styCnt2 = wb.getNumCellStyles();\r
+        assertEquals(styCnt2, styCnt1+1);\r
+\r
+        // Add same border another to same cell, should not create another style\r
+        c = r.createCell(1);\r
+        CellUtil.setCellStyleProperties(c, props);\r
+        int styCnt3 = wb.getNumCellStyles();\r
+        assertEquals(styCnt3, styCnt2);\r
+\r
+        wb.close();\r
+    }\r
+}\r