Skip to content

Commit

Permalink
Merge pull request #21 from biggray/develop
Browse files Browse the repository at this point in the history
port to netstandard 2.0
  • Loading branch information
rigofunc authored Jul 10, 2018
2 parents 18ed6dd + 6b8e72f commit 2cb105f
Show file tree
Hide file tree
Showing 10 changed files with 332 additions and 260 deletions.
89 changes: 18 additions & 71 deletions samples/FluentExcel.Samples.csproj
Original file line number Diff line number Diff line change
@@ -1,78 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{08DCA8C6-8AB5-4341-AB82-001EC59B9ACC}</ProjectGuid>
<TargetFrameworks>net461</TargetFrameworks>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>FluentExcel.Samples</RootNamespace>
<AssemblyName>FluentExcel.Samples</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<StartupObject>samples.Program</StartupObject>
<Authors>RigoFunc (xuyingting)</Authors>
<Description>The examples of the FluentExcel</Description>
<Copyright>Copyright © RigoFunc (xuyingting). All rights reserved.</Copyright>
<PackageProjectUrl>https://github.com/Arch/FluentExcel</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/Arch/FluentExcel/blob/master/LICENSE</PackageLicenseUrl>
<RepositoryUrl>https://github.com/Arch/FluentExcel</RepositoryUrl>
<RepositoryType>GIT</RepositoryType>
<PackageTags>FluentExcel, NPOI, Fluent API, NPOI.Extension, xyting, Arch, dotnetcore</PackageTags>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="NPOI, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net40\NPOI.dll</HintPath>
</Reference>
<Reference Include="NPOI.OOXML, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net40\NPOI.OOXML.dll</HintPath>
</Reference>
<Reference Include="NPOI.OpenXml4Net, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net40\NPOI.OpenXml4Net.dll</HintPath>
</Reference>
<Reference Include="NPOI.OpenXmlFormats, Version=2.3.0.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
<HintPath>..\packages\NPOI.2.3.0\lib\net40\NPOI.OpenXmlFormats.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="FluentConfigurationExtensions.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Report.cs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\FluentExcel.csproj">
<Project>{5addd29d-b3af-4966-b730-5e5192d0e9df}</Project>
<Name>FluentExcel</Name>
</ProjectReference>
<ProjectReference Include="../src/FluentExcel.csproj" />
</ItemGroup>

<ItemGroup>
<None Include="packages.config" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

</Project>
35 changes: 0 additions & 35 deletions samples/Properties/AssemblyInfo.cs

This file was deleted.

163 changes: 150 additions & 13 deletions src/Excel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,127 @@ public static class Excel
/// <param name="sheetIndex">Which sheet to read.</param>
/// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
public static IEnumerable<T> Load<T>(string excelFile, int startRow = 1, int sheetIndex = 0) where T : class, new()
=> Load<T>(excelFile, Setting, startRow, sheetIndex);

/// <summary>
/// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
/// </summary>
/// <typeparam name="T">The type of the model.</typeparam>
/// <param name="excelFile">The excel file.</param>
/// <param name="excelSetting">The excel setting to use to load data.</param>
/// <param name="startRow">The row to start read.</param>
/// <param name="sheetIndex">Which sheet to read.</param>
/// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
public static IEnumerable<T> Load<T>(string excelFile, ExcelSetting excelSetting, int startRow = 1, int sheetIndex = 0) where T : class, new()
{
if (!File.Exists(excelFile))
{
throw new FileNotFoundException();
}
if (!File.Exists(excelFile)) throw new FileNotFoundException();

return Load<T>(File.OpenRead(excelFile), excelSetting, startRow, sheetIndex);
}

/// <summary>
/// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
/// </summary>
/// <typeparam name="T">The type of the model.</typeparam>
/// <param name="excelFile">The excel file.</param>
/// <param name="sheetName">Which sheet to read.</param>
/// <param name="startRow">The row to start read.</param>
/// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
public static IEnumerable<T> Load<T>(string excelFile, string sheetName, int startRow = 1) where T : class, new()
=> Load<T>(excelFile, Setting, sheetName, startRow);

/// <summary>
/// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
/// </summary>
/// <typeparam name="T">The type of the model.</typeparam>
/// <param name="excelFile">The excel file.</param>
/// <param name="excelSetting">The excel setting to use to load data.</param>
/// <param name="sheetName">Which sheet to read.</param>
/// <param name="startRow">The row to start read.</param>
/// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
public static IEnumerable<T> Load<T>(string excelFile, ExcelSetting excelSetting, string sheetName, int startRow = 1) where T : class, new()
{
if (!File.Exists(excelFile)) throw new FileNotFoundException();

var workbook = InitializeWorkbook(excelFile);
return Load<T>(File.OpenRead(excelFile), excelSetting, sheetName, startRow);
}

/// <summary>
/// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
/// </summary>
/// <typeparam name="T">The type of the model.</typeparam>
/// <param name="excelStream">The excel stream.</param>
/// <param name="startRow">The row to start read.</param>
/// <param name="sheetIndex">Which sheet to read.</param>
/// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
public static IEnumerable<T> Load<T>(Stream excelStream, int startRow = 1, int sheetIndex = 0) where T : class, new()
=> Load<T>(excelStream, Setting, startRow, sheetIndex);

