Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Async/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/ExcelHeaderFooter.cs @ 13329

Last change on this file since 13329 was 12074, checked in by sraggl, 10 years ago

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 20.2 KB
Line 
1/*******************************************************************************
2 * You may amend and distribute as you like, but don't remove this header!
3 *
4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
5 * See http://www.codeplex.com/EPPlus for details.
6 *
7 * Copyright (C) 2011  Jan Källman
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
17 * See the GNU Lesser General Public License for more details.
18 *
19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
21 *
22 * All code and executables are provided "as is" with no warranty either express or implied.
23 * The author accepts no liability for any damage or loss of business that this product may cause.
24 *
25 * Code change notes:
26 *
27 * Author             Change            Date
28 *******************************************************************************
29 * Jan Källman                    Initial Release           2009-10-01
30 * Jan Källman                      Total rewrite               2010-03-01
31 * Jan Källman    License changed GPL-->LGPL 2011-12-27
32 * *******************************************************************************/
33using System;
34using System.Xml;
35using System.Text.RegularExpressions;
36using System.Drawing;
37using System.Collections.Generic;
38using OfficeOpenXml.Drawing.Vml;
39using System.IO;
40using OfficeOpenXml.Drawing;
41using OfficeOpenXml.Utils;
42namespace OfficeOpenXml
43{   
44    /// <summary>
45    /// How a picture will be aligned in the header/footer
46    /// </summary>
47    public enum PictureAlignment
48    {
49        /// <summary>
50        /// The picture will be added to the left aligned text
51        /// </summary>
52        Left,
53        /// <summary>
54        /// The picture will be added to the centered text
55        /// </summary>
56        Centered,
57        /// <summary>
58        /// The picture will be added to the right aligned text
59        /// </summary>
60        Right
61    }
62    #region class ExcelHeaderFooterText
63  /// <summary>
64    /// Print header and footer
65    /// </summary>
66  public class ExcelHeaderFooterText
67  {
68        ExcelWorksheet _ws;
69        string _hf;
70        internal ExcelHeaderFooterText(XmlNode TextNode, ExcelWorksheet ws, string hf)
71        {
72            _ws = ws;
73            _hf = hf;
74            if (TextNode == null || string.IsNullOrEmpty(TextNode.InnerText)) return;
75            string text = TextNode.InnerText;
76            string code = text.Substring(0, 2); 
77            int startPos=2;
78            for (int pos=startPos;pos<text.Length-2;pos++)
79            {
80                string newCode = text.Substring(pos, 2);
81                if (newCode == "&C" || newCode == "&R")
82                {
83                    SetText(code, text.Substring(startPos, pos-startPos));
84                    startPos = pos+2;
85                    pos = startPos;
86                    code = newCode;
87                }
88            }
89            SetText(code, text.Substring(startPos, text.Length - startPos));
90        }
91        private void SetText(string code, string text)
92        {
93            switch (code)
94            {
95                case "&L":
96                    LeftAlignedText=text;
97                    break;
98                case "&C":
99                    CenteredText=text;
100                    break;
101                default:
102                    RightAlignedText=text;
103                    break;
104            }
105        }
106    /// <summary>
107    /// Get/set the text to appear on the left hand side of the header (or footer) on the worksheet.
108    /// </summary>
109    public string LeftAlignedText = null;
110    /// <summary>
111        /// Get/set the text to appear in the center of the header (or footer) on the worksheet.
112    /// </summary>
113    public string CenteredText = null;
114    /// <summary>
115        /// Get/set the text to appear on the right hand side of the header (or footer) on the worksheet.
116    /// </summary>
117    public string RightAlignedText = null;
118        /// <summary>
119        /// Inserts a picture at the end of the text in the header or footer
120        /// </summary>
121        /// <param name="Picture">The image object containing the Picture</param>
122        /// <param name="Alignment">Alignment. The image object will be inserted at the end of the Text.</param>
123        public ExcelVmlDrawingPicture InsertPicture(Image Picture, PictureAlignment Alignment)
124        {
125            string id = ValidateImage(Alignment);
126           
127            //Add the image
128            ImageConverter ic = new ImageConverter();
129            byte[] img = (byte[])ic.ConvertTo(Picture, typeof(byte[]));
130            var ii = _ws.Workbook._package.AddImage(img);
131
132            return AddImage(Picture, id, ii);
133        }
134        /// <summary>
135        /// Inserts a picture at the end of the text in the header or footer
136        /// </summary>
137        /// <param name="PictureFile">The image object containing the Picture</param>
138        /// <param name="Alignment">Alignment. The image object will be inserted at the end of the Text.</param>
139        public ExcelVmlDrawingPicture InsertPicture(FileInfo PictureFile, PictureAlignment Alignment)
140        {
141            string id = ValidateImage(Alignment);
142
143            Image Picture;
144            try
145            {
146                if (!PictureFile.Exists)
147                {
148                    throw (new FileNotFoundException(string.Format("{0} is missing", PictureFile.FullName)));
149                }
150                Picture = Image.FromFile(PictureFile.FullName);
151            }
152            catch (Exception ex)
153            {
154                throw (new InvalidDataException("File is not a supported image-file or is corrupt", ex));
155            }
156
157            ImageConverter ic = new ImageConverter();
158            string contentType = ExcelPicture.GetContentType(PictureFile.Extension);
159            var uriPic = XmlHelper.GetNewUri(_ws._package.Package, "/xl/media/"+PictureFile.Name.Substring(0, PictureFile.Name.Length-PictureFile.Extension.Length) + "{0}" + PictureFile.Extension);
160            byte[] imgBytes = (byte[])ic.ConvertTo(Picture, typeof(byte[]));
161            var ii = _ws.Workbook._package.AddImage(imgBytes, uriPic, contentType);
162
163            return AddImage(Picture, id, ii);
164        }
165
166        private ExcelVmlDrawingPicture AddImage(Image Picture, string id, ExcelPackage.ImageInfo ii)
167        {
168            double width = Picture.Width * 72 / Picture.HorizontalResolution,      //Pixel --> Points
169                   height = Picture.Height * 72 / Picture.VerticalResolution;      //Pixel --> Points
170            //Add VML-drawing           
171            return _ws.HeaderFooter.Pictures.Add(id, ii.Uri, "", width, height);
172        }
173        private string ValidateImage(PictureAlignment Alignment)
174        {
175            string id = string.Concat(Alignment.ToString()[0], _hf);
176            foreach (ExcelVmlDrawingPicture image in _ws.HeaderFooter.Pictures)
177            {
178                if (image.Id == id)
179                {
180                    throw (new InvalidOperationException("A picture already exists in this section"));
181                }
182            }
183            //Add the image placeholder to the end of the text
184            switch (Alignment)
185            {
186                case PictureAlignment.Left:
187                    LeftAlignedText += ExcelHeaderFooter.Image;
188                    break;
189                case PictureAlignment.Centered:
190                    CenteredText += ExcelHeaderFooter.Image;
191                    break;
192                default:
193                    RightAlignedText += ExcelHeaderFooter.Image;
194                    break;
195            }
196            return id;
197        }
198  }
199  #endregion
200
201  #region ExcelHeaderFooter
202  /// <summary>
203  /// Represents the Header and Footer on an Excel Worksheet
204  /// </summary>
205  public sealed class ExcelHeaderFooter : XmlHelper
206  {
207    #region Static Properties
208    /// <summary>
209        /// The code for "current page #"
210    /// </summary>
211    public const string PageNumber = @"&P";
212    /// <summary>
213        /// The code for "total pages"
214    /// </summary>
215    public const string NumberOfPages = @"&N";
216        /// <summary>
217        /// The code for "text font color"
218        /// RGB Color is specified as RRGGBB
219        /// Theme Color is specified as TTSNN where TT is the theme color Id, S is either "+" or "-" of the tint/shade value, NN is the tint/shade value.
220        /// </summary>
221        public const string FontColor = @"&K";
222    /// <summary>
223        /// The code for "sheet tab name"
224    /// </summary>
225    public const string SheetName = @"&A";
226    /// <summary>
227        /// The code for "this workbook's file path"
228    /// </summary>
229    public const string FilePath = @"&Z";
230    /// <summary>
231        /// The code for "this workbook's file name"
232    /// </summary>
233    public const string FileName = @"&F";
234    /// <summary>
235        /// The code for "date"
236    /// </summary>
237    public const string CurrentDate = @"&D";
238    /// <summary>
239        /// The code for "time"
240    /// </summary>
241    public const string CurrentTime = @"&T";
242        /// <summary>
243        /// The code for "picture as background"
244        /// </summary>
245        public const string Image = @"&G";
246        /// <summary>
247        /// The code for "outline style"
248        /// </summary>
249        public const string OutlineStyle = @"&O";
250        /// <summary>
251        /// The code for "shadow style"
252        /// </summary>
253        public const string ShadowStyle = @"&H";
254    #endregion
255
256    #region ExcelHeaderFooter Private Properties
257    internal ExcelHeaderFooterText _oddHeader;
258        internal ExcelHeaderFooterText _oddFooter;
259    internal ExcelHeaderFooterText _evenHeader;
260        internal ExcelHeaderFooterText _evenFooter;
261        internal ExcelHeaderFooterText _firstHeader;
262        internal ExcelHeaderFooterText _firstFooter;
263        private ExcelWorksheet _ws;
264        #endregion
265
266    #region ExcelHeaderFooter Constructor
267    /// <summary>
268    /// ExcelHeaderFooter Constructor
269    /// </summary>
270    /// <param name="nameSpaceManager"></param>
271        /// <param name="topNode"></param>
272        /// <param name="ws">The worksheet</param>
273    internal ExcelHeaderFooter(XmlNamespaceManager nameSpaceManager, XmlNode topNode, ExcelWorksheet ws) :
274            base(nameSpaceManager, topNode)
275    {
276            _ws = ws;
277            SchemaNodeOrder = new string[] { "headerFooter", "oddHeader", "oddFooter", "evenHeader", "evenFooter", "firstHeader", "firstFooter" };
278    }
279    #endregion
280
281    #region alignWithMargins
282        const string alignWithMarginsPath="@alignWithMargins";
283        /// <summary>
284    /// Gets/sets the alignWithMargins attribute
285    /// </summary>
286    public bool AlignWithMargins
287    {
288      get
289      {
290                return GetXmlNodeBool(alignWithMarginsPath);
291      }
292      set
293      {
294                SetXmlNodeString(alignWithMarginsPath, value ? "1" : "0");
295      }
296    }
297    #endregion
298
299        #region differentOddEven
300        const string differentOddEvenPath = "@differentOddEven";
301        /// <summary>
302    /// Gets/sets the flag that tells Excel to display different headers and footers on odd and even pages.
303    /// </summary>
304    public bool differentOddEven
305    {
306      get
307      {
308                return GetXmlNodeBool(differentOddEvenPath);
309      }
310      set
311      {
312                SetXmlNodeString(differentOddEvenPath, value ? "1" : "0");
313      }
314    }
315    #endregion
316
317    #region differentFirst
318        const string differentFirstPath = "@differentFirst";
319
320    /// <summary>
321    /// Gets/sets the flag that tells Excel to display different headers and footers on the first page of the worksheet.
322    /// </summary>
323    public bool differentFirst
324    {
325      get
326      {
327                return GetXmlNodeBool(differentFirstPath);
328      }
329      set
330      {
331                SetXmlNodeString(differentFirstPath, value ? "1" : "0");
332      }
333    }
334    #endregion
335
336    #region ExcelHeaderFooter Public Properties
337    /// <summary>
338    /// Provides access to the header on odd numbered pages of the document.
339    /// If you want the same header on both odd and even pages, then only set values in this ExcelHeaderFooterText class.
340    /// </summary>
341    public ExcelHeaderFooterText OddHeader
342        {
343            get
344            {
345                if (_oddHeader == null)
346                {
347                    _oddHeader = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:oddHeader", NameSpaceManager), _ws, "H");
348                }
349                return _oddHeader; }
350        }
351    /// <summary>
352    /// Provides access to the footer on odd numbered pages of the document.
353    /// If you want the same footer on both odd and even pages, then only set values in this ExcelHeaderFooterText class.
354    /// </summary>
355    public ExcelHeaderFooterText OddFooter
356        {
357            get
358            {
359                if (_oddFooter == null)
360                {
361                    _oddFooter = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:oddFooter", NameSpaceManager), _ws, "F"); ;
362                }
363                return _oddFooter;
364            }
365        }
366    // evenHeader and evenFooter set differentOddEven = true
367    /// <summary>
368    /// Provides access to the header on even numbered pages of the document.
369    /// </summary>
370    public ExcelHeaderFooterText EvenHeader
371        {
372            get
373            {
374                if (_evenHeader == null)
375                {
376                    _evenHeader = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:evenHeader", NameSpaceManager), _ws, "HEVEN");
377                    differentOddEven = true;
378                }
379                return _evenHeader;
380            }
381        }
382    /// <summary>
383    /// Provides access to the footer on even numbered pages of the document.
384    /// </summary>
385    public ExcelHeaderFooterText EvenFooter
386        {
387            get
388            {
389                if (_evenFooter == null)
390                {
391                    _evenFooter = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:evenFooter", NameSpaceManager), _ws, "FEVEN");
392                    differentOddEven = true;
393                }
394                return _evenFooter ;
395            }
396        }
397    /// <summary>
398    /// Provides access to the header on the first page of the document.
399    /// </summary>
400    public ExcelHeaderFooterText FirstHeader
401        {
402            get
403            {
404                if (_firstHeader == null)
405                {
406                    _firstHeader = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:firstHeader", NameSpaceManager), _ws, "HFIRST");
407                     differentFirst = true;
408                }
409                return _firstHeader;
410            }
411        }
412    /// <summary>
413    /// Provides access to the footer on the first page of the document.
414    /// </summary>
415    public ExcelHeaderFooterText FirstFooter
416        {
417            get
418            {
419                if (_firstFooter == null)
420                {
421                    _firstFooter = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:firstFooter", NameSpaceManager), _ws, "FFIRST");
422                    differentFirst = true;
423                }
424                return _firstFooter;
425            }
426        }
427        private ExcelVmlDrawingPictureCollection _vmlDrawingsHF = null;
428        /// <summary>
429        /// Vml drawings. Underlaying object for Header footer images
430        /// </summary>
431        public ExcelVmlDrawingPictureCollection Pictures
432        {
433            get
434            {
435                if (_vmlDrawingsHF == null)
436                {
437                    var vmlNode = _ws.WorksheetXml.SelectSingleNode("d:worksheet/d:legacyDrawingHF/@r:id", NameSpaceManager);
438                    if (vmlNode == null)
439                    {
440                        _vmlDrawingsHF = new ExcelVmlDrawingPictureCollection(_ws._package, _ws, null);
441                    }
442                    else
443                    {
444                        if (_ws.Part.RelationshipExists(vmlNode.Value))
445                        {
446                            var rel = _ws.Part.GetRelationship(vmlNode.Value);
447                            var vmlUri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);
448
449                            _vmlDrawingsHF = new ExcelVmlDrawingPictureCollection(_ws._package, _ws, vmlUri);
450                            _vmlDrawingsHF.RelId = rel.Id;
451                        }
452                    }
453                }
454                return _vmlDrawingsHF;
455            }
456        }
457    #endregion
458    #region Save  //  ExcelHeaderFooter
459    /// <summary>
460    /// Saves the header and footer information to the worksheet XML
461    /// </summary>
462    internal void Save()
463    {
464      if (_oddHeader != null)
465      {
466                SetXmlNodeString("d:oddHeader", GetText(OddHeader));
467      }
468      if (_oddFooter != null)
469      {
470                SetXmlNodeString("d:oddFooter", GetText(OddFooter));
471      }
472
473      // only set evenHeader and evenFooter
474      if (differentOddEven)
475      {
476        if (_evenHeader != null)
477        {
478                    SetXmlNodeString("d:evenHeader", GetText(EvenHeader));
479        }
480        if (_evenFooter != null)
481        {
482                    SetXmlNodeString("d:evenFooter", GetText(EvenFooter));
483        }
484      }
485
486      // only set firstHeader and firstFooter
487      if (differentFirst)
488      {
489        if (_firstHeader != null)
490        {
491                    SetXmlNodeString("d:firstHeader", GetText(FirstHeader));
492        }
493        if (_firstFooter != null)
494        {
495                    SetXmlNodeString("d:firstFooter", GetText(FirstFooter));
496        }
497      }
498    }
499        internal void SaveHeaderFooterImages()
500        {
501            if (_vmlDrawingsHF != null)
502            {
503                if (_vmlDrawingsHF.Count == 0)
504                {
505                    if (_vmlDrawingsHF.Uri != null)
506                    {
507                        _ws.Part.DeleteRelationship(_vmlDrawingsHF.RelId);
508                        _ws._package.Package.DeletePart(_vmlDrawingsHF.Uri);
509                    }
510                }
511                else
512                {
513                    if (_vmlDrawingsHF.Uri == null)
514                    {
515                        _vmlDrawingsHF.Uri = XmlHelper.GetNewUri(_ws._package.Package, @"/xl/drawings/vmlDrawing{0}.vml");
516                    }
517                    if (_vmlDrawingsHF.Part == null)
518                    {
519                        _vmlDrawingsHF.Part = _ws._package.Package.CreatePart(_vmlDrawingsHF.Uri, "application/vnd.openxmlformats-officedocument.vmlDrawing", _ws._package.Compression);
520                        var rel = _ws.Part.CreateRelationship(UriHelper.GetRelativeUri(_ws.WorksheetUri, _vmlDrawingsHF.Uri), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/vmlDrawing");
521                        _ws.SetHFLegacyDrawingRel(rel.Id);
522                        _vmlDrawingsHF.RelId = rel.Id;
523                        foreach (ExcelVmlDrawingPicture draw in _vmlDrawingsHF)
524                        {
525                            rel = _vmlDrawingsHF.Part.CreateRelationship(UriHelper.GetRelativeUri(_vmlDrawingsHF.Uri, draw.ImageUri), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/image");
526                            draw.RelId = rel.Id;
527                        }
528                    }
529                    _vmlDrawingsHF.VmlDrawingXml.Save(_vmlDrawingsHF.Part.GetStream());
530                }
531            }
532        }
533    private string GetText(ExcelHeaderFooterText headerFooter)
534    {
535      string ret = "";
536      if (headerFooter.LeftAlignedText != null)
537        ret += "&L" + headerFooter.LeftAlignedText;
538      if (headerFooter.CenteredText != null)
539        ret += "&C" + headerFooter.CenteredText;
540      if (headerFooter.RightAlignedText != null)
541        ret += "&R" + headerFooter.RightAlignedText;
542      return ret;
543    }
544    #endregion
545  }
546  #endregion
547}
Note: See TracBrowser for help on using the repository browser.