2016-04-15 13 views
3

Mit EPPlus möchte ich eine Excel-Tabelle lesen und dann den gesamten Inhalt aus jeder Spalte in die entsprechende List speichern. Ich möchte, dass es die Überschrift der Tabelle erkennt und den Inhalt darauf basierend kategorisiert.EPPlus - Excel-Tabelle lesen

Zum Beispiel, wenn meine Excel-Tabelle als unten:

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

Ich möchte die Daten in List<ExcelData> speichern, wo

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

Damit ich die Überschrift Name den Inhalt rufen kann mit . Zum Beispiel, wenn ich dies tun:

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

Es gibt mir diese Ausgabe:

1JohnMale 
2MariaFemale 
3DanielUnknown 

Das ist wirklich alles, was ich habe:

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 

Bitte helfen :( Ich habe lange Stunden damit verbracht, nach Beispielcode zu suchen, damit ich daraus lernen kann, aber vergeblich, ich verstehe auch ExcelTo LinQ ist dazu in der Lage, aber es kann keine Tabelle erkennen.

Antwort

4

Es gibt keine native aber was ist, wenn Sie, was ich in diesem Beitrag setzen:

How to parse excel rows back to types using EPPlus

Wenn Sie es an einem Tisch auf Punkt wollen nur müssen sie geändert werden. So etwas sollte es tun:

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; 
} 

Hier ist eine Testmethode:

[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(); 
    } 
} 

gab dies in der Konsole:

1JohnMale 
2MariaFemale 
3DanielUnknown 

Nur vorsichtig sein, wenn Sie Id Feld eine Nummer oder Zeichenfolge in Excel, da die Klasse eine Zeichenfolge erwartet.

1

Der folgende Code liest Excel-Daten in eine Datentabelle, die in eine Liste von Datenzeilen konvertiert wird.

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

den Fehler bekommen '‚ExcelPackage‘enthält keine Definition für‚ToDataTable‘und keine Erweiterungsmethode‚ToDataTable‘ein erstes Argument vom Typ‚ExcelPackage‘Annahme gefunden werden (möglicherweise fehlt eine using-Direktive oder ein Referenz der Baugruppe?) ' –