NPOI 1.2.3实现Excel 2007(.xls)页眉/页脚:奇偶页不同、与页边距对齐

       最近在做一个项目,需要将数据输出的Excel文件中。使用C#引用Excel COM对象创建Excel文件,速度很慢,所有选用的开源的NPOI创建Excel文件。NPOI是一个开源的在没有安装微软Office的情况下读写Office 97-2003的文件的.NET 2.0类库,最新版本是1.2.4 alpha,官方网站为:http://npoi.codeplex.com/(源码和更多例子请到这里下载)。NPOI具体用法请参考:http://www.cnblogs.com/atao/archive/2009/11/15/1603528.html。此项目选用的是NPOI 1.2.3正式版。

       在NPOI 1.2.3中,通过HSSFHeader类设置页眉,HSSFFooter类设置页脚,可以设置三种页眉/页脚——左、中、右,HSSFHeader/HSSFFooter类不支持Excel2007中页眉/页脚奇偶页不同、首页不同。在Excel 2000-2003中,页眉页脚距纸张边界距离为1英寸,而我做的这个项目输出的Excel文件中右上角单元格为页码,且距纸张边界小于1英寸,这样生成的文档在打印时页码显示的位置就不正确了,需要用户在打印之前,现在Office 2007中将页面设置中的页眉/页脚选项卡中选中“与页边距对齐”选项,这样以来,给用户造成了一定的负担。

image

       通过查阅微软发布的《MICROSOFT OFFICE EXCEL 97-2007 BINARY FILE FORMAT SPECIFICATION [*.xls (97-2007) format]》文档得知,在Excel 2007的xls格式中,新增了一个新的记录块叫HeaderFooterRecord(089Ch),用来专门设置Excel 2007的页眉/页脚:

The HEADERFOOTER record stores information added in Office Excel 2007 for headers/footers.

 
Offset Name Size Contents 
4rt 2Record type; this matches the BIFF rt in thefirst two bytes of the record; =089Ch 
6grbitFrt 2FRT cell reference flag; =0 currently 
8(Reserved) 8Currently not used, and set to 0 
16guidSview 16If this header FRT belongs to a specific sheetview (sview), the sheet view‘s GUID will be saved here. 
32grbitFlags 2see text 
34cchHeaderEven 2length of even header text 
36cchFooterEven 2length of even footer text 
38cchHeaderFirst 2length of first page header text 
40cchFooterFirst 2length of first page footer text 
42rgchHeaderEven var even header text if non-zero length 
var rgchFooterEven var even footer text if non-zero length 
var rgchHeaderFirst var first page header text if non-zero length 
var rgchFooterFirst var first page footer text if non-zero length 

