]> source.dussan.org Git - poi.git/commitdiff
fixed setting named styles to HSSFCells. see Bugzilla 50912
authorYegor Kozlov <yegor@apache.org>
Fri, 11 Mar 2011 17:33:36 +0000 (17:33 +0000)
committerYegor Kozlov <yegor@apache.org>
Fri, 11 Mar 2011 17:33:36 +0000 (17:33 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1080689 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
src/testcases/org/apache/poi/hssf/usermodel/TestCellStyle.java

index 435cf869559e3b159e8dce0b7eb88c891986335f..67b632793fcb372f6530f8a5ebb0c7b220f6af74 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.8-beta2" date="2011-??-??">
+           <action dev="poi-developers" type="fix">50912 - fixed setting named styles to HSSFCells</action>
            <action dev="poi-developers" type="fix">50779 - fixed RecordFormatException when reading unicode strings with photenic data</action>
            <action dev="poi-developers" type="fix">50718 - More helpful error message when you try to create a CellReference with #REF!</action>
            <action dev="poi-developers" type="fix">50784 - XSSFColors return by XSSFFont now have theme information applied to them</action>
index 2e7bf09b062fa3997fa776d0e721e0b2ab8fe263..d89c86760e533b04c7aaaad7c04c6e381792de46 100644 (file)
@@ -907,8 +907,15 @@ public class HSSFCell implements Cell {
         // Verify it really does belong to our workbook
         style.verifyBelongsToWorkbook(_book);
 
+        short styleIndex;
+        if(style.getUserStyleName() != null) {
+            styleIndex = applyUserCellStyle(style);
+        } else {
+            styleIndex = style.getIndex();
+        }
+
         // Change our cell record to use this style
-        _record.setXFIndex(style.getIndex());
+        _record.setXFIndex(styleIndex);
     }
 
     /**
@@ -1245,4 +1252,49 @@ public class HSSFCell implements Cell {
         notifyArrayFormulaChanging(msg);
     }
 
+    /**
+     * Applying a user-defined style (UDS) is special. Excel does not directly reference user-defined styles, but
+     * instead create a 'proxy' ExtendedFormatRecord referencing the UDS as parent.
+     *
+     * The proceudre to apply a UDS is as follows:
+     *
+     * 1. search for a ExtendedFormatRecord with parentIndex == style.getIndex()
+     *    and xfType ==  ExtendedFormatRecord.XF_CELL.
+     * 2. if not found then create a new ExtendedFormatRecord and copy all attributes from the user-defined style
+     *    and set the parentIndex to be style.getIndex()
+     * 3. return the index of the ExtendedFormatRecord, this will be assigned to the parent cell record
+     *
+     * @param style  the user style to apply
+     *
+     * @return  the index of a ExtendedFormatRecord record that will be referenced by the cell
+     */
+    private short applyUserCellStyle(HSSFCellStyle style){
+        if(style.getUserStyleName() == null) {
+            throw new IllegalArgumentException("Expected user-defined style");
+        }
+
+        InternalWorkbook iwb = _book.getWorkbook();
+        short userXf = -1;
+        int numfmt = iwb.getNumExFormats();
+        for(short i = 0; i < numfmt; i++){
+            ExtendedFormatRecord xf = iwb.getExFormatAt(i);
+            if(xf.getXFType() == ExtendedFormatRecord.XF_CELL && xf.getParentIndex() == style.getIndex() ){
+                userXf = i;
+                break;
+            }
+        }
+        short styleIndex;
+        if (userXf == -1){
+            ExtendedFormatRecord xfr = iwb.createCellXF();
+            xfr.cloneStyleFrom(iwb.getExFormatAt(style.getIndex()));
+            xfr.setIndentionOptions((short)0);
+            xfr.setXFType(ExtendedFormatRecord.XF_CELL);
+            xfr.setParentIndex(style.getIndex());
+            styleIndex = (short)numfmt;
+        } else {
+            styleIndex = userXf;
+        }
+
+        return styleIndex;
+    }
 }
index d65cb4ebceeb1c31db29d8ff46e4f738576b3847..6e2f9fe133779340deae257cd2e006183bbae995 100644 (file)
@@ -69,12 +69,14 @@ public final class HSSFCellStyle implements CellStyle {
      *  cases there'll be a fully defined parent.
      */
     public HSSFCellStyle getParentStyle() {
-       if(_format.getParentIndex() == 0) {
+        short parentIndex = _format.getParentIndex();
+        // parentIndex equal 0xFFF indicates no inheritance from a cell style XF (See 2.4.353 XF)
+       if(parentIndex == 0 || parentIndex == 0xFFF) {
                return null;
        }
        return new HSSFCellStyle(
-                       _format.getParentIndex(),
-                       _workbook.getExFormatAt(_format.getParentIndex()),
+                       parentIndex,
+                       _workbook.getExFormatAt(parentIndex),
                        _workbook
        );
     }
index 17ad850d7f479188b8658a004b1806f41e5ef85c..baaad8c425f5314dc28c795521ede16d0b59a3af 100644 (file)
 
 package org.apache.poi.hssf.usermodel;
 
+import junit.framework.TestCase;
+import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.util.TempFile;
+
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.Calendar;
 import java.util.Date;
 
-import junit.framework.TestCase;
-
-import org.apache.poi.hssf.HSSFTestDataSamples;
-import org.apache.poi.util.TempFile;
-
 /**
  * Class to test cell styling functionality
  *
@@ -326,5 +325,11 @@ public final class TestCellStyle extends TestCase {
         assertEquals(null, cs3.getUserStyleName());
         assertEquals("style1", cs2.getParentStyle().getUserStyleName());
         assertEquals("style2", cs3.getParentStyle().getUserStyleName());
+
+        // now apply a named style to a new cell
+        HSSFCell c4 = s.getRow(0).createCell(1);
+        c4.setCellStyle(cs2);
+        assertEquals("style1", c4.getCellStyle().getParentStyle().getUserStyleName());
     }
+
 }