// currently, only handle sheet one (or call side using foreach to support multiple sheet)
/// <summary>
/// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
/// </summary>
/// <typeparam name="T">The type of the model.</typeparam>
/// <param name="excelStream">The excel stream.</param>
/// <param name="excelSetting">The excel setting to use to load data.</param>
/// <param name="startRow">The row to start read.</param>
/// <param name="sheetIndex">Which sheet to read.</param>
/// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
public static IEnumerable<T> Load<T>(Stream excelStream, ExcelSetting excelSetting, int startRow = 1, int sheetIndex = 0) where T : class, new()
{
var workbook = InitializeWorkbook(excelStream);

// currently, only handle one sheet (or call side using foreach to support multiple sheet)
var sheet = workbook.GetSheetAt(sheetIndex);
if (null == sheet) throw new ArgumentException($"Excel sheet with specified index [{sheetIndex}] not found", nameof(sheetIndex));

return Load<T>(sheet, _formulaEvaluator, excelSetting, startRow);
}

/// <summary>
/// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
/// </summary>
/// <typeparam name="T">The type of the model.</typeparam>
/// <param name="excelStream">The excel stream.</param>
/// <param name="sheetName">Which sheet to read.</param>
/// <param name="startRow">The row to start read.</param>
/// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
public static IEnumerable<T> Load<T>(Stream excelStream, string sheetName, int startRow = 1) where T : class, new()
=> Load<T>(excelStream, Setting, sheetName, startRow);

/// <summary>
/// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
/// </summary>
/// <typeparam name="T">The type of the model.</typeparam>
/// <param name="excelStream">The excel stream.</param>
/// <param name="excelSetting">The excel setting to use to load data.</param>
/// <param name="sheetName">Which sheet to read.</param>
/// <param name="startRow">The row to start read.</param>
/// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
public static IEnumerable<T> Load<T>(Stream excelStream, ExcelSetting excelSetting, string sheetName, int startRow = 1) where T : class, new()
{
if (string.IsNullOrWhiteSpace(sheetName)) throw new ArgumentException($"sheet name cannot be null or whitespace", nameof(sheetName));

var workbook = InitializeWorkbook(excelStream);

// currently, only handle one sheet (or call side using foreach to support multiple sheet)
var sheet = workbook.GetSheet(sheetName);
if (null == sheet) throw new ArgumentException($"Excel sheet with specified name [{sheetName}] not found", nameof(sheetName));

return Load<T>(sheet, _formulaEvaluator, excelSetting, startRow);
}

public static IEnumerable<T> Load<T>(ISheet sheet, IFormulaEvaluator formulaEvaluator, int startRow = 1) where T : class, new()
=> Load<T>(sheet, formulaEvaluator, Excel.Setting, startRow);
public static IEnumerable<T> Load<T>(ISheet sheet, IFormulaEvaluator formulaEvaluator, ExcelSetting excelSetting, int startRow = 1) where T : class, new()
{
if (null == sheet) throw new ArgumentNullException(nameof(sheet));

// get the writable properties
var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);

bool fluentConfigEnabled = false;
// get the fluent config
if (Setting.FluentConfigs.TryGetValue(typeof(T), out var fluentConfig))
if (excelSetting.FluentConfigs.TryGetValue(typeof(T), out var fluentConfig))
{
fluentConfigEnabled = true;
}
Expand Down Expand Up @@ -136,12 +240,28 @@ public static class Excel
}
}

var value = row.GetCellValue(index, _formulaEvaluator);
var value = row.GetCellValue(index, formulaEvaluator);

// give a chance to the cell value validator
if (null != config?.CellValueValidator)
{
var validationResult = config.CellValueValidator(row.RowNum - 1, config.Index, value);
if (false == validationResult)
{
if (fluentConfig.SkipInvalidRows)
{
itemIsValid = false;
break;
}

throw new ArgumentException($"Validation of cell value at row {row.RowNum}, column {config.Title}({config.Index + 1}) failed! Value: [{value}]");
}
}

// give a chance to the value converter.
if (config?.ValueConverter != null)
if (config?.CellValueConverter != null)
{
value = config.ValueConverter(value);
value = config.CellValueConverter(row.RowNum - 1, config.Index, value);
}

if (value == null)
Expand Down Expand Up @@ -173,6 +293,22 @@ public static class Excel

if (itemIsValid)
{
// give a chance to the row data validator
if (null != fluentConfig?.RowDataValidator)
{
var validationResult = fluentConfig.RowDataValidator(row.RowNum - 1, item);
if (false == validationResult)
{
if (fluentConfig.SkipInvalidRows)
{
itemIsValid = false;
continue;
}

throw new ArgumentException($"Validation of row data at row {row.RowNum} failed!");
}
}

list.Add(item);
}
}
Expand Down Expand Up @@ -242,11 +378,12 @@ internal static object GetDefault(this Type type)
}

private static IWorkbook InitializeWorkbook(string excelFile)
=> InitializeWorkbook(File.OpenRead(excelFile));
private static IWorkbook InitializeWorkbook(Stream excelStream)
{
var extension = Path.GetExtension(excelFile);
var workbook = WorkbookFactory.Create(new FileStream(excelFile, FileMode.Open, FileAccess.Read));
var workbook = WorkbookFactory.Create(excelStream);
_formulaEvaluator = workbook.GetCreationHelper().CreateFormulaEvaluator();
return workbook;
}
}
}
}
2 changes: 1 addition & 1 deletion src/ExcelSetting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class ExcelSetting
/// <summary>
/// Gets or sets a value indicating whether to use *.xlsx file extension.
/// </summary>
public bool UserXlsx { get; set; } = true;
public bool UseXlsx { get; set; } = true;

/// <summary>
/// Gets or sets the title cell style applier.
Expand Down
Loading

0 comments on commit 2cb105f

Please sign in to comment.