]> source.dussan.org Git - poi.git/commitdiff
Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-63924...
authorNick Burch <nick@apache.org>
Thu, 14 Aug 2008 21:57:00 +0000 (21:57 +0000)
committerNick Burch <nick@apache.org>
Thu, 14 Aug 2008 21:57:00 +0000 (21:57 +0000)
https://svn.apache.org/repos/asf/poi/trunk

........
  r686036 | nick | 2008-08-14 21:50:06 +0100 (Thu, 14 Aug 2008) | 1 line

  Refactor header/footer stuff to remove duplication
........
  r686046 | nick | 2008-08-14 22:25:16 +0100 (Thu, 14 Aug 2008) | 1 line

  Fix bug #45623 - Support stripping HSSF header and footer fields (eg page number) out of header and footer text if required
........
  r686053 | nick | 2008-08-14 22:41:01 +0100 (Thu, 14 Aug 2008) | 1 line

  More for bug #45623 - Support for additional HSSF header and footer fields, including bold and full file path
........

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@686057 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/changes.xml
src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/usermodel/HSSFFooter.java
src/java/org/apache/poi/hssf/usermodel/HSSFHeader.java
src/java/org/apache/poi/hssf/usermodel/HeaderFooter.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFHeaderFooter.java

index 04547c7a91799c2c93472720bc8d8ee6070d022d..09fcd8574be6e5ec8cb0be54fb26775384acb7a9 100644 (file)
@@ -59,7 +59,9 @@
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.1.1-alpha1" date="2008-??-??">
-           <action dev="POI-DEVELOPERS" type="fix">45622 - Support stripping HWPF fields (eg macros) out of text, via Range.stripFields(text)</action>
+           <action dev="POI-DEVELOPERS" type="add">45623 - Support for additional HSSF header and footer fields, including bold and full file path</action>
+           <action dev="POI-DEVELOPERS" type="add">45623 - Support stripping HSSF header and footer fields (eg page number) out of header and footer text if required</action>
+           <action dev="POI-DEVELOPERS" type="add">45622 - Support stripping HWPF fields (eg macros) out of text, via Range.stripFields(text)</action>
            <action dev="POI-DEVELOPERS" type="add">New HPSF based TextExtractor for document metadata, org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor</action>
            <action dev="POI-DEVELOPERS" type="fix">Properly update the array of Slide's text runs in HSLF when new text shapes are added</action>
            <action dev="POI-DEVELOPERS" type="fix">45590 - Fix for Header/footer extraction for .ppt files saved in Office 2007</action>
index a75dc2837a8d9093e18dc275a877b7884b8cb089..282ee631e45c347527e9da3fcc29c75cd8209faa 100644 (file)
@@ -56,7 +56,9 @@
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.1.1-alpha1" date="2008-??-??">
-           <action dev="POI-DEVELOPERS" type="fix">45622 - Support stripping HWPF fields (eg macros) out of text, via Range.stripFields(text)</action>
+           <action dev="POI-DEVELOPERS" type="add">45623 - Support for additional HSSF header and footer fields, including bold and full file path</action>
+           <action dev="POI-DEVELOPERS" type="add">45623 - Support stripping HSSF header and footer fields (eg page number) out of header and footer text if required</action>
+           <action dev="POI-DEVELOPERS" type="add">45622 - Support stripping HWPF fields (eg macros) out of text, via Range.stripFields(text)</action>
            <action dev="POI-DEVELOPERS" type="add">New HPSF based TextExtractor for document metadata, org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor</action>
            <action dev="POI-DEVELOPERS" type="fix">Properly update the array of Slide's text runs in HSLF when new text shapes are added</action>
            <action dev="POI-DEVELOPERS" type="fix">45590 - Fix for Header/footer extraction for .ppt files saved in Office 2007</action>
