| /******************************************************************************* | 
 |  * You may amend and distribute as you like, but don't remove this header! | 
 |  * | 
 |  * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. | 
 |  * See http://www.codeplex.com/EPPlus for details. | 
 |  * | 
 |  * Copyright (C) 2011  Jan Källman | 
 |  * | 
 |  * This library is free software; you can redistribute it and/or | 
 |  * modify it under the terms of the GNU Lesser General Public | 
 |  * License as published by the Free Software Foundation; either | 
 |  * version 2.1 of the License, or (at your option) any later version. | 
 |  | 
 |  * This library is distributed in the hope that it will be useful, | 
 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   | 
 |  * See the GNU Lesser General Public License for more details. | 
 |  * | 
 |  * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php | 
 |  * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html | 
 |  * | 
 |  * All code and executables are provided "as is" with no warranty either express or implied.  | 
 |  * The author accepts no liability for any damage or loss of business that this product may cause. | 
 |  * | 
 |  * Code change notes: | 
 |  *  | 
 |  * Author							Change						Date | 
 |  * ****************************************************************************** | 
 |  * Jan Källman		                Initial Release		        2009-10-01 | 
 |  * Jan Källman		                License changed GPL-->LGPL 2011-12-27 | 
 |  *******************************************************************************/ | 
 | using System; | 
 | using System.Collections.Generic; | 
 | using System.Text; | 
 | using System.Xml; | 
 | using System.Globalization; | 
 |  | 
 | namespace OfficeOpenXml | 
 | { | 
 |     #region "Enums" | 
 |     /// <summary> | 
 |     /// Printer orientation | 
 |     /// </summary> | 
 |     public enum eOrientation | 
 |     { | 
 |         /// <summary> | 
 |         /// Portrait orientation | 
 |         /// </summary> | 
 |         Portrait, | 
 |         /// <summary> | 
 |         /// Landscape orientation | 
 |         /// </summary> | 
 |         Landscape | 
 |     } | 
 |     /// <summary> | 
 |     /// Papersize | 
 |     /// </summary> | 
 |     public enum ePaperSize | 
 |     { | 
 |         /// <summary> | 
 |         /// Letter paper (8.5 in. by 11 in.) | 
 |         /// </summary> | 
 |         Letter= 1,       | 
 |         /// <summary> | 
 |         /// Letter small paper (8.5 in. by 11 in.) | 
 |         /// </summary> | 
 |         LetterSmall=2,   | 
 |         /// <summary> | 
 |         /// // Tabloid paper (11 in. by 17 in.) | 
 |         /// </summary> | 
 |         Tabloid=3,       | 
 |         /// <summary> | 
 |         /// Ledger paper (17 in. by 11 in.) | 
 |         /// </summary> | 
 |         Ledger=4,        | 
 |         /// <summary> | 
 |         /// Legal paper (8.5 in. by 14 in.) | 
 |         /// </summary> | 
 |         Legal=5,          | 
 |         /// <summary> | 
 |         /// Statement paper (5.5 in. by 8.5 in.) | 
 |         /// </summary> | 
 |         Statement=6,     | 
 |         /// <summary> | 
 |         /// Executive paper (7.25 in. by 10.5 in.) | 
 |         /// </summary> | 
 |         Executive=7,      | 
 |         /// <summary> | 
 |         /// A3 paper (297 mm by 420 mm) | 
 |         /// </summary> | 
 |         A3=8,            | 
 |         /// <summary> | 
 |         /// A4 paper (210 mm by 297 mm) | 
 |         /// </summary> | 
 |         A4=9,             | 
 |         /// <summary> | 
 |         /// A4 small paper (210 mm by 297 mm) | 
 |         /// </summary> | 
 |         A4Small=10,       | 
 |         /// <summary> | 
 |         /// A5 paper (148 mm by 210 mm) | 
 |         /// </summary> | 
 |         A5=11,            | 
 |         /// <summary> | 
 |         /// B4 paper (250 mm by 353 mm) | 
 |         /// </summary> | 
 |         B4=12,             | 
 |         /// <summary> | 
 |         /// B5 paper (176 mm by 250 mm) | 
 |         /// </summary> | 
 |         B5=13,             | 
 |         /// <summary> | 
 |         /// Folio paper (8.5 in. by 13 in.) | 
 |         /// </summary> | 
 |         Folio=14,          | 
 |         /// <summary> | 
 |         /// Quarto paper (215 mm by 275 mm) | 
 |         /// </summary> | 
 |         Quarto=15,         | 
 |         /// <summary> | 
 |         /// Standard paper (10 in. by 14 in.) | 
 |         /// </summary> | 
 |         Standard10_14=16,  | 
 |         /// <summary> | 
 |         /// Standard paper (11 in. by 17 in.) | 
 |         /// </summary> | 
 |         Standard11_17=17,   | 
 |         /// <summary> | 
 |         /// Note paper (8.5 in. by 11 in.) | 
 |         /// </summary> | 
 |         Note=18,            | 
 |         /// <summary> | 
 |         /// #9 envelope (3.875 in. by 8.875 in.) | 
 |         /// </summary> | 
 |         Envelope9=19,       | 
 |         /// <summary> | 
 |         /// #10 envelope (4.125 in. by 9.5 in.) | 
 |         /// </summary> | 
 |         Envelope10=20,      | 
 |         /// <summary> | 
 |         /// #11 envelope (4.5 in. by 10.375 in.) | 
 |         /// </summary> | 
 |         Envelope11=21,      | 
 |         /// <summary> | 
 |         /// #12 envelope (4.75 in. by 11 in.) | 
 |         /// </summary> | 
 |         Envelope12=22,      | 
 |         /// <summary> | 
 |         /// #14 envelope (5 in. by 11.5 in.) | 
 |         /// </summary> | 
 |         Envelope14=23,      | 
 |         /// <summary> | 
 |         /// C paper (17 in. by 22 in.) | 
 |         /// </summary> | 
 |         C=24,               | 
 |         /// <summary> | 
 |         /// D paper (22 in. by 34 in.) | 
 |         /// </summary> | 
 |         D=25,                | 
 |         /// <summary> | 
 |         /// E paper (34 in. by 44 in.) | 
 |         /// </summary> | 
 |         E=26,                | 
 |         /// <summary> | 
 |         /// DL envelope (110 mm by 220 mm) | 
 |         /// </summary> | 
 |         DLEnvelope = 27, | 
 |         /// <summary> | 
 |         /// C5 envelope (162 mm by 229 mm) | 
 |         /// </summary> | 
 |         C5Envelope = 28, | 
 |         /// <summary> | 
 |         /// C3 envelope (324 mm by 458 mm) | 
 |         /// </summary> | 
 |         C3Envelope = 29,  | 
 |         /// <summary> | 
 |         /// C4 envelope (229 mm by 324 mm) | 
 |         /// </summary> | 
 |         C4Envelope = 30,  | 
 |         /// <summary> | 
 |         /// C6 envelope (114 mm by 162 mm) | 
 |         /// </summary> | 
 |         C6Envelope = 31,  | 
 |         /// <summary> | 
 |         /// C65 envelope (114 mm by 229 mm) | 
 |         /// </summary> | 
 |         C65Envelope = 32,  | 
 |         /// <summary> | 
 |         /// B4 envelope (250 mm by 353 mm) | 
 |         /// </summary> | 
 |         B4Envelope= 33,  | 
 |         /// <summary> | 
 |         /// B5 envelope (176 mm by 250 mm) | 
 |         /// </summary> | 
 |         B5Envelope= 34,  | 
 |         /// <summary> | 
 |         /// B6 envelope (176 mm by 125 mm) | 
 |         /// </summary> | 
 |         B6Envelope = 35,  | 
 |         /// <summary> | 
 |         /// Italy envelope (110 mm by 230 mm) | 
 |         /// </summary> | 
 |         ItalyEnvelope = 36,  | 
 |         /// <summary> | 
 |         /// Monarch envelope (3.875 in. by 7.5 in.). | 
 |         /// </summary> | 
 |         MonarchEnvelope = 37,  | 
 |         /// <summary> | 
 |         /// 6 3/4 envelope (3.625 in. by 6.5 in.) | 
 |         /// </summary> | 
 |         Six3_4Envelope = 38, | 
 |         /// <summary> | 
 |         /// US standard fanfold (14.875 in. by 11 in.) | 
 |         /// </summary> | 
 |         USStandard=39,  | 
 |         /// <summary> | 
 |         /// German standard fanfold (8.5 in. by 12 in.) | 
 |         /// </summary> | 
 |         GermanStandard=40,  | 
 |         /// <summary> | 
 |         /// German legal fanfold (8.5 in. by 13 in.) | 
 |         /// </summary> | 
 |         GermanLegal=41,  | 
 |         /// <summary> | 
 |         /// ISO B4 (250 mm by 353 mm) | 
 |         /// </summary> | 
 |         ISOB4=42, | 
 |         /// <summary> | 
 |         ///  Japanese double postcard (200 mm by 148 mm) | 
 |         /// </summary> | 
 |         JapaneseDoublePostcard=43, | 
 |         /// <summary> | 
 |         /// Standard paper (9 in. by 11 in.) | 
 |         /// </summary> | 
 |         Standard9=44,  | 
 |         /// <summary> | 
 |         /// Standard paper (10 in. by 11 in.) | 
 |         /// </summary> | 
 |         Standard10=45,  | 
 |         /// <summary> | 
 |         /// Standard paper (15 in. by 11 in.) | 
 |         /// </summary> | 
 |         Standard15=46,  | 
 |         /// <summary> | 
 |         /// Invite envelope (220 mm by 220 mm) | 
 |         /// </summary> | 
 |         InviteEnvelope = 47,  | 
 |         /// <summary> | 
 |         /// Letter extra paper (9.275 in. by 12 in.) | 
 |         /// </summary> | 
 |         LetterExtra=50, | 
 |         /// <summary> | 
 |         /// Legal extra paper (9.275 in. by 15 in.) | 
 |         /// </summary> | 
 |         LegalExtra=51,  | 
 |         /// <summary> | 
 |         /// Tabloid extra paper (11.69 in. by 18 in.) | 
 |         /// </summary> | 
 |         TabloidExtra=52, | 
 |         /// <summary> | 
 |         /// A4 extra paper (236 mm by 322 mm) | 
 |         /// </summary> | 
 |         A4Extra=53,  | 
 |         /// <summary> | 
 |         /// Letter transverse paper (8.275 in. by 11 in.) | 
 |         /// </summary> | 
 |         LetterTransverse=54,  | 
 |         /// <summary> | 
 |         /// A4 transverse paper (210 mm by 297 mm) | 
 |         /// </summary> | 
 |         A4Transverse=55,  | 
 |         /// <summary> | 
 |         /// Letter extra transverse paper (9.275 in. by 12 in.) | 
 |         /// </summary> | 
 |         LetterExtraTransverse=56,  | 
 |         /// <summary> | 
 |         /// SuperA/SuperA/A4 paper (227 mm by 356 mm) | 
 |         /// </summary> | 
 |         SuperA=57,  | 
 |         /// <summary> | 
 |         /// SuperB/SuperB/A3 paper (305 mm by 487 mm) | 
 |         /// </summary> | 
 |         SuperB=58,  | 
 |         /// <summary> | 
 |         /// Letter plus paper (8.5 in. by 12.69 in.) | 
 |         /// </summary> | 
 |         LetterPlus=59,  | 
 |         /// <summary> | 
 |         /// A4 plus paper (210 mm by 330 mm) | 
 |         /// </summary> | 
 |         A4Plus=60,  | 
 |         /// <summary> | 
 |         /// A5 transverse paper (148 mm by 210 mm) | 
 |         /// </summary> | 
 |         A5Transverse=61,  | 
 |         /// <summary> | 
 |         /// JIS B5 transverse paper (182 mm by 257 mm) | 
 |         /// </summary> | 
 |         JISB5Transverse=62,  | 
 |         /// <summary> | 
 |         /// A3 extra paper (322 mm by 445 mm) | 
 |         /// </summary> | 
 |         A3Extra=63,  | 
 |         /// <summary> | 
 |         /// A5 extra paper (174 mm by 235 mm) | 
 |         /// </summary> | 
 |         A5Extra=64,  | 
 |         /// <summary> | 
 |         /// ISO B5 extra paper (201 mm by 276 mm) | 
 |         /// </summary> | 
 |         ISOB5=65,  | 
 |         /// <summary> | 
 |         /// A2 paper (420 mm by 594 mm) | 
 |         /// </summary> | 
 |         A2=66,  | 
 |         /// <summary> | 
 |         /// A3 transverse paper (297 mm by 420 mm) | 
 |         /// </summary> | 
 |         A3Transverse=67,  | 
 |         /// <summary> | 
 |         /// A3 extra transverse paper (322 mm by 445 mm*/ | 
 |         /// </summary> | 
 |         A3ExtraTransverse = 68 | 
 |     } | 
 |     /// <summary> | 
 |     /// Specifies printed page order | 
 |     /// </summary> | 
 |     public enum ePageOrder | 
 |     { | 
 |  | 
 |         /// <summary> | 
 |         /// Order pages vertically first, then move horizontally. | 
 |         /// </summary> | 
 |         DownThenOver, | 
 |         /// <summary> | 
 |         /// Order pages horizontally first, then move vertically | 
 |         /// </summary> | 
 |         OverThenDown | 
 |     } | 
 |     #endregion | 
 |     /// <summary> | 
 |     /// Printer settings | 
 |     /// </summary> | 
 |     public sealed class ExcelPrinterSettings : XmlHelper | 
 |     { | 
 |         ExcelWorksheet _ws; | 
 |         bool _marginsCreated = false; | 
 |  | 
 |         internal ExcelPrinterSettings(XmlNamespaceManager ns, XmlNode topNode,ExcelWorksheet ws) : | 
 |             base(ns, topNode) | 
 |         { | 
 |             _ws = ws; | 
 |             SchemaNodeOrder = ws.SchemaNodeOrder; | 
 |         } | 
 |         const string _leftMarginPath = "d:pageMargins/@left"; | 
 |         /// <summary> | 
 |         /// Left margin in inches | 
 |         /// </summary> | 
 |         public decimal LeftMargin  | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeDecimal(_leftMarginPath); | 
 |             } | 
 |             set | 
 |             { | 
 |                CreateMargins(); | 
 |                SetXmlNodeString(_leftMarginPath, value.ToString(CultureInfo.InvariantCulture)); | 
 |             } | 
 |         } | 
 |         const string _rightMarginPath = "d:pageMargins/@right"; | 
 |         /// <summary> | 
 |         /// Right margin in inches | 
 |         /// </summary> | 
 |         public decimal RightMargin  | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeDecimal(_rightMarginPath); | 
 |             } | 
 |             set | 
 |             { | 
 |                 CreateMargins(); | 
 |                 SetXmlNodeString(_rightMarginPath, value.ToString(CultureInfo.InvariantCulture)); | 
 |             } | 
 |         } | 
 |         const string _topMarginPath = "d:pageMargins/@top"; | 
 |         /// <summary> | 
 |         /// Top margin in inches | 
 |         /// </summary> | 
 |         public decimal TopMargin  | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeDecimal(_topMarginPath); | 
 |             } | 
 |             set | 
 |             { | 
 |                 CreateMargins(); | 
 |                 SetXmlNodeString(_topMarginPath, value.ToString(CultureInfo.InvariantCulture)); | 
 |             } | 
 |         } | 
 |         const string _bottomMarginPath = "d:pageMargins/@bottom"; | 
 |         /// <summary> | 
 |         /// Bottom margin in inches | 
 |         /// </summary> | 
 |         public decimal BottomMargin  | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeDecimal(_bottomMarginPath); | 
 |             } | 
 |             set | 
 |             { | 
 |                 CreateMargins(); | 
 |                 SetXmlNodeString(_bottomMarginPath, value.ToString(CultureInfo.InvariantCulture)); | 
 |             } | 
 |         } | 
 |         const string _headerMarginPath = "d:pageMargins/@header"; | 
 |         /// <summary> | 
 |         /// Header margin in inches | 
 |         /// </summary> | 
 |         public decimal HeaderMargin  | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeDecimal(_headerMarginPath); | 
 |             } | 
 |             set | 
 |             { | 
 |                 CreateMargins(); | 
 |                 SetXmlNodeString(_headerMarginPath, value.ToString(CultureInfo.InvariantCulture)); | 
 |             } | 
 |         } | 
 |         const string _footerMarginPath = "d:pageMargins/@footer"; | 
 |         /// <summary> | 
 |         /// Footer margin in inches | 
 |         /// </summary> | 
 |         public decimal FooterMargin  | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeDecimal(_footerMarginPath); | 
 |             } | 
 |             set | 
 |             { | 
 |                 CreateMargins(); | 
 |                 SetXmlNodeString(_footerMarginPath, value.ToString(CultureInfo.InvariantCulture)); | 
 |             } | 
 |         } | 
 |         const string _orientationPath = "d:pageSetup/@orientation"; | 
 |         /// <summary> | 
 |         /// Orientation  | 
 |         /// Portrait or Landscape | 
 |         /// </summary> | 
 |         public eOrientation Orientation | 
 |         { | 
 |             get | 
 |             { | 
 |                 return (eOrientation)Enum.Parse(typeof(eOrientation), GetXmlNodeString(_orientationPath), true); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeString(_orientationPath, value.ToString().ToLower(CultureInfo.InvariantCulture)); | 
 |             } | 
 |         } | 
 |         const string _fitToWidthPath = "d:pageSetup/@fitToWidth"; | 
 |         /// <summary> | 
 |         /// Fit to Width in pages.  | 
 |         /// Set FitToPage to true when using this one.  | 
 |         /// 0 is automatic | 
 |         /// </summary> | 
 |         public int FitToWidth | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeInt(_fitToWidthPath); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeString(_fitToWidthPath, value.ToString()); | 
 |             } | 
 |         } | 
 |         const string _fitToHeightPath = "d:pageSetup/@fitToHeight"; | 
 |         /// <summary> | 
 |         /// Fit to height in pages.  | 
 |         /// Set FitToPage to true when using this one.  | 
 |         /// 0 is automatic | 
 |         /// </summary> | 
 |         public int FitToHeight | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeInt(_fitToHeightPath); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeString(_fitToHeightPath, value.ToString()); | 
 |             } | 
 |         } | 
 |         const string _scalePath = "d:pageSetup/@scale"; | 
 |         /// <summary> | 
 |         /// Print scale | 
 |         /// </summary> | 
 |         public int Scale | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeInt(_scalePath); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeString(_scalePath, value.ToString()); | 
 |             } | 
 |         } | 
 |         const string _fitToPagePath = "d:sheetPr/d:pageSetUpPr/@fitToPage"; | 
 |         /// <summary> | 
 |         /// Fit To Page. | 
 |         /// </summary> | 
 |         public bool FitToPage | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeBool(_fitToPagePath); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeString(_fitToPagePath, value ? "1" : "0"); | 
 |             } | 
 |         } | 
 |         const string _headersPath = "d:printOptions/@headings"; | 
 |         /// <summary> | 
 |         /// Print headings (column letter and row numbers) | 
 |         /// </summary> | 
 |         public bool ShowHeaders | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeBool(_headersPath, false); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeBool(_headersPath, value, false); | 
 |             } | 
 |         } | 
 |         /// <summary> | 
 |         /// Print titles | 
 |         /// Rows to be repeated after each pagebreak. | 
 |         /// The address must be a full row address (ex. 1:1) | 
 |         /// </summary> | 
 |         public ExcelAddress RepeatRows | 
 |         { | 
 |             get | 
 |             { | 
 |                 if (_ws.Names.ContainsKey("_xlnm.Print_Titles")) | 
 |                 { | 
 |                     ExcelRangeBase r = _ws.Names["_xlnm.Print_Titles"] as ExcelRangeBase; | 
 |                     if (r.Start.Column == 1 && r.End.Column == ExcelPackage.MaxColumns) | 
 |                     { | 
 |                         return new ExcelAddress(r.FirstAddress); | 
 |                     } | 
 |                     else if (r._addresses != null && r.Addresses[0].Start.Column == 1 && r.Addresses[0].End.Column == ExcelPackage.MaxColumns) | 
 |                     { | 
 |                         return r._addresses[0]; | 
 |                     } | 
 |                     else | 
 |                     { | 
 |                         return null; | 
 |                     } | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     return null; | 
 |                 } | 
 |             } | 
 |             set | 
 |             { | 
 |  | 
 |                 //Must span entire columns | 
 |                 if (!(value.Start.Column == 1 && value.End.Column == ExcelPackage.MaxColumns)) | 
 |                 { | 
 |                     throw new InvalidOperationException("Address must span full columns only (for ex. Address=\"A:A\" for the first column)."); | 
 |                 } | 
 |  | 
 |                 var vertAddr = RepeatColumns; | 
 |                 string addr; | 
 |                 if (vertAddr == null) | 
 |                 { | 
 |                     addr = value.Address; | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     addr = vertAddr.Address + "," + value.Address; | 
 |                 } | 
 |  | 
 |                 if (_ws.Names.ContainsKey("_xlnm.Print_Titles")) | 
 |                 { | 
 |                     _ws.Names["_xlnm.Print_Titles"].Address = addr; | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     _ws.Names.Add("_xlnm.Print_Titles", new ExcelRangeBase(_ws, addr)); | 
 |                 } | 
 |             } | 
 |         } | 
 |         /// <summary> | 
 |         /// Print titles | 
 |         /// Columns to be repeated after each pagebreak. | 
 |         /// The address must be a full column address (ex. A:A) | 
 |         /// </summary> | 
 |         public ExcelAddress RepeatColumns | 
 |         { | 
 |             get | 
 |             { | 
 |                 if (_ws.Names.ContainsKey("_xlnm.Print_Titles")) | 
 |                 { | 
 |                     ExcelRangeBase r = _ws.Names["_xlnm.Print_Titles"] as ExcelRangeBase; | 
 |                     if (r.Start.Row == 1 && r.End.Row == ExcelPackage.MaxRows) | 
 |                     { | 
 |                         return new ExcelAddress(r.FirstAddress); | 
 |                     } | 
 |                     else if (r._addresses != null && (r._addresses[0].Start.Row == 1 && r._addresses[0].End.Row == ExcelPackage.MaxRows)) | 
 |                     { | 
 |                         return r._addresses[0]; | 
 |                     } | 
 |                     else | 
 |                     { | 
 |                         return null; | 
 |                     } | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     return null; | 
 |                 } | 
 |             } | 
 |             set | 
 |             { | 
 |                 //Must span entire rows | 
 |                 if (!(value.Start.Row == 1 && value.End.Row== ExcelPackage.MaxRows)) | 
 |                 { | 
 |                     throw new InvalidOperationException("Address must span rows only (for ex. Address=\"1:1\" for the first row)."); | 
 |                 } | 
 |  | 
 |                 var horAddr = RepeatRows; | 
 |                 string addr; | 
 |                 if (horAddr == null) | 
 |                 { | 
 |                     addr = value.Address; | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     addr = value.Address + "," + horAddr.Address; | 
 |                 } | 
 |  | 
 |                 if (_ws.Names.ContainsKey("_xlnm.Print_Titles")) | 
 |                 { | 
 |                     _ws.Names["_xlnm.Print_Titles"].Address = addr; | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     _ws.Names.Add("_xlnm.Print_Titles", new ExcelRangeBase(_ws, addr)); | 
 |                 } | 
 |             } | 
 |         } | 
 |         /// <summary> | 
 |         /// The printarea. | 
 |         /// Null if no print area is set. | 
 |         /// </summary> | 
 |         public ExcelRangeBase PrintArea  | 
 |         { | 
 |             get | 
 |             { | 
 |                 if (_ws.Names.ContainsKey("_xlnm.Print_Area")) | 
 |                 { | 
 |                     return _ws.Names["_xlnm.Print_Area"]; | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     return null; | 
 |                 } | 
 |             } | 
 |             set | 
 |             { | 
 |                 if (value == null) | 
 |                 { | 
 |                     _ws.Names.Remove("_xlnm.Print_Area"); | 
 |                 } | 
 |                 else if (_ws.Names.ContainsKey("_xlnm.Print_Area")) | 
 |                 { | 
 |                     _ws.Names["_xlnm.Print_Area"].Address = value.Address; | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     _ws.Names.Add("_xlnm.Print_Area", value); | 
 |                 } | 
 |             } | 
 |         } | 
 |         const string _gridLinesPath = "d:printOptions/@gridLines"; | 
 |         /// <summary> | 
 |         /// Print gridlines  | 
 |         /// </summary> | 
 |         public bool ShowGridLines | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeBool(_gridLinesPath, false); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeBool(_gridLinesPath, value, false); | 
 |             } | 
 |         } | 
 |         const string _horizontalCenteredPath = "d:printOptions/@horizontalCentered"; | 
 |         /// <summary> | 
 |         /// Horizontal centered when printing  | 
 |         /// </summary>w | 
 |         public bool HorizontalCentered | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeBool(_horizontalCenteredPath, false); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeBool(_horizontalCenteredPath, value, false); | 
 |             } | 
 |         } | 
 |         const string _verticalCenteredPath = "d:printOptions/@verticalCentered"; | 
 |         /// <summary> | 
 |         /// Vertical centered when printing  | 
 |         /// </summary> | 
 |         public bool VerticalCentered | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeBool(_verticalCenteredPath, false); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeBool(_verticalCenteredPath, value, false); | 
 |             } | 
 |         } | 
 |         const string _pageOrderPath = "d:pageSetup/@pageOrder";         | 
 |         /// <summary> | 
 |         /// Specifies printed page order | 
 |         /// </summary> | 
 |         public ePageOrder PageOrder | 
 |         { | 
 |             get | 
 |             { | 
 |                 if (GetXmlNodeString(_pageOrderPath) == "overThenDown") | 
 |                 { | 
 |                     return ePageOrder.OverThenDown; | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     return ePageOrder.DownThenOver; | 
 |                 } | 
 |             } | 
 |             set | 
 |             { | 
 |                 if (value == ePageOrder.OverThenDown) | 
 |                 { | 
 |                     SetXmlNodeString(_pageOrderPath, "overThenDown"); | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     DeleteNode(_pageOrderPath); | 
 |                 } | 
 |             } | 
 |         } | 
 |         const string _blackAndWhitePath = "d:pageSetup/@blackAndWhite"; | 
 |         /// <summary> | 
 |         /// Print black and white | 
 |         /// </summary> | 
 |         public bool BlackAndWhite | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeBool(_blackAndWhitePath, false); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeBool(_blackAndWhitePath, value, false); | 
 |             } | 
 |         } | 
 |         const string _draftPath = "d:pageSetup/@draft"; | 
 |         /// <summary> | 
 |         /// Print a draft | 
 |         /// </summary> | 
 |         public bool Draft | 
 |         { | 
 |             get | 
 |             { | 
 |                 return GetXmlNodeBool(_draftPath, false); | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeBool(_draftPath, value, false); | 
 |             } | 
 |         } | 
 |         const string _paperSizePath = "d:pageSetup/@paperSize"; | 
 |         /// <summary> | 
 |         /// Paper size  | 
 |         /// </summary> | 
 |         public ePaperSize PaperSize  | 
 |         { | 
 |             get | 
 |             { | 
 |                 string s = GetXmlNodeString(_paperSizePath); | 
 |                 if (s != "") | 
 |                 { | 
 |                     return (ePaperSize)int.Parse(s); | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     return ePaperSize.Letter; | 
 |                      | 
 |                 } | 
 |             } | 
 |             set | 
 |             { | 
 |                 SetXmlNodeString(_paperSizePath, ((int)value).ToString()); | 
 |             } | 
 |         } | 
 |         /// <summary> | 
 |         /// All or none of the margin attributes must exist. Create all att ones. | 
 |         /// </summary> | 
 |         private void CreateMargins() | 
 |         { | 
 |             if (_marginsCreated==false && TopNode.SelectSingleNode(_leftMarginPath, NameSpaceManager) == null)  | 
 |             { | 
 |                 _marginsCreated=true; | 
 |                 LeftMargin = 0.7087M; | 
 |                 RightMargin = 0.7087M; | 
 |                 TopMargin = 0.7480M; | 
 |                 BottomMargin = 0.7480M; | 
 |                 HeaderMargin = 0.315M; | 
 |                 FooterMargin = 0.315M; | 
 |             } | 
 |         } | 
 |     } | 
 | } |