|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Reflection;
|
|
|
|
using System.Xml;
|
|
|
|
using System.Xml.Linq;
|
|
|
|
|
|
|
|
namespace Npoi.Core
|
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
return root.Attribute(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static ConstructorInfo FilterConstructorsByType(this IEnumerable<ConstructorInfo> constructors, params Type[] types)
|
|
|
|
{
|
|
|
|
foreach (var item in constructors)
|
|
|
|
{
|
|
|
|
var paramsInfo = item.GetParameters().Select(x => x.ParameterType.FullName);
|
|
|
|
var typesInfo = types.Select(x => x.FullName);
|
|
|
|
var isThis = paramsInfo.Except(typesInfo).Count()==0;
|
|
|
|
if (isThis)
|
|
|
|
{
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return constructors.First();
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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 string AttributeValue(this XElement element, string attribute, string sub = null)
|
|
|
|
{
|
|
|
|
return element.Attribute(attribute).Value ?? sub;
|
|
|
|
}
|
|
|
|
|
|
|
|
//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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|