Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/OfficeProperties.cs @ 17945

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

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 21.7 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 * Raziq York                       Added Created & Modified    2014-08-20
33 *******************************************************************************/
34using System;
35using System.Xml;
36using System.IO;
37using System.Globalization;
38using OfficeOpenXml.Utils;
39
40namespace OfficeOpenXml
41{
42    /// <summary>
43    /// Provides access to the properties bag of the package
44    /// </summary>
45    public sealed class OfficeProperties : XmlHelper
46    {
47        #region Private Properties
48        private XmlDocument _xmlPropertiesCore;
49        private XmlDocument _xmlPropertiesExtended;
50        private XmlDocument _xmlPropertiesCustom;
51
52        private Uri _uriPropertiesCore = new Uri("/docProps/core.xml", UriKind.Relative);
53        private Uri _uriPropertiesExtended = new Uri("/docProps/app.xml", UriKind.Relative);
54        private Uri _uriPropertiesCustom = new Uri("/docProps/custom.xml", UriKind.Relative);
55
56        XmlHelper _coreHelper;
57        XmlHelper _extendedHelper;
58        XmlHelper _customHelper;
59        private ExcelPackage _package;
60        #endregion
61
62        #region ExcelProperties Constructor
63        /// <summary>
64        /// Provides access to all the office document properties.
65        /// </summary>
66        /// <param name="package"></param>
67        /// <param name="ns"></param>
68        internal OfficeProperties(ExcelPackage package, XmlNamespaceManager ns) :
69            base(ns)
70        {
71            _package = package;
72
73            _coreHelper = XmlHelperFactory.Create(ns, CorePropertiesXml.SelectSingleNode("cp:coreProperties", NameSpaceManager));
74            _extendedHelper = XmlHelperFactory.Create(ns, ExtendedPropertiesXml);
75            _customHelper = XmlHelperFactory.Create(ns, CustomPropertiesXml);
76
77        }
78        #endregion
79        #region CorePropertiesXml
80        /// <summary>
81        /// Provides access to the XML document that holds all the code
82        /// document properties.
83        /// </summary>
84        public XmlDocument CorePropertiesXml
85        {
86            get
87            {
88                if (_xmlPropertiesCore == null)
89                {
90                    string xml = string.Format("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><cp:coreProperties xmlns:cp=\"{0}\" xmlns:dc=\"{1}\" xmlns:dcterms=\"{2}\" xmlns:dcmitype=\"{3}\" xmlns:xsi=\"{4}\"></cp:coreProperties>",
91                        ExcelPackage.schemaCore,
92                        ExcelPackage.schemaDc,
93                        ExcelPackage.schemaDcTerms,
94                        ExcelPackage.schemaDcmiType,
95                        ExcelPackage.schemaXsi);
96
97                    _xmlPropertiesCore = GetXmlDocument(xml, _uriPropertiesCore, @"application/vnd.openxmlformats-package.core-properties+xml", @"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties");
98                }
99                return (_xmlPropertiesCore);
100            }
101        }
102
103        private XmlDocument GetXmlDocument(string startXml, Uri uri, string contentType, string relationship)
104        {
105            XmlDocument xmlDoc;
106            if (_package.Package.PartExists(uri))
107                xmlDoc = _package.GetXmlFromUri(uri);
108            else
109            {
110                xmlDoc = new XmlDocument();
111                xmlDoc.LoadXml(startXml);
112
113                // Create a the part and add to the package
114                Packaging.ZipPackagePart part = _package.Package.CreatePart(uri, contentType);
115
116                // Save it to the package
117                StreamWriter stream = new StreamWriter(part.GetStream(FileMode.Create, FileAccess.Write));
118                xmlDoc.Save(stream);
119                //stream.Close();
120                _package.Package.Flush();
121
122                // create the relationship between the workbook and the new shared strings part
123                _package.Package.CreateRelationship(UriHelper.GetRelativeUri(new Uri("/xl", UriKind.Relative), uri), Packaging.TargetMode.Internal, relationship);
124                _package.Package.Flush();
125            }
126            return xmlDoc;
127        }
128        #endregion
129        #region Core Properties
130        const string TitlePath = "dc:title";
131        /// <summary>
132        /// Gets/sets the title property of the document (core property)
133        /// </summary>
134        public string Title
135        {
136            get { return _coreHelper.GetXmlNodeString(TitlePath); }
137            set { _coreHelper.SetXmlNodeString(TitlePath, value); }
138        }
139
140        const string SubjectPath = "dc:subject";
141        /// <summary>
142        /// Gets/sets the subject property of the document (core property)
143        /// </summary>
144        public string Subject
145        {
146            get { return _coreHelper.GetXmlNodeString(SubjectPath); }
147            set { _coreHelper.SetXmlNodeString(SubjectPath, value); }
148        }
149
150        const string AuthorPath = "dc:creator";
151        /// <summary>
152        /// Gets/sets the author property of the document (core property)
153        /// </summary>
154        public string Author
155        {
156            get { return _coreHelper.GetXmlNodeString(AuthorPath); }
157            set { _coreHelper.SetXmlNodeString(AuthorPath, value); }
158        }
159
160        const string CommentsPath = "dc:description";
161        /// <summary>
162        /// Gets/sets the comments property of the document (core property)
163        /// </summary>
164        public string Comments
165        {
166            get { return _coreHelper.GetXmlNodeString(CommentsPath); }
167            set { _coreHelper.SetXmlNodeString(CommentsPath, value); }
168        }
169
170        const string KeywordsPath = "cp:keywords";
171        /// <summary>
172        /// Gets/sets the keywords property of the document (core property)
173        /// </summary>
174        public string Keywords
175        {
176            get { return _coreHelper.GetXmlNodeString(KeywordsPath); }
177            set { _coreHelper.SetXmlNodeString(KeywordsPath, value); }
178        }
179
180        const string LastModifiedByPath = "cp:lastModifiedBy";
181        /// <summary>
182        /// Gets/sets the lastModifiedBy property of the document (core property)
183        /// </summary>
184        public string LastModifiedBy
185        {
186            get { return _coreHelper.GetXmlNodeString(LastModifiedByPath); }
187            set { _coreHelper.SetXmlNodeString(LastModifiedByPath, value); }
188        }
189
190        const string LastPrintedPath = "cp:lastPrinted";
191        /// <summary>
192        /// Gets/sets the lastPrinted property of the document (core property)
193        /// </summary>
194        public string LastPrinted
195        {
196            get { return _coreHelper.GetXmlNodeString(LastPrintedPath); }
197            set { _coreHelper.SetXmlNodeString(LastPrintedPath, value); }
198        }
199
200        const string CreatedPath = "dcterms:created";
201
202        /// <summary>
203      /// Gets/sets the created property of the document (core property)
204      /// </summary>
205      public DateTime Created
206      {
207          get
208          {
209              DateTime date;
210              return DateTime.TryParse(_coreHelper.GetXmlNodeString(CreatedPath), out date) ? date : DateTime.MinValue;
211          }
212          set
213          {
214              var dateString = value.ToUniversalTime().ToString("s", CultureInfo.InvariantCulture) + "Z";
215              _coreHelper.SetXmlNodeString(CreatedPath, dateString);
216          }
217      }
218
219        const string CategoryPath = "cp:category";
220        /// <summary>
221        /// Gets/sets the category property of the document (core property)
222        /// </summary>
223        public string Category
224        {
225            get { return _coreHelper.GetXmlNodeString(CategoryPath); }
226            set { _coreHelper.SetXmlNodeString(CategoryPath, value); }
227        }
228
229        const string ContentStatusPath = "cp:contentStatus";
230        /// <summary>
231        /// Gets/sets the status property of the document (core property)
232        /// </summary>
233        public string Status
234        {
235            get { return _coreHelper.GetXmlNodeString(ContentStatusPath); }
236            set { _coreHelper.SetXmlNodeString(ContentStatusPath, value); }
237        }
238        #endregion
239
240        #region Extended Properties
241        #region ExtendedPropertiesXml
242        /// <summary>
243        /// Provides access to the XML document that holds the extended properties of the document (app.xml)
244        /// </summary>
245        public XmlDocument ExtendedPropertiesXml
246        {
247            get
248            {
249                if (_xmlPropertiesExtended == null)
250                {
251                    _xmlPropertiesExtended = GetXmlDocument(string.Format("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><Properties xmlns:vt=\"{0}\" xmlns=\"{1}\"></Properties>",
252                            ExcelPackage.schemaVt,
253                            ExcelPackage.schemaExtended),
254                        _uriPropertiesExtended,
255                        @"application/vnd.openxmlformats-officedocument.extended-properties+xml",
256                        @"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties");
257                }
258                return (_xmlPropertiesExtended);
259            }
260        }
261        #endregion
262
263        const string ApplicationPath = "xp:Properties/xp:Application";
264        /// <summary>
265        /// Gets the Application property of the document (extended property)
266        /// </summary>
267        public string Application
268        {
269            get { return _extendedHelper.GetXmlNodeString(ApplicationPath); }
270        }
271
272        const string HyperlinkBasePath = "xp:Properties/xp:HyperlinkBase";
273        /// <summary>
274        /// Gets/sets the HyperlinkBase property of the document (extended property)
275        /// </summary>
276        public Uri HyperlinkBase
277        {
278            get { return new Uri(_extendedHelper.GetXmlNodeString(HyperlinkBasePath), UriKind.Absolute); }
279            set { _extendedHelper.SetXmlNodeString(HyperlinkBasePath, value.AbsoluteUri); }
280        }
281
282        const string AppVersionPath = "xp:Properties/xp:AppVersion";
283        /// <summary>
284        /// Gets the AppVersion property of the document (extended property)
285        /// </summary>
286        public string AppVersion
287        {
288            get { return _extendedHelper.GetXmlNodeString(AppVersionPath); }
289        }
290        const string CompanyPath = "xp:Properties/xp:Company";
291
292        /// <summary>
293        /// Gets/sets the Company property of the document (extended property)
294        /// </summary>
295        public string Company
296        {
297            get { return _extendedHelper.GetXmlNodeString(CompanyPath); }
298            set { _extendedHelper.SetXmlNodeString(CompanyPath, value); }
299        }
300
301        const string ManagerPath = "xp:Properties/xp:Manager";
302        /// <summary>
303        /// Gets/sets the Manager property of the document (extended property)
304        /// </summary>
305        public string Manager
306        {
307            get { return _extendedHelper.GetXmlNodeString(ManagerPath); }
308            set { _extendedHelper.SetXmlNodeString(ManagerPath, value); }
309        }
310
311        const string ModifiedPath = "dcterms:modified";
312      /// <summary>
313      /// Gets/sets the modified property of the document (core property)
314      /// </summary>
315      public DateTime Modified
316      {
317          get
318          {
319              DateTime date;
320              return DateTime.TryParse(_coreHelper.GetXmlNodeString(ModifiedPath), out date) ? date : DateTime.MinValue;
321          }
322          set
323          {
324              var dateString = value.ToUniversalTime().ToString("s", CultureInfo.InvariantCulture) + "Z";
325              _coreHelper.SetXmlNodeString(ModifiedPath, dateString);
326          }
327      }
328
329        #region Get and Set Extended Properties
330        private string GetExtendedPropertyValue(string propertyName)
331        {
332            string retValue = null;
333            string searchString = string.Format("xp:Properties/xp:{0}", propertyName);
334            XmlNode node = ExtendedPropertiesXml.SelectSingleNode(searchString, NameSpaceManager);
335            if (node != null)
336            {
337                retValue = node.InnerText;
338            }
339            return retValue;
340        }
341        #endregion
342        #endregion
343
344        #region Custom Properties
345
346        #region CustomPropertiesXml
347        /// <summary>
348        /// Provides access to the XML document which holds the document's custom properties
349        /// </summary>
350        public XmlDocument CustomPropertiesXml
351        {
352            get
353            {
354                if (_xmlPropertiesCustom == null)
355                {
356                    _xmlPropertiesCustom = GetXmlDocument(string.Format("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><Properties xmlns:vt=\"{0}\" xmlns=\"{1}\"></Properties>",
357                            ExcelPackage.schemaVt,
358                            ExcelPackage.schemaCustom),
359                         _uriPropertiesCustom,
360                         @"application/vnd.openxmlformats-officedocument.custom-properties+xml",
361                         @"http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties");
362                }
363                return (_xmlPropertiesCustom);
364            }
365        }
366        #endregion
367
368        #region Get and Set Custom Properties
369        /// <summary>
370        /// Gets the value of a custom property
371        /// </summary>
372        /// <param name="propertyName">The name of the property</param>
373        /// <returns>The current value of the property</returns>
374        public object GetCustomPropertyValue(string propertyName)
375        {
376            string searchString = string.Format("ctp:Properties/ctp:property[@name='{0}']", propertyName);
377            XmlElement node = CustomPropertiesXml.SelectSingleNode(searchString, NameSpaceManager) as XmlElement;
378            if (node != null)
379            {
380                string value = node.LastChild.InnerText;
381                switch (node.LastChild.LocalName)
382                {
383                    case "filetime":
384                        DateTime dt;
385                        if (DateTime.TryParse(value, out dt))
386                        {
387                            return dt;
388                        }
389                        else
390                        {
391                            return null;
392                        }
393                    case "i4":
394                        int i;
395                        if (int.TryParse(value, out i))
396                        {
397                            return i;
398                        }
399                        else
400                        {
401                            return null;
402                        }
403                    case "r8":
404                        double d;
405                        if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out d))
406                        {
407                            return d;
408                        }
409                        else
410                        {
411                            return null;
412                        }
413                    case "bool":
414                        if (value == "true")
415                        {
416                            return true;
417                        }
418                        else if (value == "false")
419                        {
420                            return false;
421                        }
422                        else
423                        {
424                            return null;
425                        }
426                    default:
427                        return value;
428                }
429            }
430            else
431            {
432                return null;
433            }
434        }
435
436        /// <summary>
437        /// Allows you to set the value of a current custom property or create your own custom property. 
438        /// </summary>
439        /// <param name="propertyName">The name of the property</param>
440        /// <param name="value">The value of the property</param>
441        public void SetCustomPropertyValue(string propertyName, object value)
442        {
443            XmlNode allProps = CustomPropertiesXml.SelectSingleNode(@"ctp:Properties", NameSpaceManager);
444
445            var prop = string.Format("ctp:Properties/ctp:property[@name='{0}']", propertyName);
446            XmlElement node = CustomPropertiesXml.SelectSingleNode(prop, NameSpaceManager) as XmlElement;
447            if (node == null)
448            {
449                int pid;
450                var MaxNode = CustomPropertiesXml.SelectSingleNode("ctp:Properties/ctp:property[not(@pid <= preceding-sibling::ctp:property/@pid) and not(@pid <= following-sibling::ctp:property/@pid)]", NameSpaceManager);
451                if (MaxNode == null)
452                {
453                    pid = 2;
454                }
455                else
456                {
457                    if (!int.TryParse(MaxNode.Attributes["pid"].Value, out pid))
458                    {
459                        pid = 2;
460                    }
461                    pid++;
462                }
463                node = CustomPropertiesXml.CreateElement("property", ExcelPackage.schemaCustom);
464                node.SetAttribute("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}");
465                node.SetAttribute("pid", pid.ToString());  // custom property pid
466                node.SetAttribute("name", propertyName);
467
468                allProps.AppendChild(node);
469            }
470            else
471            {
472                while (node.ChildNodes.Count > 0) node.RemoveChild(node.ChildNodes[0]);
473            }
474            XmlElement valueElem;
475            if (value is bool)
476            {
477                valueElem = CustomPropertiesXml.CreateElement("vt", "bool", ExcelPackage.schemaVt);
478                valueElem.InnerText = value.ToString().ToLower(CultureInfo.InvariantCulture);
479            }
480            else if (value is DateTime)
481            {
482                valueElem = CustomPropertiesXml.CreateElement("vt", "filetime", ExcelPackage.schemaVt);
483                valueElem.InnerText = ((DateTime)value).AddHours(-1).ToString("yyyy-MM-ddTHH:mm:ssZ");
484            }
485            else if (value is short || value is int)
486            {
487                valueElem = CustomPropertiesXml.CreateElement("vt", "i4", ExcelPackage.schemaVt);
488                valueElem.InnerText = value.ToString();
489            }
490            else if (value is double || value is decimal || value is float || value is long)
491            {
492                valueElem = CustomPropertiesXml.CreateElement("vt", "r8", ExcelPackage.schemaVt);
493                if (value is double)
494                {
495                    valueElem.InnerText = ((double)value).ToString(CultureInfo.InvariantCulture);
496                }
497                else if (value is float)
498                {
499                    valueElem.InnerText = ((float)value).ToString(CultureInfo.InvariantCulture);
500                }
501                else if (value is decimal)
502                {
503                    valueElem.InnerText = ((decimal)value).ToString(CultureInfo.InvariantCulture);
504                }
505                else
506                {
507                    valueElem.InnerText = value.ToString();
508                }
509            }
510            else
511            {
512                valueElem = CustomPropertiesXml.CreateElement("vt", "lpwstr", ExcelPackage.schemaVt);
513                valueElem.InnerText = value.ToString();
514            }
515            node.AppendChild(valueElem);
516        }
517        #endregion
518        #endregion
519
520        #region Save
521        /// <summary>
522        /// Saves the document properties back to the package.
523        /// </summary>
524        internal void Save()
525        {
526            if (_xmlPropertiesCore != null)
527            {
528                _package.SavePart(_uriPropertiesCore, _xmlPropertiesCore);
529            }
530            if (_xmlPropertiesExtended != null)
531            {
532                _package.SavePart(_uriPropertiesExtended, _xmlPropertiesExtended);
533            }
534            if (_xmlPropertiesCustom != null)
535            {
536                _package.SavePart(_uriPropertiesCustom, _xmlPropertiesCustom);
537            }
538
539        }
540        #endregion
541
542    }
543}
Note: See TracBrowser for help on using the repository browser.