Skip to content
This repository has been archived by the owner on Jan 25, 2019. It is now read-only.

Commit

Permalink
Updated to change set #fcded570d92e
Browse files Browse the repository at this point in the history
  • Loading branch information
VahidN committed May 30, 2017
1 parent 561d7d7 commit 2d61232
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 156 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
EPPlus.Core
===========
`EPPlus.Core` is an **unofficial** port of the [EPPlus library](https://epplus.codeplex.com) to .NET Core.
It's based on the [4/8/2017, change set#9818e8625288](https://epplus.codeplex.com/SourceControl/list/changesets).
It's based on the [5/24/2017, change set#fcded570d92e](https://epplus.codeplex.com/SourceControl/list/changesets).


Install via NuGet
Expand Down
2 changes: 1 addition & 1 deletion src/EPPlus.Core/EPPlus.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<Description>EPPlus.Core is an unofficial port of the EPPlus library to .NET Core.</Description>
<VersionPrefix>1.3.2</VersionPrefix>
<VersionPrefix>1.4.0</VersionPrefix>
<Authors>Vahid Nasiri</Authors>
<TargetFrameworks>net40;net45;net46;netstandard1.3</TargetFrameworks>
<DefineConstants>$(DefineConstants);NO_SFX</DefineConstants>
Expand Down
43 changes: 31 additions & 12 deletions src/EPPlus.Core/ExcelRangeBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2299,18 +2299,37 @@ public ExcelRangeBase LoadFromText(FileInfo TextFile, ExcelTextFormat Format, Ta
{
return LoadFromText(File.ReadAllText(TextFile.FullName, Format.Encoding), Format, TableStyle, FirstRowIsHeader);
}
#endregion
#region GetValue
/// <summary>
/// Get the strongly typed value of the cell.
/// </summary>
/// <typeparam name="T">The type</typeparam>
/// <returns>The value. If the value can't be converted to the specified type, the default value will be returned</returns>
public T GetValue<T>()
{
return _worksheet.GetTypedValue<T>(Value);
}
#endregion
#endregion
#region GetValue

/// <summary>
/// Convert cell value to desired type, including nullable structs.
/// When converting blank string to nullable struct (e.g. ' ' to int?) null is returned.
/// When attempted conversion fails exception is passed through.
/// </summary>
/// <typeparam name="T">
/// The type to convert to.
/// </typeparam>
/// <returns>
/// The <see cref="Value"/> converted to <typeparamref name="T"/>.
/// </returns>
/// <remarks>
/// If <see cref="Value"/> is string, parsing is performed for output types of DateTime and TimeSpan, which if fails throws <see cref="FormatException"/>.
/// Another special case for output types of DateTime and TimeSpan is when input is double, in which case <see cref="DateTime.FromOADate"/>
/// is used for conversion. This special case does not work through other types convertible to double (e.g. integer or string with number).
/// In all other cases 'direct' conversion <see cref="Convert.ChangeType(object, Type)"/> is performed.
/// </remarks>
/// <exception cref="FormatException">
/// <see cref="Value"/> is string and its format is invalid for conversion (parsing fails)
/// </exception>
/// <exception cref="InvalidCastException">
/// <see cref="Value"/> is not string and direct conversion fails
/// </exception>
public T GetValue<T>()
{
return ConvertUtil.GetTypedCellValue<T>(Value);
}
#endregion
/// <summary>
/// Get a range with an offset from the top left cell.
/// The new range has the same dimensions as the current range
Expand Down
133 changes: 2 additions & 131 deletions src/EPPlus.Core/ExcelWorksheet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2811,139 +2811,10 @@ public T GetValue<T>(int Row, int Column)
{
return (T)(object)Cells[Row, Column].RichText.Text;
}
else
{
return GetTypedValue<T>(v);
}
}
//Thanks to Michael Tran for parts of this method
internal T GetTypedValue<T>(object v)
{
if (v == null)
{
return default(T);
}
Type fromType = v.GetType();
Type toType = typeof(T);
Type toType2 = (
#if COREFX
toType.GetTypeInfo().IsGenericType
#else
toType.IsGenericType
#endif
&& toType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
? Nullable.GetUnderlyingType(toType)
: null;
if (fromType == toType || fromType == toType2)
{
return (T)v;
}
var cnv = TypeDescriptor.GetConverter(fromType);
if (toType == typeof(DateTime) || toType2 == typeof(DateTime)) //Handle dates
{
if (fromType == typeof(TimeSpan))
{
return ((T)(object)(new DateTime(((TimeSpan)v).Ticks)));
}
else if (fromType == typeof(string))
{
DateTime dt;
if (DateTime.TryParse(v.ToString(), out dt))
{
return (T)(object)(dt);
}
else
{
return default(T);
}

}
else
{
if (cnv.CanConvertTo(typeof(double)))
{
return (T)(object)(DateTimeExtensions.FromOADate((double)cnv.ConvertTo(v, typeof(double))));
}
else
{
return default(T);
}
}
}
else if (toType == typeof(TimeSpan) || toType2 == typeof(TimeSpan)) //Handle timespan
{
if (fromType == typeof(DateTime))
{
return ((T)(object)(new TimeSpan(((DateTime)v).Ticks)));
}
else if (fromType == typeof(string))
{
TimeSpan ts;
if (TimeSpan.TryParse(v.ToString(), out ts))
{
return (T)(object)(ts);
}
else
{
return default(T);
}
}
else
{
if (cnv.CanConvertTo(typeof(double)))
{

return (T)(object)(new TimeSpan(DateTimeExtensions.FromOADate((double)cnv.ConvertTo(v, typeof(double))).Ticks));
}
else
{
try
{
// Issue 14682 -- "GetValue<decimal>() won't convert strings"
// As suggested, after all special cases, all .NET to do it's
// preferred conversion rather than simply returning the default
return (T)Convert.ChangeType(v, typeof(T));
}
catch (Exception)
{
// This was the previous behaviour -- no conversion is available.
return default(T);
}
}
}
}
else
{
if (cnv.CanConvertTo(toType))
{
return (T)cnv.ConvertTo(v, typeof(T));
}
else
{
if (toType2 != null)
{
toType = toType2;
if (cnv.CanConvertTo(toType))
{
return (T)cnv.ConvertTo(v, toType); //Fixes issue 15377
}
}

if (fromType == typeof(double) && toType == typeof(decimal))
{
return (T)(object)Convert.ToDecimal(v);
}
else if (fromType == typeof(decimal) && toType == typeof(double))
{
return (T)(object)Convert.ToDouble(v);
}
else
{
return default(T);
}
}
}
return ConvertUtil.GetTypedCellValue<T>(v);
}

/// <summary>
/// Set the value of a cell
/// </summary>
Expand Down
49 changes: 38 additions & 11 deletions src/EPPlus.Core/ExcelWorksheetView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ private bool IsActiveCellInSelection(ExcelAddressBase ac, ExcelAddressBase sd)
return false;
}
/// <summary>
/// Indicates if the worksheet is selected within the workbook
/// Indicates if the worksheet is selected within the workbook. NOTE: Setter clears other selected tabs.
/// </summary>
public bool TabSelected
{
Expand All @@ -280,23 +280,50 @@ public bool TabSelected
}
set
{
if (value)
SetTabSelected(value, false);
}
}