The grbitFlags field contains the fields listed in the following table.

 
Bits Mask Name Contents 
00001h fHFDiffOddEven =1 if different odd/even pages 
10002h fHFDiffFirst =1 if different first page 
20004h fHFScaleWithDoc =1 scales header/footer with document 
30008h fHFAlignMargins =1 align header/footer with pagemargins 
4..15 FFF0h (Reserved) Reserved; must be 0 (zero)

 

        翻看NPOI 1.2.3源码,并没有找到HeaderFooterRecord对应的类,而在NPOI.HSSF.Record.UnknownRecord类中找到089C,这说明在NPOI 1.2.3中,并不支持HeaderFooterRecord。换用NPOI 1.2.4 alpha版本,在NPOI中找到HeaderFooterRecord类,但该类成员中并没有设页眉/页脚的成员。随决定修改NPOI 1.2.3源码,自己实现HeaderFooterRecord。

        首先,在NPOI.HSSF.Record命名空间中新增HeaderFooterRecord类,实现HeaderFooterRecord二进制读取与输出。代码如下:

   1: namespace NPOI.HSSF.Record
   2: {
   3:  
   4:     using System;
   5:     using System.Text;
   6:     using System.Collections;
   7:  
   8:     using NPOI.Util;
   9:     using NPOI.HSSF.Model;
  10:     using NPOI.HSSF.Record;
  11:     using NPOI.HSSF.Util;
  12:     using NPOI.HSSF.UserModel;
  13:     using NPOI.HSSF.Record.Formula;
  14:     using SSFormula = NPOI.SS.Formula;
  15:  
  16:     /**
  17:      * Title:        Header Footer Record  
  18:      * Description:  This record specifies the even page header and footer text, and the first page header and footer text of the current sheet.
  19:      * REFERENCE:  
  20:      * @author Junjie Wang 
  21:      * @version 1.0-pre
  22:      */
  23:     public class HeaderFooterRecord : StandardRecord
  24:     {
  25:         private enum Option : short
  26:         {
  27:             OPT_DIFF_ODD_EVEN = 0x0001,
  28:             OPT_DIFF_FIRST = 0x0002,
  29:             OPT_SCALE_WITH_DOC = 0x0004,
  30:             OPT_ALIGN_MARGINS = 0x0008,
  31:         }
  32:  
  33:  
  34:         /**
  35:          */
  36:         public const short sid = 0x89C;
  37:  
  38:  
  39:         private short field_1_option_flag;
  40:         private GUID field_2_sview_guid;
  41:         //private short field_3_Length_header_even_text;
  42:         //private short field_4_Length_footer_even_text;
  43:         //private short field_5_Length_header_first_text;
  44:         //private short field_6_Length_footer_first_text;
  45:         private string field_7_header_even_text;
  46:         private string field_8_footer_even_text;
  47:         private string field_9_header_first_text;
  48:         private string field_10_footer_first_text;
  49:  
  50:  
  51:         /** Creates new NameRecord */
  52:         public HeaderFooterRecord()
  53:         {
  54:             this.field_1_option_flag = (short)((short)Option.OPT_ALIGN_MARGINS | (short)Option.OPT_SCALE_WITH_DOC);
  55:             this.field_2_sview_guid = new GUID(0, 0, 0, 0);
  56:             this.field_7_header_even_text = "";
  57:             this.field_8_footer_even_text = "";
  58:             this.field_9_header_first_text = "";
  59:             this.field_10_footer_first_text = "";
  60:         }
  61:         protected override int DataSize
  62:         {
  63:             get
  64:             {
  65:                 return 38
  66:                     + (field_7_header_even_text.Length > 0 ? field_7_header_even_text.Length + 3 : 0)
  67:                         + (field_8_footer_even_text.Length > 0 ? field_8_footer_even_text.Length + 3 : 0)
  68:                         + (field_9_header_first_text.Length > 0 ? field_9_header_first_text.Length + 3 : 0)
  69:                         + (field_10_footer_first_text.Length > 0 ? field_10_footer_first_text.Length + 3 : 0);
  70:             }
  71:         }
  72:         /**
  73:          * Constructs a Name record and Sets its fields appropriately.
  74:          *
  75:          * @param in the RecordInputstream to Read the record from
  76:          */
  77:         public HeaderFooterRecord(RecordInputStream in1)
  78:         {
  79:             in1.ReadShort();
  80:             in1.ReadShort();
  81:             in1.ReadLong();
  82:             this.field_2_sview_guid = new GUID(in1);
  83:             this.field_1_option_flag = in1.ReadShort();
  84:  
  85:             int field_3_Length_header_even_text = in1.ReadShort();
  86:             int field_4_Length_footer_even_text = in1.ReadShort();
  87:             int field_5_Length_header_first_text = in1.ReadShort();
  88:             int field_6_Length_footer_first_text = in1.ReadShort();
  89:  
  90:             this.field_7_header_even_text = "";
  91:             this.field_8_footer_even_text = "";
  92:             this.field_9_header_first_text = "";
  93:             this.field_10_footer_first_text = "";
  94:             if (field_3_Length_header_even_text > 0)
  95:             {
  96:                 this.field_7_header_even_text = StringUtil.ReadUnicodeString(in1);
  97:             }
  98:             if (field_4_Length_footer_even_text > 0)
  99:             {
 100:                 this.field_8_footer_even_text = StringUtil.ReadUnicodeString(in1);
 101:             }
 102:             if (field_5_Length_header_first_text > 0)
 103:             {
 104:                 this.field_9_header_first_text = StringUtil.ReadUnicodeString(in1);
 105:             }
 106:             if (field_6_Length_footer_first_text > 0)
 107:             {
 108:                 this.field_10_footer_first_text = StringUtil.ReadUnicodeString(in1);
 109:             }
 110:  
 111:         }
 112:  
 113:  
 114:  
 115:  
 116:         /**
 117:          * Gets the specific sheet view‘s GUID
 118:          * @return the specific sheet view‘s GUID
 119:          * @see GUIDRecord
 120:          */
 121:         public GUID SViewGuid
 122:         {
 123:             get
 124:             {
 125:                 return this.field_2_sview_guid;
 126:             }
 127:             set
 128:             {
 129:                 field_2_sview_guid = value;
 130:             }
 131:         }
 132:  
 133:         /** Gets the option flag
 134:          * @return option flag
 135:          */
 136:         public short OptionFlag
 137:         {
 138:             get
 139:             {
 140:                 return field_1_option_flag;
 141:             }
 142:             set
 143:             {
 144:                 field_1_option_flag = value;
 145:             }
 146:         }
 147:  
 148:  
 149:         public bool IsDiffOddEven
 150:         {
 151:             get
 152:             {
 153:                 return (this.field_1_option_flag & (short)Option.OPT_DIFF_ODD_EVEN) != 0;
 154:             }
 155:             set
 156:             {
 157:                 field_1_option_flag = (short)(field_1_option_flag | (short)Option.OPT_DIFF_ODD_EVEN);
 158:             }
 159:         }
 160:  
 161:         public bool IsDiffFirst
 162:         {
 163:             get
 164:             {
 165:                 return (this.field_1_option_flag & (short)Option.OPT_DIFF_FIRST) != 0;
 166:             }
 167:             set
 168:             {
 169:                 field_1_option_flag = (short)(field_1_option_flag | (short)Option.OPT_DIFF_FIRST);
 170:             }
 171:         }
 172:  
 173:         public bool IsScaleWithDoc
 174:         {
 175:             get
 176:             {
 177:                 return (this.field_1_option_flag & (short)Option.OPT_SCALE_WITH_DOC) != 0;
 178:             }
 179:             set
 180:             {
 181:                 field_1_option_flag = (short)(field_1_option_flag | (short)Option.OPT_SCALE_WITH_DOC);
 182:             }
 183:         }
 184:  
 185:         public bool IsAlignMargins
 186:         {
 187:             get
 188:             {
 189:                 return (this.field_1_option_flag & (short)Option.OPT_ALIGN_MARGINS) != 0;
 190:             }
 191:             set
 192:             {
 193:                 field_1_option_flag = (short)(field_1_option_flag | (short)Option.OPT_ALIGN_MARGINS);
 194:             }
 195:         }
 196:  
 197:  
 198:         public int HeaderEvenTextLength
 199:         {
 200:             get
 201:             {
 202:                 return this.field_7_header_even_text.Length;
 203:             }
 204:         }
 205:  
 206:         public int FooterEvenTextLength
 207:         {
 208:             get
 209:             {
 210:                 return this.field_8_footer_even_text.Length;
 211:             }
 212:         }
 213:  
 214:         public int HeaderFirsTtextLength
 215:         {
 216:             get
 217:             {
 218:                 return this.field_9_header_first_text.Length;
 219:             }
 220:         }
 221:  
 222:         public int FooterFirsTtextLength
 223:         {
 224:             get
 225:             {
 226:                 return this.field_10_footer_first_text.Length;
 227:             }
 228:         }
 229:  
 230:         public string HeaderEvenText
 231:         {
 232:             get
 233:             {
 234:                 return this.field_7_header_even_text;
 235:             }
 236:             set
 237:             {
 238:                 if (this.IsDiffOddEven)
 239:                 {
 240:                     this.field_7_header_even_text = value;
 241:                 }
 242:                 else
 243:                 {
 244:                     this.field_7_header_even_text = "";
 245:                 }
 246:             }
 247:         }
 248:  
 249:         public string FooterEvenText
 250:         {
 251:             get
 252:             {
 253:                 return this.field_8_footer_even_text;
 254:             }
 255:             set
 256:             {
 257:                 if (this.IsDiffOddEven)
 258:                 {
 259:                     this.field_8_footer_even_text = value;
 260:                 }
 261:                 else
 262:                 {
 263:                     this.field_8_footer_even_text = "";
 264:                 }
 265:             }
 266:         }
 267:  
 268:         public string HeaderFirsText
 269:         {
 270:             get
 271:             {
 272:                 return this.field_9_header_first_text;
 273:             }
 274:             set
 275:             {
 276:                 if (this.IsDiffFirst)
 277:                 {
 278:                     this.field_9_header_first_text = value;
 279:                 }
 280:                 else
 281:                 {
 282:                     this.field_9_header_first_text = "";
 283:                 }
 284:             }
 285:         }
 286:  
 287:         public string FooterFirsText
 288:         {
 289:             get
 290:             {
 291:                 return this.field_10_footer_first_text;
 292:             }
 293:             set
 294:             {
 295:                 if (this.IsDiffFirst)
 296:                 {
 297:                     this.field_10_footer_first_text = value;
 298:                 }
 299:                 else
 300:                 {
 301:                     this.field_10_footer_first_text = "";
 302:                 }
 303:             }
 304:         }
 305:  
 306:  
 307:  
 308:         /**
 309:          * called by the class that Is responsible for writing this sucker.
 310:          * Subclasses should implement this so that their data Is passed back in a
 311:          * @param offset to begin writing at
 312:          * @param data byte array containing instance data
 313:          * @return number of bytes written
 314:          */
 315:         public override void Serialize(NPOI.Util.IO.LittleEndianOutput out1)
 316:         {
 317:             out1.WriteShort(this.Sid);
 318:             out1.WriteShort(0);
 319:             out1.WriteLong(0);
 320:             this.SViewGuid.Serialize(out1);
 321:             out1.WriteShort(OptionFlag);
 322:             out1.WriteShort((short)this.field_7_header_even_text.Length);
 323:             out1.WriteShort((short)this.field_8_footer_even_text.Length);
 324:             out1.WriteShort((short)this.field_9_header_first_text.Length);
 325:             out1.WriteShort((short)this.field_10_footer_first_text.Length);
 326:             if (this.field_7_header_even_text.Length > 0)
 327:             {
 328:                 StringUtil.WriteUnicodeString(out1, this.field_7_header_even_text);
 329:             }
 330:             if (this.field_8_footer_even_text.Length > 0)
 331:             {
 332:                 StringUtil.WriteUnicodeString(out1, this.field_8_footer_even_text);
 333:             }
 334:             if (this.field_9_header_first_text.Length > 0)
 335:             {
 336:                 StringUtil.WriteUnicodeString(out1, this.field_9_header_first_text);
 337:             }
 338:             if (this.field_10_footer_first_text.Length > 0)
 339:             {
 340:                 StringUtil.WriteUnicodeString(out1, this.field_10_footer_first_text);
 341:             }
 342:         }
 343:  
 344:  
 345:         /**
 346:          * return the non static version of the id for this record.
 347:          */
 348:         public override short Sid
 349:         {
 350:             get
 351:             {
 352:                 return sid;
 353:             }
 354:         }
 355:  
 356:  
 357:         /**
 358:          * @see Object#ToString()
 359:          */
 360:         public override String ToString()
 361:         {
 362:             StringBuilder buffer = new StringBuilder();
 363:  
 364:             buffer.Append("[HeaderFooter]\n");
 365:             buffer.Append("    .option flags         = ").Append(HexDump.ToHex(field_1_option_flag))
 366:                 .Append("\n");
 367:             buffer.Append("    .is different odd/even pages    = ").Append(this.IsDiffOddEven)
 368:                 .Append("\n");
 369:             buffer.Append("    .is different first page   = ").Append(this.IsDiffFirst)
 370:                 .Append("\n");
 371:             buffer.Append("    .is scales header/footer with document  = ").Append(this.IsScaleWithDoc)
 372:                 .Append("\n");
 373:             buffer.Append("    .is align header/footer with page margins  = ").Append(this.IsAlignMargins)
 374:                 .Append("\n");
 375:             buffer.Append("    .even header text  = ").Append(field_7_header_even_text)
 376:                 .Append("\n");
 377:             buffer.Append("    .even footer text = ").Append(field_8_footer_even_text)
 378:                 .Append("\n");
 379:             buffer.Append("    .first page header text  = ").Append(field_9_header_first_text)
 380:                 .Append("\n");
 381:             buffer.Append("    .first page footer text  = ").Append(field_10_footer_first_text)
 382:                 .Append("\n");
 383:             buffer.Append("[/HeaderFooter]\n");
 384:  
 385:             return buffer.ToString();
 386:         }
 387:  
 388:  
 389:     }
 390: }

