2016-04-15 29 views
3

EPPlusを使用して、Excelテーブルを読み込み、各カラムのすべての内容を対応するListに保存します。テーブルの見出しを認識し、それに基づいてコンテンツを分類する必要があります。例えばEPPlus - Excelテーブルを読む

、私のExcelの表は以下の通りである場合:

Id Name  Gender 
1 John  Male 
2 Maria Female 
3 Daniel Unknown 

私は、見出し名を使用して内容を呼び出すことができるように、データが

public class ExcelData 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public string Gender { get; set; } 
} 

List<ExcelData>に格納します。例えば、私が行うとき、これは::(

var package = new ExcelPackage(new FileInfo(@"C:\ExcelFile.xlsx")); 
ExcelWorksheet sheet = package.Workbook.Worksheets[1]; 

var table = sheet.Tables.First(); 

table.Columns.Something //I guess I can use this to do what I want 

助けてください:これは本当に私が得たすべてである

1JohnMale 
2MariaFemale 
3DanielUnknown 

foreach (var data in ThatList) 
{ 
    Console.WriteLine(data.Id + data.Name + data.Gender); 
} 

は、それは私にこの出力が得られます 私はこれに関連してサンプルコードを検索するのに長時間を費やしてきましたが、私はそれから学ぶことができますが、役に立たないと思います。 LinQはそのように管理されていますが、テーブルを認識できません。

答えて

4

そこにはネイティブではありませんが、あなたは、私はこの記事に入れて何何を使用している場合:

How to parse excel rows back to types using EPPlus

あなたがテーブルでそれを指すようにしたい場合のみ、それを変更する必要があります。このような何かがそれを行う必要があります。ここでは

public static IEnumerable<T> ConvertTableToObjects<T>(this ExcelTable table) where T : new() 
{ 
    //DateTime Conversion 
    var convertDateTime = new Func<double, DateTime>(excelDate => 
    { 
     if (excelDate < 1) 
      throw new ArgumentException("Excel dates cannot be smaller than 0."); 

     var dateOfReference = new DateTime(1900, 1, 1); 

     if (excelDate > 60d) 
      excelDate = excelDate - 2; 
     else 
      excelDate = excelDate - 1; 
     return dateOfReference.AddDays(excelDate); 
    }); 

    //Get the properties of T 
    var tprops = (new T()) 
     .GetType() 
     .GetProperties() 
     .ToList(); 

    //Get the cells based on the table address 
    var groups = table.WorkSheet.Cells[table.Address.Start.Row, table.Address.Start.Column, table.Address.End.Row, table.Address.End.Column] 
     .GroupBy(cell => cell.Start.Row) 
     .ToList(); 

    //Assume the second row represents column data types (big assumption!) 
    var types = groups 
     .Skip(1) 
     .First() 
     .Select(rcell => rcell.Value.GetType()) 
     .ToList(); 

    //Assume first row has the column names 
    var colnames = groups 
     .First() 
     .Select((hcell, idx) => new { Name = hcell.Value.ToString(), index = idx }) 
     .Where(o => tprops.Select(p => p.Name).Contains(o.Name)) 
     .ToList(); 

    //Everything after the header is data 
    var rowvalues = groups 
     .Skip(1) //Exclude header 
     .Select(cg => cg.Select(c => c.Value).ToList()); 


    //Create the collection container 
    var collection = rowvalues 
     .Select(row => 
     { 
      var tnew = new T(); 
      colnames.ForEach(colname => 
      { 
       //This is the real wrinkle to using reflection - Excel stores all numbers as double including int 
       var val = row[colname.index]; 
       var type = types[colname.index]; 
       var prop = tprops.First(p => p.Name == colname.Name); 

       //If it is numeric it is a double since that is how excel stores all numbers 
       if (type == typeof(double)) 
       { 
        //Unbox it 
        var unboxedVal = (double)val; 

        //FAR FROM A COMPLETE LIST!!! 
        if (prop.PropertyType == typeof(Int32)) 
         prop.SetValue(tnew, (int)unboxedVal); 
        else if (prop.PropertyType == typeof(double)) 
         prop.SetValue(tnew, unboxedVal); 
        else if (prop.PropertyType == typeof(DateTime)) 
         prop.SetValue(tnew, convertDateTime(unboxedVal)); 
        else 
         throw new NotImplementedException(String.Format("Type '{0}' not implemented yet!", prop.PropertyType.Name)); 
       } 
       else 
       { 
        //Its a string 
        prop.SetValue(tnew, val); 
       } 
      }); 

      return tnew; 
     }); 


    //Send it back 
    return collection; 
} 

は、試験方法である:

[TestMethod] 
public void Table_To_Object_Test() 
{ 
    //Create a test file 
    var fi = new FileInfo(@"c:\temp\Table_To_Object.xlsx"); 

    using (var package = new ExcelPackage(fi)) 
    { 
     var workbook = package.Workbook; 
     var worksheet = workbook.Worksheets.First(); 
     var ThatList = worksheet.Tables.First().ConvertTableToObjects<ExcelData>(); 
     foreach (var data in ThatList) 
     { 
      Console.WriteLine(data.Id + data.Name + data.Gender); 
     } 

     package.Save(); 
    } 
} 

は、コンソールでこれを与えた:

1JohnMale 
2MariaFemale 
3DanielUnknown 

をおIdフィールドが数値である場合にだけ気をつけてクラスが文字列を予期しているので、excelの文字列が必要です。

1

以下のコードは、データをExcelのリストに変換されたデータテーブルに読み込みます。

if (FileUpload1.HasFile) 
{ 
    if (Path.GetExtension(FileUpload1.FileName) == ".xlsx") 
    { 
     Stream fs = FileUpload1.FileContent; 
     ExcelPackage package = new ExcelPackage(fs); 
     DataTable dt = new DataTable(); 
     dt= package.ToDataTable(); 
     List<DataRow> listOfRows = new List<DataRow>(); 
     listOfRows = dt.AsEnumerable().ToList(); 

    } 
} 
+1

'「ExcelPackageは」「ToDataTable」となし拡張メソッドの定義が含まれていないエラーを取得して「ToDataTable」「ExcelPackage」は見つけることができるタイプの最初の引数を受け取る(あなたがusingディレクティブが欠落したりしていますアセンブリ参照?) ' –