/// <summary>
/// Indicates if the worksheet is selected within the workbook. NOTE: Setter keeps other selected tabs.
/// </summary>
public bool TabSelectedMulti
{
get
{
return GetXmlNodeBool("@tabSelected");
}
set
{
SetTabSelected(value, true);
}
}

/// <summary>
/// Sets whether the worksheet is selected within the workbook.
/// </summary>
/// <param name="isSelected">Whether the tab is selected, defaults to true.</param>
/// <param name="allowMultiple">Whether to allow multiple active tabs, defaults to false.</param>
public void SetTabSelected(bool isSelected = true, bool allowMultiple = false)
{
if (isSelected)
{
SheetViewElement.SetAttribute("tabSelected", "1");
if (!allowMultiple)
{
// // ensure no other worksheet has its tabSelected attribute set to 1
foreach (ExcelWorksheet sheet in _worksheet._package.Workbook.Worksheets)
sheet.View.TabSelected = false;

SheetViewElement.SetAttribute("tabSelected", "1");
XmlElement bookView = _worksheet.Workbook.WorkbookXml.SelectSingleNode("//d:workbookView", _worksheet.NameSpaceManager) as XmlElement;
if (bookView != null)
{
bookView.SetAttribute("activeTab", (_worksheet.PositionID - 1).ToString());
}
}
else
SetXmlNodeString("@tabSelected", "0");

XmlElement bookView = _worksheet.Workbook.WorkbookXml.SelectSingleNode("//d:workbookView", _worksheet.NameSpaceManager) as XmlElement;
if (bookView != null)
{
bookView.SetAttribute("activeTab", (_worksheet.PositionID - 1).ToString());
}
}
else
SetXmlNodeString("@tabSelected", "0");
}