然后修改NPOI.HSSF.Record.Aggregates.PageSettingsBlock类,添加HeaderFooterRecord类实例,即在创建Sheet时,创建HeaderFooterRecord块,从文件中读取时,读取HeaderFooterRecord块。

   1: namespace NPOI.HSSF.Record.Aggregates
   2: {
   3:  
   4:     using System;
   5:     using System.Text;
   6:     using System.Collections;
   7:     using NPOI.HSSF.Model;
   8:     using NPOI.HSSF.Record;
   9:     using NPOI.HSSF.Util;
  10:     /**
  11:      * Groups the page settings records for a worksheet.<p/>
  12:      * 
  13:      * See OOO excelfileformat.pdf sec 4.4 'Page Settings Block'
  14:      * 
  15:      * @author Josh Micich
  16:      */
  17:     public class PageSettingsBlock : RecordAggregate
  18:     {
  19:         // Every one of these component records is optional 
  20:         // (The whole PageSettingsBlock may not be present) 
  21:         private PageBreakRecord _rowBreaksRecord;
  22:         private PageBreakRecord _columnBreaksRecord;
  23:         private HeaderRecord header;
  24:         private FooterRecord footer;
  25:         private HeaderFooterRecord _headerfooter;
  26:         private HCenterRecord _hCenter;
  27:         private VCenterRecord _vCenter;
  28:         private LeftMarginRecord _leftMargin;
  29:         private RightMarginRecord _rightMargin;
  30:         private TopMarginRecord _topMargin;
  31:         private BottomMarginRecord _bottomMargin;
  32:         private Record _pls;
  33:         private PrintSetupRecord printSetup;
  34:         private Record _bitmap;
  35:  
  36:         private ArrayList _rowRecords;
  37:  
  38:         public PageSettingsBlock(RecordStream rs)
  39:         {
  40:             _rowRecords = new ArrayList();
  41:             while (ReadARecord(rs)) ;
  42:         }
  43:  
  44:         /**
  45:          * Creates a PageSettingsBlock with default settings
  46:          */
  47:         public PageSettingsBlock()
  48:         {
  49:             _rowBreaksRecord = new HorizontalPageBreakRecord();
  50:             _columnBreaksRecord = new VerticalPageBreakRecord();
  51:             _rowRecords = new ArrayList();
  52:             header = new HeaderRecord(string.Empty);
  53:             footer = new FooterRecord(string.Empty);
  54:            _headerfooter= new HeaderFooterRecord();
  55:             _hCenter = CreateHCenter();
  56:             _vCenter = CreateVCenter();
  57:             printSetup = CreatePrintSetup();
  58:         }
  59:         public override void Dispose()
  60:         {
  61:             _rowBreaksRecord = null;
  62:             _columnBreaksRecord = null;
  63:             header = null;
  64:             footer = null;
  65:             _headerfooter = null;
  66:             _hCenter = null;
  67:             _vCenter = null;
  68:             _leftMargin = null;
  69:             _rightMargin = null;
  70:             _topMargin = null;
  71:             _bottomMargin = null;
  72:             _pls = null;
  73:             printSetup = null;
  74:             _bitmap = null;
  75:         }
  76:         /**
  77:          * @return <c>true</c> if the specified Record sid is one belonging to the 
  78:          * 'Page Settings Block'.
  79:          */
  80:         public static bool IsComponentRecord(int sid)
  81:         {
  82:             switch (sid)
  83:             {
  84:                 case HorizontalPageBreakRecord.sid:
  85:                 case VerticalPageBreakRecord.sid:
  86:                 case HeaderRecord.sid:
  87:                 case FooterRecord.sid:
  88:                 case HeaderFooterRecord.sid:
  89:                 case HCenterRecord.sid:
  90:                 case VCenterRecord.sid:
  91:                 case LeftMarginRecord.sid:
  92:                 case RightMarginRecord.sid:
  93:                 case TopMarginRecord.sid:
  94:                 case BottomMarginRecord.sid:
  95:                 case UnknownRecord.PLS_004D:
  96:                 case PrintSetupRecord.sid:
  97:                 case UnknownRecord.BITMAP_00E9:
  98:                     return true;
  99:             }
 100:             return false;
 101:         }
 102:  
 103:         private bool ReadARecord(RecordStream rs)
 104:         {
 105:             switch (rs.PeekNextSid())
 106:             {
 107:                 case HorizontalPageBreakRecord.sid:
 108:                     _rowBreaksRecord = (PageBreakRecord)rs.GetNext();
 109:                     _rowRecords.Add(_rowBreaksRecord);
 110:                     break;
 111:                 case VerticalPageBreakRecord.sid:
 112:                     _columnBreaksRecord = (PageBreakRecord)rs.GetNext();
 113:                     _rowRecords.Add(_columnBreaksRecord);
 114:                     break;
 115:                 case HeaderRecord.sid:
 116:                     header = (HeaderRecord)rs.GetNext();
 117:                     _rowRecords.Add(header);
 118:                     break;
 119:                 case FooterRecord.sid:
 120:                     footer = (FooterRecord)rs.GetNext();
 121:                     _rowRecords.Add(footer);
 122:                     break;
 123:                 case HeaderFooterRecord.sid:
 124:                     _headerfooter = (HeaderFooterRecord)rs.GetNext();
 125:                     _rowRecords.Add(_headerfooter);
 126:                     break;
 127:                 case HCenterRecord.sid:
 128:                     _hCenter = (HCenterRecord)rs.GetNext();
 129:                     _rowRecords.Add(_hCenter);
 130:                     break;
 131:                 case VCenterRecord.sid:
 132:                     _vCenter = (VCenterRecord)rs.GetNext();
 133:                     _rowRecords.Add(_vCenter);
 134:                     break;
 135:                 case LeftMarginRecord.sid:
 136:                     _leftMargin = (LeftMarginRecord)rs.GetNext();
 137:                     _rowRecords.Add(_leftMargin);
 138:                     break;
 139:                 case RightMarginRecord.sid:
 140:                     _rightMargin = (RightMarginRecord)rs.GetNext();
 141:                     _rowRecords.Add(_rightMargin);
 142:                     break;
 143:                 case TopMarginRecord.sid:
 144:                     _topMargin = (TopMarginRecord)rs.GetNext();
 145:                     _rowRecords.Add(_topMargin);
 146:                     break;
 147:                 case BottomMarginRecord.sid:
 148:                     _bottomMargin = (BottomMarginRecord)rs.GetNext();
 149:                     _rowRecords.Add(_bottomMargin);
 150:                     break;
 151:                 case 0x004D: // PLS
 152:                     _pls = rs.GetNext();
 153:                     _rowRecords.Add(_pls);
 154:                     break;
 155:                 case PrintSetupRecord.sid:
 156:                     printSetup = (PrintSetupRecord)rs.GetNext();
 157:                     _rowRecords.Add(printSetup);
 158:                     break;
 159:                 case 0x00E9: // BITMAP
 160:                     _bitmap = rs.GetNext();
 161:                     _rowRecords.Add(_bitmap);
 162:                     break;
 163:                 default:
 164:                     // all other record types are not part of the PageSettingsBlock
 165:                     return false;
 166:             }
 167:             return true;
 168:         }
 169:  
 170:         private PageBreakRecord RowBreaksRecord
 171:         {
 172:             get
 173:             {
 174:                 if (_rowBreaksRecord == null)
 175:                 {
 176:                     _rowBreaksRecord = new HorizontalPageBreakRecord();
 177:                 }
 178:                 return _rowBreaksRecord;
 179:             }
 180:         }
 181:  
 182:         private PageBreakRecord ColumnBreaksRecord
 183:         {
 184:             get
 185:             {
 186:                 if (_columnBreaksRecord == null)
 187:                 {
 188:                     _columnBreaksRecord = new VerticalPageBreakRecord();
 189:                 }
 190:                 return _columnBreaksRecord;
 191:             }
 192:         }
 193:  
 194:         public IEnumerator GetEnumerator()
 195:         {
 196:             return _rowRecords.GetEnumerator();
 197:         }
 198:  
 199:         /**
 200:          * Sets a page break at the indicated column
 201:          *
 202:          */
 203:         public void SetColumnBreak(int column, int fromRow, int toRow)
 204:         {
 205:             this.ColumnBreaksRecord.AddBreak(column, fromRow, toRow);
 206:         }
 207:  
 208:         /**
 209:          * Removes a page break at the indicated column
 210:          *
 211:          */
 212:         public void RemoveColumnBreak(int column)
 213:         {
 214:             this.ColumnBreaksRecord.RemoveBreak(column);
 215:         }
 216:  
 217:         public override void VisitContainedRecords(RecordVisitor rv)
 218:         {
 219:             VisitIfPresent(_rowBreaksRecord, rv);
 220:             VisitIfPresent(_columnBreaksRecord, rv);
 221:             VisitIfPresent(header, rv);
 222:             VisitIfPresent(footer, rv);
 223:             VisitIfPresent(_headerfooter, rv);
 224:             VisitIfPresent(_hCenter, rv);
 225:             VisitIfPresent(_vCenter, rv);
 226:             VisitIfPresent(_leftMargin, rv);
 227:             VisitIfPresent(_rightMargin, rv);
 228:             VisitIfPresent(_topMargin, rv);
 229:             VisitIfPresent(_bottomMargin, rv);
 230:             VisitIfPresent(_pls, rv);
 231:             VisitIfPresent(printSetup, rv);
 232:             VisitIfPresent(_bitmap, rv);
 233:         }
 234:         private static void VisitIfPresent(Record r, RecordVisitor rv)
 235:         {
 236:             if (r != null)
 237:             {
 238:                 rv.VisitRecord(r);
 239:             }
 240:         }
 241:  
 242:         /**
 243:          * Creates the HCenter Record and sets it to false (don't horizontally center)
 244:          */
 245:         private static HCenterRecord CreateHCenter()
 246:         {
 247:             HCenterRecord retval = new HCenterRecord();
 248:  
 249:             retval.HCenter = (false);
 250:             return retval;
 251:         }
 252:  
 253:         /**
 254:          * Creates the VCenter Record and sets it to false (don't horizontally center)
 255:         */
 256:         private static VCenterRecord CreateVCenter()
 257:         {
 258:             VCenterRecord retval = new VCenterRecord();
 259:  
 260:             retval.VCenter = (false);
 261:             return retval;
 262:         }
 263:  
 264:         /**
 265:          * Creates the PrintSetup Record and sets it to defaults and marks it invalid
 266:          * @see org.apache.poi.hssf.record.PrintSetupRecord
 267:          * @see org.apache.poi.hssf.record.Record
 268:          * @return record containing a PrintSetupRecord
 269:          */
 270:         private static PrintSetupRecord CreatePrintSetup()
 271:         {
 272:             PrintSetupRecord retval = new PrintSetupRecord();
 273:  
 274:             retval.PaperSize = ((short)1);
 275:             retval.Scale = ((short)100);
 276:             retval.PageStart = ((short)1);
 277:             retval.FitWidth = ((short)1);
 278:             retval.FitHeight = ((short)1);
 279:             retval.Options = ((short)2);
 280:             retval.HResolution = ((short)300);
 281:             retval.VResolution = ((short)300);
 282:             retval.HeaderMargin = (0.5);
 283:             retval.FooterMargin = (0.5);
 284:             retval.Copies = ((short)0);
 285:             return retval;
 286:         }
 287:  
 288:  
 289:         /**
 290:          * Returns the HeaderRecord.
 291:          * @return HeaderRecord for the sheet.
 292:          */
 293:         public HeaderRecord Header
 294:         {
 295:             get
 296:             {
 297:                 return header;
 298:             }
 299:             set 
 300:             {
 301:                 header = value;
 302:             }
 303:         }
 304:  
 305:         /**
 306:          * Returns the FooterRecord.
 307:          * @return FooterRecord for the sheet.
 308:          */
 309:         public FooterRecord Footer
 310:         {
 311:             get
 312:             {
 313:                 return footer;
 314:             }
 315:             set { footer = value; }
 316:         }
 317:  
 318:  
 319:         /**
 320:          * Returns the HeaderFooterRecord.
 321:          * @return HeaderFooterRecord for the sheet.
 322:          */
 323:         public HeaderFooterRecord HeaderFooter
 324:         {
 325:             get
 326:             {
 327:                 return _headerfooter;
 328:             }
 329:             set { _headerfooter = value; }
 330:         }
 331:  
 332:         /**
 333:          * Returns the PrintSetupRecord.
 334:          * @return PrintSetupRecord for the sheet.
 335:          */
 336:         public PrintSetupRecord PrintSetup
 337:         {
 338:             get
 339:             {
 340:                 return printSetup;
 341:             }
 342:             set 
 343:             {
 344:                 printSetup = value;
 345:             }
 346:         }
 347:  
 348:  
 349:         private Margin GetMarginRec(NPOI.SS.UserModel.MarginType margin)
 350:         {
 351:             switch (margin)
 352:             {
 353:                 case NPOI.SS.UserModel.MarginType.LeftMargin: return _leftMargin;
 354:                 case NPOI.SS.UserModel.MarginType.RightMargin: return _rightMargin;
 355:                 case NPOI.SS.UserModel.MarginType.TopMargin: return _topMargin;
 356:                 case NPOI.SS.UserModel.MarginType.BottomMargin: return _bottomMargin;
 357:                 default:
 358:                     throw new InvalidOperationException("Unknown margin constant:  " + (short)margin);
 359:             }
 360:         }
 361:  
 362:  
 363:         /**
 364:          * Gets the size of the margin in inches.
 365:          * @param margin which margin to Get
 366:          * @return the size of the margin
 367:          */
 368:         public double GetMargin(NPOI.SS.UserModel.MarginType margin)
 369:         {
 370:             Margin m = GetMarginRec(margin);
 371:             if (m != null)
 372:             {
 373:                 return m.Margin;
 374:             }
 375:             else
 376:             {
 377:                 switch (margin)
 378:                 {
 379:                     case NPOI.SS.UserModel.MarginType.LeftMargin:
 380:                         return .75;
 381:                     case NPOI.SS.UserModel.MarginType.RightMargin:
 382:                         return .75;
 383:                     case NPOI.SS.UserModel.MarginType.TopMargin:
 384:                         return 1.0;
 385:                     case NPOI.SS.UserModel.MarginType.BottomMargin:
 386:                         return 1.0;
 387:                 }
 388:                 throw new InvalidOperationException("Unknown margin constant:  " + margin);
 389:             }
 390:         }
 391:  
 392:         /**
 393:          * Sets the size of the margin in inches.
 394:          * @param margin which margin to Get
 395:          * @param size the size of the margin
 396:          */
 397:         public void SetMargin(NPOI.SS.UserModel.MarginType margin, double size)
 398:         {
 399:             Margin m = GetMarginRec(margin);
 400:             if (m == null)
 401:             {
 402:                 switch (margin)
 403:                 {
 404:                     case NPOI.SS.UserModel.MarginType.LeftMargin:
 405:                         _leftMargin = new LeftMarginRecord();
 406:                         m = _leftMargin;
 407:                         break;
 408:                     case NPOI.SS.UserModel.MarginType.RightMargin:
 409:                         _rightMargin = new RightMarginRecord();
 410:                         m = _rightMargin;
 411:                         break;
 412:                     case NPOI.SS.UserModel.MarginType.TopMargin:
 413:                         _topMargin = new TopMarginRecord();
 414:                         m = _topMargin;
 415:                         break;
 416:                     case NPOI.SS.UserModel.MarginType.BottomMargin:
 417:                         _bottomMargin = new BottomMarginRecord();
 418:                         m = _bottomMargin;
 419:                         break;
 420:                     default:
 421:                         throw new InvalidOperationException("Unknown margin constant:  " + margin);
 422:                 }
 423:             }
 424:             m.Margin= size;
 425:         }
 426:  
 427:         /**
 428:          * Shifts all the page breaks in the range "count" number of rows/columns
 429:          * @param breaks The page record to be shifted
 430:          * @param start Starting "main" value to shift breaks
 431:          * @param stop Ending "main" value to shift breaks
 432:          * @param count number of units (rows/columns) to shift by
 433:          */
 434:         private static void ShiftBreaks(PageBreakRecord breaks, int start, int stop, int count) {
 435:  
 436:         IEnumerator iterator = breaks.GetBreaksEnumerator();
 437:         IList shiftedBreak = new ArrayList();
 438:         while(iterator.MoveNext())
 439:         {
 440:             PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.Current;
 441:             int breakLocation = breakItem.main;
 442:             bool inStart = (breakLocation >= start);
 443:             bool inEnd = (breakLocation <= stop);
 444:             if(inStart && inEnd)
 445:                 shiftedBreak.Add(breakItem);
 446:         }
 447:  
 448:         iterator = shiftedBreak.GetEnumerator();
 449:         while (iterator.MoveNext()) {
 450:             PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.Current;
 451:             breaks.RemoveBreak(breakItem.main);
 452:             breaks.AddBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo);
 453:         }
 454:     }
 455:  
 456:  
 457:         /**
 458:          * Sets a page break at the indicated row
 459:          * @param row
 460:          */
 461:         public void SetRowBreak(int row, short fromCol, short toCol)
 462:         {
 463:             this.RowBreaksRecord.AddBreak((short)row, fromCol, toCol);
 464:         }
 465:  
 466:         /**
 467:          * Removes a page break at the indicated row
 468:          * @param row
 469:          */
 470:         public void RemoveRowBreak(int row)
 471:         {
 472:             if (this.RowBreaksRecord.GetBreaks().Length < 1)
 473:                 throw new ArgumentException("Sheet does not define any row breaks");
 474:             this.RowBreaksRecord.RemoveBreak((short)row);
 475:         }
 476:  
 477:         /**
 478:          * Queries if the specified row has a page break
 479:          * @param row
 480:          * @return true if the specified row has a page break
 481:          */
 482:         public bool IsRowBroken(int row)
 483:         {
 484:             return this.RowBreaksRecord.GetBreak(row) != null;
 485:         }
 486:  
 487:  
 488:         /**
 489:          * Queries if the specified column has a page break
 490:          *
 491:          * @return <c>true</c> if the specified column has a page break
 492:          */
 493:         public bool IsColumnBroken(int column)
 494:         {
 495:             return this.ColumnBreaksRecord.GetBreak(column) != null;
 496:         }
 497:  
 498:         /**
 499:          * Shifts the horizontal page breaks for the indicated count
 500:          * @param startingRow
 501:          * @param endingRow
 502:          * @param count
 503:          */
 504:         public void ShiftRowBreaks(int startingRow, int endingRow, int count)
 505:         {
 506:             ShiftBreaks(this.RowBreaksRecord, startingRow, endingRow, count);
 507:         }
 508:  
 509:         /**
 510:          * Shifts the vertical page breaks for the indicated count
 511:          * @param startingCol
 512:          * @param endingCol
 513:          * @param count
 514:          */
 515:         public void ShiftColumnBreaks(short startingCol, short endingCol, short count)
 516:         {
 517:             ShiftBreaks(this.ColumnBreaksRecord, startingCol, endingCol, count);
 518:         }
 519:  
 520:         /**
 521:          * @return all the horizontal page breaks, never <c>null</c>
 522:          */
 523:         public int[] RowBreaks
 524:         {
 525:             get
 526:             {
 527:                 return this.RowBreaksRecord.GetBreaks();
 528:             }
 529:         }
 530:  
 531:         /**
 532:          * @return the number of row page breaks
 533:          */
 534:         public int NumRowBreaks
 535:         {
 536:             get
 537:             {
 538:                 return this.RowBreaksRecord.NumBreaks;
 539:             }
 540:         }
 541:  
 542:         /**
 543:          * @return all the column page breaks, never <c>null</c>
 544:          */
 545:         public int[] ColumnBreaks
 546:         {
 547:             get
 548:             {
 549:                 return this.ColumnBreaksRecord.GetBreaks();
 550:             }
 551:         }
 552:  
 553:         /**
 554:          * @return the number of column page breaks
 555:          */
 556:         public int NumColumnBreaks
 557:         {
 558:             get
 559:             {
 560:                 return this.ColumnBreaksRecord.NumBreaks;
 561:             }
 562:         }
 563:  
 564:         public VCenterRecord VCenter
 565:         {
 566:             get { return _vCenter; }
 567:         }
 568:  
 569:         public HCenterRecord HCenter
 570:         {
 571:             get { return _hCenter; }
 572:         }
 573:     }
 574: }

在NPOI.HSSF.Record.UnknownRecord中,将089Ch相关的变量注释掉,这样在读取Excel文件中就可以读取HeaderFooterRecord信息了。

转载于:https://www.cnblogs.com/absana/archive/2011/05/28/2061063.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值