|  | /******************************************************************************* | 
|  | * 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                      Total rewrite               2010-03-01 | 
|  | * Jan K�llman		    License changed GPL-->LGPL  2011-12-27 | 
|  | * Raziq York                       Added Created & Modified    2014-08-20 | 
|  | *******************************************************************************/ | 
|  |  | 
|  | using System; | 
|  | using System.Globalization; | 
|  | using System.Xml; | 
|  |  | 
|  | namespace OfficeOpenXml; | 
|  |  | 
|  | /// <summary> | 
|  | /// Provides access to the properties bag of the package | 
|  | /// </summary> | 
|  | public sealed class OfficeProperties : XmlHelper { | 
|  | private readonly XmlDocument _xmlPropertiesCore; | 
|  | private readonly XmlDocument _xmlPropertiesExtended; | 
|  |  | 
|  | private readonly Uri _uriPropertiesCore = new("/docProps/core.xml", UriKind.Relative); | 
|  | private readonly Uri _uriPropertiesExtended = new("/docProps/app.xml", UriKind.Relative); | 
|  |  | 
|  | private readonly XmlHelper _coreHelper; | 
|  | private readonly XmlHelper _extendedHelper; | 
|  |  | 
|  | /// <summary> | 
|  | /// Provides access to all the office document properties. | 
|  | /// </summary> | 
|  | /// <param name="package"></param> | 
|  | /// <param name="ns"></param> | 
|  | internal OfficeProperties(ExcelPackage package, XmlNamespaceManager ns) | 
|  | : base(ns) { | 
|  | const string coreBaseXml = | 
|  | $"""<?xml version="1.0" encoding="UTF-8" standalone="yes" ?><cp:coreProperties xmlns:cp="{ExcelPackage._schemaCore}" xmlns:dc="{ExcelPackage._schemaDc}" xmlns:dcterms="{ExcelPackage._schemaDcTerms}" xmlns:dcmitype="{ExcelPackage._schemaDcmiType}" xmlns:xsi="{ExcelPackage._schemaXsi}"></cp:coreProperties>"""; | 
|  | _xmlPropertiesCore = package.GetOrCreateXmlDocument( | 
|  | _uriPropertiesCore, | 
|  | "application/vnd.openxmlformats-package.core-properties+xml", | 
|  | "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties", | 
|  | coreBaseXml); | 
|  | _coreHelper = XmlHelperFactory.Create( | 
|  | ns, | 
|  | _xmlPropertiesCore.SelectSingleNode("cp:coreProperties", NameSpaceManager)); | 
|  |  | 
|  | const string extendedBaseXml = | 
|  | $"""<?xml version="1.0" encoding="UTF-8" standalone="yes" ?><Properties xmlns:vt="{ExcelPackage._schemaVt}" xmlns="{ExcelPackage._schemaExtended}"></Properties>"""; | 
|  | _xmlPropertiesExtended = package.GetOrCreateXmlDocument( | 
|  | _uriPropertiesExtended, | 
|  | "application/vnd.openxmlformats-officedocument.extended-properties+xml", | 
|  | "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties", | 
|  | extendedBaseXml); | 
|  | _extendedHelper = XmlHelperFactory.Create(ns, _xmlPropertiesExtended); | 
|  | } | 
|  |  | 
|  | private const string _titlePath = "dc:title"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the title property of the document (core property) | 
|  | /// </summary> | 
|  | public string Title { | 
|  | get => _coreHelper.GetXmlNodeString(_titlePath); | 
|  | set => _coreHelper.SetXmlNodeString(_titlePath, value); | 
|  | } | 
|  |  | 
|  | private const string _subjectPath = "dc:subject"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the subject property of the document (core property) | 
|  | /// </summary> | 
|  | public string Subject { | 
|  | get => _coreHelper.GetXmlNodeString(_subjectPath); | 
|  | set => _coreHelper.SetXmlNodeString(_subjectPath, value); | 
|  | } | 
|  |  | 
|  | private const string _authorPath = "dc:creator"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the author property of the document (core property) | 
|  | /// </summary> | 
|  | public string Author { | 
|  | get => _coreHelper.GetXmlNodeString(_authorPath); | 
|  | set => _coreHelper.SetXmlNodeString(_authorPath, value); | 
|  | } | 
|  |  | 
|  | private const string _commentsPath = "dc:description"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the comments property of the document (core property) | 
|  | /// </summary> | 
|  | public string Comments { | 
|  | get => _coreHelper.GetXmlNodeString(_commentsPath); | 
|  | set => _coreHelper.SetXmlNodeString(_commentsPath, value); | 
|  | } | 
|  |  | 
|  | private const string _keywordsPath = "cp:keywords"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the keywords property of the document (core property) | 
|  | /// </summary> | 
|  | public string Keywords { | 
|  | get => _coreHelper.GetXmlNodeString(_keywordsPath); | 
|  | set => _coreHelper.SetXmlNodeString(_keywordsPath, value); | 
|  | } | 
|  |  | 
|  | private const string _lastModifiedByPath = "cp:lastModifiedBy"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the lastModifiedBy property of the document (core property) | 
|  | /// </summary> | 
|  | public string LastModifiedBy { | 
|  | get => _coreHelper.GetXmlNodeString(_lastModifiedByPath); | 
|  | set => _coreHelper.SetXmlNodeString(_lastModifiedByPath, value); | 
|  | } | 
|  |  | 
|  | private const string _lastPrintedPath = "cp:lastPrinted"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the lastPrinted property of the document (core property) | 
|  | /// </summary> | 
|  | public string LastPrinted { | 
|  | get => _coreHelper.GetXmlNodeString(_lastPrintedPath); | 
|  | set => _coreHelper.SetXmlNodeString(_lastPrintedPath, value); | 
|  | } | 
|  |  | 
|  | private const string _createdPath = "dcterms:created"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the created property of the document (core property) | 
|  | /// </summary> | 
|  | public DateTime Created { | 
|  | get => | 
|  | DateTime.TryParse(_coreHelper.GetXmlNodeString(_createdPath), out var date) | 
|  | ? date | 
|  | : DateTime.MinValue; | 
|  | set { | 
|  | var dateString = value.ToUniversalTime().ToString("s", CultureInfo.InvariantCulture) + "Z"; | 
|  | _coreHelper.SetXmlNodeString(_createdPath, dateString); | 
|  | _coreHelper.SetXmlNodeString(_createdPath + "/@xsi:type", "dcterms:W3CDTF"); | 
|  | } | 
|  | } | 
|  |  | 
|  | private const string _categoryPath = "cp:category"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the category property of the document (core property) | 
|  | /// </summary> | 
|  | public string Category { | 
|  | get => _coreHelper.GetXmlNodeString(_categoryPath); | 
|  | set => _coreHelper.SetXmlNodeString(_categoryPath, value); | 
|  | } | 
|  |  | 
|  | private const string _contentStatusPath = "cp:contentStatus"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the status property of the document (core property) | 
|  | /// </summary> | 
|  | public string Status { | 
|  | get => _coreHelper.GetXmlNodeString(_contentStatusPath); | 
|  | set => _coreHelper.SetXmlNodeString(_contentStatusPath, value); | 
|  | } | 
|  |  | 
|  | /// <summary> | 
|  | /// Provides access to the XML document that holds the extended properties of the document (app.xml) | 
|  | /// </summary> | 
|  | public XmlDocument ExtendedPropertiesXml { | 
|  | get { | 
|  | if (_xmlPropertiesExtended == null) {} | 
|  | return (_xmlPropertiesExtended); | 
|  | } | 
|  | } | 
|  |  | 
|  | private const string _applicationPath = "xp:Properties/xp:Application"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/Set the Application property of the document (extended property) | 
|  | /// </summary> | 
|  | public string Application { | 
|  | get => _extendedHelper.GetXmlNodeString(_applicationPath); | 
|  | set => _extendedHelper.SetXmlNodeString(_applicationPath, value); | 
|  | } | 
|  |  | 
|  | private const string _hyperlinkBasePath = "xp:Properties/xp:HyperlinkBase"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the HyperlinkBase property of the document (extended property) | 
|  | /// </summary> | 
|  | public Uri HyperlinkBase { | 
|  | get => new(_extendedHelper.GetXmlNodeString(_hyperlinkBasePath), UriKind.Absolute); | 
|  | set => _extendedHelper.SetXmlNodeString(_hyperlinkBasePath, value.AbsoluteUri); | 
|  | } | 
|  |  | 
|  | private const string _appVersionPath = "xp:Properties/xp:AppVersion"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/Set the AppVersion property of the document (extended property) | 
|  | /// </summary> | 
|  | public string AppVersion { | 
|  | get => _extendedHelper.GetXmlNodeString(_appVersionPath); | 
|  | set => _extendedHelper.SetXmlNodeString(_appVersionPath, value); | 
|  | } | 
|  |  | 
|  | private const string _companyPath = "xp:Properties/xp:Company"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the Company property of the document (extended property) | 
|  | /// </summary> | 
|  | public string Company { | 
|  | get => _extendedHelper.GetXmlNodeString(_companyPath); | 
|  | set => _extendedHelper.SetXmlNodeString(_companyPath, value); | 
|  | } | 
|  |  | 
|  | private const string _managerPath = "xp:Properties/xp:Manager"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the Manager property of the document (extended property) | 
|  | /// </summary> | 
|  | public string Manager { | 
|  | get => _extendedHelper.GetXmlNodeString(_managerPath); | 
|  | set => _extendedHelper.SetXmlNodeString(_managerPath, value); | 
|  | } | 
|  |  | 
|  | private const string _modifiedPath = "dcterms:modified"; | 
|  |  | 
|  | /// <summary> | 
|  | /// Gets/sets the modified property of the document (core property) | 
|  | /// </summary> | 
|  | public DateTime Modified { | 
|  | get => | 
|  | DateTime.TryParse(_coreHelper.GetXmlNodeString(_modifiedPath), out var date) | 
|  | ? date | 
|  | : DateTime.MinValue; | 
|  | set { | 
|  | var dateString = value.ToUniversalTime().ToString("s", CultureInfo.InvariantCulture) + "Z"; | 
|  | _coreHelper.SetXmlNodeString(_modifiedPath, dateString); | 
|  | _coreHelper.SetXmlNodeString(_modifiedPath + "/@xsi:type", "dcterms:W3CDTF"); | 
|  | } | 
|  | } | 
|  | } |