/// <summary>
Expand Down
3 changes: 3 additions & 0 deletions src/EPPlus.Core/ExcelWorksheets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@ private void CopyTable(ExcelWorksheet Copy, ExcelWorksheet added)
name = string.Format("Table{0}", ++ix);
}
}
                //ensure the _nextTableID value has been initialized - Pull request by WillR
                _pck.Workbook.ReadAllTables();

int Id = _pck.Workbook._nextTableID++;
prevName = name;
XmlDocument xmlDoc = new XmlDocument();
Expand Down
76 changes: 76 additions & 0 deletions src/EPPlus.Core/Utils/ConvertUtil.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -241,6 +242,81 @@ internal static string ExcelDecodeString(string t)
return ret.ToString();
}

/// <summary>
/// Convert cell value to desired type, including nullable structs.
/// When converting blank string to nullable struct (e.g. ' ' to int?) null is returned.
/// When attempted conversion fails exception is passed through.
/// </summary>
/// <typeparam name="T">
/// The type to convert to.
/// </typeparam>
/// <returns>
/// The <paramref name="value"/> converted to <typeparamref name="T"/>.
/// </returns>
/// <remarks>
/// If input is string, parsing is performed for output types of DateTime and TimeSpan, which if fails throws <see cref="FormatException"/>.
/// Another special case for output types of DateTime and TimeSpan is when input is double, in which case <see cref="DateTime.FromOADate"/>
/// is used for conversion. This special case does not work through other types convertible to double (e.g. integer or string with number).
/// In all other cases 'direct' conversion <see cref="Convert.ChangeType(object, Type)"/> is performed.
/// </remarks>
/// <exception cref="FormatException">
/// <paramref name="value"/> is string and its format is invalid for conversion (parsing fails)
/// </exception>
/// <exception cref="InvalidCastException">
/// <paramref name="value"/> is not string and direct conversion fails
/// </exception>
public static T GetTypedCellValue<T>(object value)
{
if (value == null)
return default(T);

var fromType = value.GetType();
var toType = typeof(T);
var toNullableUnderlyingType = (
#if COREFX
toType.GetTypeInfo().IsGenericType
#else
toType.IsGenericType
#endif
&& toType.GetGenericTypeDefinition() == typeof(Nullable<>))
? Nullable.GetUnderlyingType(toType)
: null;

if (fromType == toType || fromType == toNullableUnderlyingType)
return (T)value;

// if converting to nullable struct and input is blank string, return null
if (toNullableUnderlyingType != null && fromType == typeof(string) && ((string)value).Trim() == string.Empty)
return default(T);

toType = toNullableUnderlyingType ?? toType;

if (toType == typeof(DateTime))
{
if (value is double)
return (T)(object)(DateTimeExtensions.FromOADate((double)value));

if (fromType == typeof(TimeSpan))
return ((T)(object)(new DateTime(((TimeSpan)value).Ticks)));

if (fromType == typeof(string))
return (T)(object)DateTime.Parse(value.ToString());
}
else if (toType == typeof(TimeSpan))
{
if (value is double)
return (T)(object)(new TimeSpan(DateTimeExtensions.FromOADate((double)value).Ticks));

if (fromType == typeof(DateTime))
return ((T)(object)(new TimeSpan(((DateTime)value).Ticks)));

if (fromType == typeof(string))
return (T)(object)TimeSpan.Parse(value.ToString());
}

return (T)Convert.ChangeType(value, toType);
}

#region internal cache objects
internal static TextInfo _invariantTextInfo = CultureInfo.InvariantCulture.TextInfo;
internal static CompareInfo _invariantCompareInfo =
Expand Down

0 comments on commit 2d61232

Please sign in to comment.