YNICTE/packages/OfficeOpenXml.Core.ExcelPac.../src/OfficeOpenXml.Core.ExcelPac.../ExcelExtensions.cs

216 lines
6.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using System.Xml.Linq;
namespace OfficeOpenXml.Core.ExcelPackage
{
public static class ExcelExtensions
{
public static XElement CreateElement(this XDocument element, string name)
{
return new XElement(name);
}
public static string GetAttribute(this XElement element, string name, string sub = null)
{
return element.Attribute(name)?.Value ?? sub;
}
public static void AppendChild(this XElement element, object content)
{
element.Add(content);
}
public static void AppendChild(this XDocument element, object content)
{
element.Add(content);
}
public static XElement CloneNode(this XElement element, bool deep)
{
return element;
}
public static XAttribute GetAttributeNode(this XElement root, string name)
{
throw new NotImplementedException();
}
public static ConstructorInfo FilterConstructorsByType(this IEnumerable<ConstructorInfo> constructors, params Type[] types)
{
throw new NotImplementedException();
}
// This function is duplicated in COMDateTime.cpp
// Number of 100ns ticks per time unit
private const long TicksPerMillisecond = 10000;
private const long TicksPerSecond = TicksPerMillisecond * 1000;
private const long TicksPerMinute = TicksPerSecond * 60;
private const long TicksPerHour = TicksPerMinute * 60;
private const long TicksPerDay = TicksPerHour * 24;
// Number of milliseconds per time unit
private const int MillisPerSecond = 1000;
private const int MillisPerMinute = MillisPerSecond * 60;
private const int MillisPerHour = MillisPerMinute * 60;
private const int MillisPerDay = MillisPerHour * 24;
// Number of days in a non-leap year
private const int DaysPerYear = 365;
// Number of days in 4 years
private const int DaysPer4Years = DaysPerYear * 4 + 1;
// Number of days in 100 years
private const int DaysPer100Years = DaysPer4Years * 25 - 1;
// Number of days in 400 years
private const int DaysPer400Years = DaysPer100Years * 4 + 1;
private const int DaysTo1899 = DaysPer400Years*4 + DaysPer100Years*3 - 367;
private const long DoubleDateOffset = DaysTo1899 * TicksPerDay;
private const long OADateMinAsTicks = (DaysPer100Years - DaysPerYear) * TicksPerDay;
private static double TicksToOADate(long value)
{
if (value == 0)
return 0.0; // Returns OleAut's zero'ed date value.
if (value < TicksPerDay) // This is a fix for VB. They want the default day to be 1/1/0001 rathar then 12/30/1899.
value += DoubleDateOffset; // We could have moved this fix down but we would like to keep the bounds check.
if (value < OADateMinAsTicks)
throw new OverflowException("Arg_OleAutDateInvalid");
// Currently, our max date == OA's max date (12/31/9999), so we don't
// need an overflow check in that direction.
long millis = (value - DoubleDateOffset) / TicksPerMillisecond;
if (millis < 0)
{
long frac = millis % MillisPerDay;
if (frac != 0) millis -= (MillisPerDay + frac) * 2;
}
return (double)millis / MillisPerDay;
}
#if !NET46
public static double ToOADate(this DateTime root)
{
return TicksToOADate(root.Ticks);
}
#endif
public static string OuterXml(this XElement root)
{
using (var reader = root.CreateReader())
{
reader.MoveToContent();
return reader.ReadOuterXml();
}
}
public static string OuterXml(this XNode root)
{
using (var reader = root.CreateReader())
{
reader.MoveToContent();
return reader.ReadOuterXml();
}
}
public static string InnerXml(this XElement root)
{
using (var reader = root.CreateReader())
{
reader.MoveToContent();
return reader.ReadInnerXml();
}
}
public static string Prefix(this XElement root)
{
return root.GetPrefixOfNamespace(root.Name.Namespace);
}
public static IEnumerable<XElement> ChildElements(this XElement root)
{
foreach (XNode childNode in root.Nodes())
{
var elm = childNode as XElement;
if (elm != null)
{
yield return elm;
}
}
}
public static XElement AddSchemaAttribute(this XElement root, string schema)
{
var nsAttribute =
new XAttribute("xmlns", schema);
root.Add(nsAttribute);
return root;
}
public static string AttributeValue(this XElement element, string attribute, string sub = null)
{
return element.Attribute(attribute).Value ?? sub;
}
public static XElement SetAttrValue(this XElement element, string attribute, string value)
{
element.SetAttributeValue(attribute, value);
return element;
//var attr = element.Attribute(attribute);
//if (attr == null)
//{
// attr = new XAttribute(attribute, value);
//}
//else
//{
// attr.Value = value;
//}
//return element;
}
/// <summary>
/// Adds additional schema attributes to the root element
/// </summary>
/// <param name="root">The root element</param>
/// <param name="nameSpace">The namespace of the schema</param>
/// <param name="schema">The schema to apply</param>
public static XElement AddSchemaAttribute(this XElement root, XNamespace schema, string nameSpace)
{
var nsAttribute =
new XAttribute(XNamespace.Xmlns + nameSpace, schema);
root.Add(nsAttribute);
return root;
}
public static XElement SetAttribute(this XElement element, string name, string value)
{
element.SetAttributeValue(name, value);
return element;
}
//public static XElement SetAttribute(this XElement root, string name, string value)
//{
// var nsAttribute =
// new XAttribute(name, value);
// root.Add(nsAttribute);
// return root;
//}
public static XmlNameTable NameTable(this XDocument doc)
{
using (var reader = doc.CreateReader())
{
return reader.NameTable;
}
}
public static XElement SetAttribute(this XElement root, string name, XNamespace schema, string value)
{
var nsAttribute =
new XAttribute(schema + name, value);
root.Add(nsAttribute);
return root;
}
}
}