index d85f1b60e30a0ecc3e0667a5469fcbf9687e7941..4b84dd2f1af5e852a5be3c02036bd5ccc6a1f0f2 100644 (file)
@@ -33,63 +33,16 @@ import org.apache.poi.ss.usermodel.Footer;
  * <P>
  * @author Shawn Laubach (slaubach at apache dot org)
  */
-public class HSSFFooter implements Footer, HeaderFooter {
-    FooterRecord footerRecord;
-    String left;
-    String center;
-    String right;
+public class HSSFFooter extends HeaderFooter implements Footer {
+    private FooterRecord footerRecord;
 
     /**
      * Constructor.  Creates a new footer interface from a footer record
      * @param footerRecord Footer record to create the footer with
      */
     protected HSSFFooter(FooterRecord footerRecord) {
-       this.footerRecord = footerRecord;
-       String foot = footerRecord.getFooter();
-       while (foot != null && foot.length() > 1) {
-           int pos = foot.length();
-           switch (foot.substring(1, 2).charAt(0)) {
-           case 'L' :
-               if (foot.indexOf("&C") >= 0) {
-                   pos = Math.min(pos, foot.indexOf("&C"));
-               } 
-               if (foot.indexOf("&R") >= 0) {
-                   pos = Math.min(pos, foot.indexOf("&R"));
-               } 
-               left = foot.substring(2, pos);
-               foot = foot.substring(pos);
-               break;
-           case 'C' : 
-               if (foot.indexOf("&L") >= 0) {
-                   pos = Math.min(pos, foot.indexOf("&L"));
-               } 
-               if (foot.indexOf("&R") >= 0) {
-                   pos = Math.min(pos, foot.indexOf("&R"));
-               } 
-               center = foot.substring(2, pos);
-               foot = foot.substring(pos);
-               break;
-           case 'R' : 
-               if (foot.indexOf("&C") >= 0) {
-                   pos = Math.min(pos, foot.indexOf("&C"));
-               } 
-               if (foot.indexOf("&L") >= 0) {
-                   pos = Math.min(pos, foot.indexOf("&L"));
-               } 
-               right = foot.substring(2, pos);
-               foot = foot.substring(pos);
-               break;
-           default : foot = null;
-           }
-       }
-    }
-
-    /**
-     * Get the left side of the footer.
-     * @return The string representing the left side.
-     */
-    public String getLeft() {
-       return left;
+       super(footerRecord.getFooter());
+       this.footerRecord = footerRecord;
     }
 
     /**
@@ -101,14 +54,6 @@ public class HSSFFooter implements Footer, HeaderFooter {
        createFooterString();
     }
 
-    /**
-     * Get the center of the footer.
-     * @return The string representing the center.
-     */
-    public String getCenter() {
-       return center;
-    }
-
     /**
      * Sets the center string.
      * @param newCenter The string to set as the center.
@@ -118,14 +63,6 @@ public class HSSFFooter implements Footer, HeaderFooter {
        createFooterString();
     }
 
-    /**
-     * Get the right side of the footer.
-     * @return The string representing the right side.
-     */
-    public String getRight() {
-       return right;
-    }
-
     /**
      * Sets the right string.
      * @param newRight The string to set as the right side.
@@ -146,112 +83,5 @@ public class HSSFFooter implements Footer, HeaderFooter {
                               "&R" + (right == null ? "" : right));
        footerRecord.setFooterLength((byte)footerRecord.getFooter().length());
     }
-
-    /**
-     * Returns the string that represents the change in font size.
-     * @param size the new font size
-     * @return The special string to represent a new font size
-     */
-    public static String fontSize(short size) {
-       return "&" + size;
-    }
-
-    /**
-     * Returns the string that represents the change in font.
-     * @param font the new font
-     * @param style the fonts style
-     * @return The special string to represent a new font size
-     */
-    public static String font(String font, String style) {
-       return "&\"" + font + "," + style + "\"";
-    }
-
-    /**
-     * Returns the string representing the current page number
-     * @return The special string for page number
-     */
-    public static String page() {
-       return "&P";
-    }
-
-    /**
-     * Returns the string representing the number of pages.
-     * @return The special string for the number of pages
-     */
-    public static String numPages() {
-       return "&N";
-    }
-
-    /**
-     * Returns the string representing the current date
-     * @return The special string for the date
-     */
-    public static String date() {
-       return "&D";
-    }
-
-    /**
-     * Returns the string representing the current time
-     * @return The special string for the time
-     */
-    public static String time() {
-       return "&T";
-    }
-
-    /**
-     * Returns the string representing the current file name
-     * @return The special string for the file name
-     */
-    public static String file() {
-       return "&F";
-    }
-
-    /**
-     * Returns the string representing the current tab (sheet) name
-     * @return The special string for tab name
-     */
-    public static String tab() {
-       return "&A";
-    }
-
-    /**
-     * Returns the string representing the start underline
-     *
-     * @return The special string for start underline
-     */
-    public static String startUnderline()
-    {
-        return "&U";
-    }
-
-    /**
-     * Returns the string representing the end underline
-     *
-     * @return The special string for end underline
-     */
-    public static String endUnderline()
-    {
-        return "&U";
-    }
-
-    /**
-     * Returns the string representing the start double underline
-     *
-     * @return The special string for start double underline
-     */
-    public static String startDoubleUnderline()
-    {
-        return "&E";
-    }
-
-    /**
-     * Returns the string representing the end double underline
-     *
-     * @return The special string for end double underline
-     */
-    public static String endDoubleUnderline()
-    {
-        return "&E";
-    }
 }
 
index 535b70efa168449e83d26e7073a92b7d04f41ea5..76bfdbd86b40667f910260a381435c6de45843b6 100644 (file)
@@ -33,78 +33,17 @@ import org.apache.poi.ss.usermodel.Header;
  *
  * @author Shawn Laubach (slaubach at apache dot org)
  */
-public class HSSFHeader implements Header, HeaderFooter
-{
-
-    HeaderRecord headerRecord;
-    String left;
-    String center;
-    String right;
+public class HSSFHeader extends HeaderFooter implements Header {
+       private HeaderRecord headerRecord;
 
     /**
      * Constructor.  Creates a new header interface from a header record
      *
      * @param headerRecord Header record to create the header with
      */
-    protected HSSFHeader( HeaderRecord headerRecord )
-    {
+    protected HSSFHeader( HeaderRecord headerRecord ) {
+       super(headerRecord.getHeader());
         this.headerRecord = headerRecord;
-        String head = headerRecord.getHeader();
-        while ( head != null && head.length() > 1 )
-        {
-            int pos = head.length();
-            switch ( head.substring( 1, 2 ).charAt( 0 ) )
-            {
-                case 'L':
-                    if ( head.indexOf( "&C" ) >= 0 )
-                    {
-                        pos = Math.min( pos, head.indexOf( "&C" ) );
-                    }
-                    if ( head.indexOf( "&R" ) >= 0 )
-                    {
-                        pos = Math.min( pos, head.indexOf( "&R" ) );
-                    }
-                    left = head.substring( 2, pos );
-                    head = head.substring( pos );
-                    break;
-                case 'C':
-                    if ( head.indexOf( "&L" ) >= 0 )
-                    {
-                        pos = Math.min( pos, head.indexOf( "&L" ) );
-                    }
-                    if ( head.indexOf( "&R" ) >= 0 )
-                    {
-                        pos = Math.min( pos, head.indexOf( "&R" ) );
-                    }
-                    center = head.substring( 2, pos );
-                    head = head.substring( pos );
-                    break;
-                case 'R':
-                    if ( head.indexOf( "&C" ) >= 0 )
-                    {
-                        pos = Math.min( pos, head.indexOf( "&C" ) );
-                    }
-                    if ( head.indexOf( "&L" ) >= 0 )
-                    {
-                        pos = Math.min( pos, head.indexOf( "&L" ) );
-                    }
-                    right = head.substring( 2, pos );
-                    head = head.substring( pos );
-                    break;
-                default :
-                    head = null;
-            }
-        }
-    }
-
-    /**
-     * Get the left side of the header.
-     *
-     * @return The string representing the left side.
-     */
-    public String getLeft()
-    {
-        return left;
     }
 
     /**
@@ -118,16 +57,6 @@ public class HSSFHeader implements Header, HeaderFooter
         createHeaderString();
     }
 
-    /**
-     * Get the center of the header.
-     *
-     * @return The string representing the center.
-     */
-    public String getCenter()
-    {
-        return center;
-    }
-
     /**
      * Sets the center string.
      *
@@ -139,16 +68,6 @@ public class HSSFHeader implements Header, HeaderFooter
         createHeaderString();
     }
 
-    /**
-     * Get the right side of the header.
-     *
-     * @return The string representing the right side.
-     */
-    public String getRight()
-    {
-        return right;
-    }
-
     /**
      * Sets the right string.
      *
@@ -172,127 +91,5 @@ public class HSSFHeader implements Header, HeaderFooter
         headerRecord.setHeaderLength( (byte) headerRecord.getHeader().length() );
     }
 
-    /**
-     * Returns the string that represents the change in font size.
-     *
-     * @param size the new font size
-     * @return The special string to represent a new font size
-     */
-    public static String fontSize( short size )
-    {
-        return "&" + size;
-    }
-
-    /**
-     * Returns the string that represents the change in font.
-     *
-     * @param font  the new font
-     * @param style the fonts style
-     * @return The special string to represent a new font size
-     */
-    public static String font( String font, String style )
-    {
-        return "&\"" + font + "," + style + "\"";
-    }
-
-    /**
-     * Returns the string representing the current page number
-     *
-     * @return The special string for page number
-     */
-    public static String page()
-    {
-        return "&P";
-    }
-
-    /**
-     * Returns the string representing the number of pages.
-     *
-     * @return The special string for the number of pages
-     */
-    public static String numPages()
-    {
-        return "&N";
-    }
-
-    /**
-     * Returns the string representing the current date
-     *
-     * @return The special string for the date
-     */
-    public static String date()
-    {
-        return "&D";
-    }
-
-    /**
-     * Returns the string representing the current time
-     *
-     * @return The special string for the time
-     */
-    public static String time()
-    {
-        return "&T";
-    }
-
-    /**
-     * Returns the string representing the current file name
-     *
-     * @return The special string for the file name
-     */
-    public static String file()
-    {
-        return "&F";
-    }
-
-    /**
-     * Returns the string representing the current tab (sheet) name
-     *
-     * @return The special string for tab name
-     */
-    public static String tab()
-    {
-        return "&A";
-    }
-
-    /**
-     * Returns the string representing the start underline
-     *
-     * @return The special string for start underline
-     */
-    public static String startUnderline()
-    {
-        return "&U";
-    }
-
-    /**
-     * Returns the string representing the end underline
-     *
-     * @return The special string for end underline
-     */
-    public static String endUnderline()
-    {
-        return "&U";
-    }
-
-    /**
-     * Returns the string representing the start double underline
-     *
-     * @return The special string for start double underline
-     */
-    public static String startDoubleUnderline()
-    {
-        return "&E";
-    }
-
-    /**
-     * Returns the string representing the end double underline
-     *
-     * @return The special string for end double underline
-     */
-    public static String endDoubleUnderline()
-    {
-        return "&E";
-    }
 }
 
index 44dfd7956700dd4bcc0afca27cd4a1401748f52e..499cda7920aadb7b9dbe7b9639f40989cc3f7da3 100644 (file)
 ==================================================================== */
 package org.apache.poi.hssf.usermodel;
 
+import java.util.ArrayList;
+
 /**
- * Common interface for {@link HSSFHeader} and
+ * Common class for {@link HSSFHeader} and
  *  {@link HSSFFooter}.
  */
-public interface HeaderFooter extends org.apache.poi.ss.usermodel.HeaderFooter {
+public abstract class HeaderFooter implements org.apache.poi.ss.usermodel.HeaderFooter {
+       protected String left;
+       protected String center;
+       protected String right;
+       
+       private boolean stripFields = false;
+       
+       protected HeaderFooter(String text) {
+               while (text != null && text.length() > 1) {
+                   int pos = text.length();
+                   switch (text.substring(1, 2).charAt(0)) {
+                           case 'L' :
+                               if (text.indexOf("&C") >= 0) {
+                                   pos = Math.min(pos, text.indexOf("&C"));
+                               } 
+                               if (text.indexOf("&R") >= 0) {
+                                   pos = Math.min(pos, text.indexOf("&R"));
+                               } 
+                               left = text.substring(2, pos);
+                               text = text.substring(pos);
+                               break;
+                   case 'C' : 
+                               if (text.indexOf("&L") >= 0) {
+                                   pos = Math.min(pos, text.indexOf("&L"));
+                               } 
+                               if (text.indexOf("&R") >= 0) {
+                                   pos = Math.min(pos, text.indexOf("&R"));
+                               } 
+                               center = text.substring(2, pos);
+                               text = text.substring(pos);
+                               break;
+                   case 'R' : 
+                               if (text.indexOf("&C") >= 0) {
+                                   pos = Math.min(pos, text.indexOf("&C"));
+                               } 
+                               if (text.indexOf("&L") >= 0) {
+                                   pos = Math.min(pos, text.indexOf("&L"));
+                               } 
+                               right = text.substring(2, pos);
+                               text = text.substring(pos);
+                               break;
+                   default: 
+                       text = null;
+                   }
+               }
+       }
+       
+    /**
+     * Get the left side of the header or footer.
+     * @return The string representing the left side.
+     */
+    public String getLeft() {
+       if(stripFields)
+               return stripFields(left);
+               return left;
+       }
+    public abstract void setLeft( String newLeft );
+
+    /**
+     * Get the center of the header or footer.
+     * @return The string representing the center.
+     */
+    public String getCenter() {
+       if(stripFields)
+               return stripFields(center);
+       return center;
+    }
+    public abstract void setCenter( String newCenter );
+
+    /**
+     * Get the right side of the header or footer.
+     * @return The string representing the right side.
+     */
+    public String getRight() {
+       if(stripFields)
+               return stripFields(right);
+       return right;
+    }
+    public abstract void setRight( String newRight );
+
+
+    /**
+     * Returns the string that represents the change in font size.
+     *
+     * @param size the new font size
+     * @return The special string to represent a new font size
+     */
+    public static String fontSize( short size )
+    {
+        return "&" + size;
+    }
+
+    /**
+     * Returns the string that represents the change in font.
+     *
+     * @param font  the new font
+     * @param style the fonts style, one of regular, italic, bold, italic bold or bold italic
+     * @return The special string to represent a new font size
+     */
+    public static String font( String font, String style )
+    {
+        return "&\"" + font + "," + style + "\"";
+    }
+
+    /**
+     * Returns the string representing the current page number
+     *
+     * @return The special string for page number
+     */
+    public static String page() {
+       return PAGE_FIELD.sequence;
+    }
+
+    /**
+     * Returns the string representing the number of pages.
+     *
+     * @return The special string for the number of pages
+     */
+    public static String numPages() {
+       return NUM_PAGES_FIELD.sequence;
+    }
+
+    /**
+     * Returns the string representing the current date
+     *
+     * @return The special string for the date
+     */
+    public static String date() {
+       return DATE_FIELD.sequence;
+    }
+
+    /**
+     * Returns the string representing the current time
+     *
+     * @return The special string for the time
+     */
+    public static String time() {
+       return TIME_FIELD.sequence;
+    }
+
+    /**
+     * Returns the string representing the current file name
+     *
+     * @return The special string for the file name
+     */
+    public static String file() {
+       return FILE_FIELD.sequence;
+    }
+
+    /**
+     * Returns the string representing the current tab (sheet) name
+     *
+     * @return The special string for tab name
+     */
+    public static String tab() {
+       return SHEET_NAME_FIELD.sequence;
+    }
+
+    /**
+     * Returns the string representing the start bold
+     *
+     * @return The special string for start bold
+     */
+    public static String startBold() {
+       return BOLD_FIELD.sequence;
+    }
+
+    /**
+     * Returns the string representing the end bold
+     *
+     * @return The special string for end bold
+     */
+    public static String endBold() {
+       return BOLD_FIELD.sequence;
+    }
+
+    /**
+     * Returns the string representing the start underline
+     *
+     * @return The special string for start underline
+     */
+    public static String startUnderline() {
+       return UNDERLINE_FIELD.sequence;
+    }
+
+    /**
+     * Returns the string representing the end underline
+     *
+     * @return The special string for end underline
+     */
+    public static String endUnderline() {
+       return UNDERLINE_FIELD.sequence;
+    }
+
+    /**
+     * Returns the string representing the start double underline
+     *
+     * @return The special string for start double underline
+     */
+    public static String startDoubleUnderline() {
+       return DOUBLE_UNDERLINE_FIELD.sequence;
+    }
+
+    /**
+     * Returns the string representing the end double underline
+     *
+     * @return The special string for end double underline
+     */
+    public static String endDoubleUnderline() {
+       return DOUBLE_UNDERLINE_FIELD.sequence;
+    }
+    
+    
+    /**
+     * Removes any fields (eg macros, page markers etc)
+     *  from the string.
+     * Normally used to make some text suitable for showing
+     *  to humans, and the resultant text should not normally
+     *  be saved back into the document!
+     */
+    public static String stripFields(String text) {
+       int pos;
+       
+       // Firstly, do the easy ones which are static
+       for(int i=0; i<Field.ALL_FIELDS.size(); i++) {
+               String seq = ((Field)Field.ALL_FIELDS.get(i)).sequence;
+               while((pos = text.indexOf(seq)) > -1) {
+                       text = text.substring(0, pos) +
+                               text.substring(pos+seq.length());
+               }
+       }
+       
+       // Now do the tricky, dynamic ones
+       text = text.replaceAll("\\&\\d+", "");
+       text = text.replaceAll("\\&\".*?,.*?\"", "");
+       
+       // All done
+       return text;
+    }
+    
+       
+       /**
+        * Are fields currently being stripped from
+        *  the text that this {@link HeaderStories} returns?
+        *  Default is false, but can be changed
+        */
+       public boolean areFieldsStripped() {
+               return stripFields;
+       }
+       /**
+        * Should fields (eg macros) be stripped from
+        *  the text that this class returns?
+        * Default is not to strip.
+        * @param stripFields
+        */
+       public void setAreFieldsStripped(boolean stripFields) {
+               this.stripFields = stripFields;
+       }
+
+    
+    public static final Field SHEET_NAME_FIELD = new Field("&A");
+    public static final Field DATE_FIELD = new Field("&D");
+    public static final Field FILE_FIELD = new Field("&F");
+    public static final Field FULL_FILE_FIELD = new Field("&Z");
+    public static final Field PAGE_FIELD = new Field("&P");
+    public static final Field TIME_FIELD = new Field("&T");
+    public static final Field NUM_PAGES_FIELD = new Field("&N");
+    
+    public static final Field PICTURE_FIELD = new Field("&P");
+    
+    public static final PairField BOLD_FIELD = new PairField("&B"); // PAID
+    public static final PairField ITALIC_FIELD = new PairField("&I");
+    public static final PairField STRIKETHROUGH_FIELD = new PairField("&S");
+    public static final PairField SUBSCRIPT_FIELD = new PairField("&Y");
+    public static final PairField SUPERSCRIPT_FIELD = new PairField("&X");
+    public static final PairField UNDERLINE_FIELD = new PairField("&U");
+    public static final PairField DOUBLE_UNDERLINE_FIELD = new PairField("&E");
+    
+    /**
+     * Represents a special field in a header or footer,
+     *  eg the page number
+     */
+    public static class Field {
+       private static ArrayList ALL_FIELDS = new ArrayList();
+       /** The character sequence that marks this field */
+       public final String sequence;
+       private Field(String sequence) {
+               this.sequence = sequence;
+               ALL_FIELDS.add(this);
+       }
+    }
+    /**
+     * A special field that normally comes in a pair, eg
+     *  turn on underline / turn off underline
+     */
+    public static class PairField extends Field {
+       private PairField(String sequence) {
+               super(sequence);
+       }
+    }
 }
index ddc95355530f32e79afead1a2bbcb721386254aa..caa75633b0668ccb0e1c9c3233ecf4e89a980660 100644 (file)
 
 package org.apache.poi.hssf.usermodel;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
@@ -49,6 +44,52 @@ public final class TestHSSFHeaderFooter extends TestCase {
        assertEquals("Top Center", head.getCenter());
        assertEquals("Top Right", head.getRight());
        }
+       
+       public void testSpecialChars() {
+               assertEquals("&U", HSSFHeader.startUnderline());
+               assertEquals("&U", HSSFHeader.endUnderline());
+               assertEquals("&P", HSSFHeader.page());
+               
+               assertEquals("&22", HSSFFooter.fontSize((short)22));
+               assertEquals("&\"Arial,bold\"", HSSFFooter.font("Arial", "bold"));
+       }
+       
+       public void testStripFields() {
+               String simple = "I am a test header";
+               String withPage = "I am a&P test header";
+               String withLots = "I&A am&N a&P test&T header&U";
+               String withFont = "I&22 am a&\"Arial,bold\" test header";
+               String withOtherAnds = "I am a&P test header&&";
+               String withOtherAnds2 = "I am a&P test header&a&b";
+               
+               assertEquals(simple, HSSFHeader.stripFields(simple));
+               assertEquals(simple, HSSFHeader.stripFields(withPage));
+               assertEquals(simple, HSSFHeader.stripFields(withLots));
+               assertEquals(simple, HSSFHeader.stripFields(withFont));
+               assertEquals(simple + "&&", HSSFHeader.stripFields(withOtherAnds));
+               assertEquals(simple + "&a&b", HSSFHeader.stripFields(withOtherAnds2));
+               
+               // Now test the default strip flag
+               HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("EmbeddedChartHeaderTest.xls");
+               HSSFSheet s = wb.getSheetAt( 0 );
+       HSSFHeader head = s.getHeader();
+    
+       assertEquals("Top Left", head.getLeft());
+       assertEquals("Top Center", head.getCenter());
+       assertEquals("Top Right", head.getRight());
+       
+       head.setLeft("Top &P&F&D Left");
+       assertEquals("Top &P&F&D Left", head.getLeft());
+       assertFalse(head.areFieldsStripped());
+       
+       head.setAreFieldsStripped(true);
+       assertEquals("Top  Left", head.getLeft());
+       assertTrue(head.areFieldsStripped());
+       
+       // Now even more complex
+       head.setCenter("HEADER TEXT &P&N&D&T&Z&F&F&A&G");
+       assertEquals("HEADER TEXT &G", head.getCenter());
+       }
 
        /**
         * Tests that get header retreives the proper values.