2016-04-15 141 views
3

使用EPPlus,我想读取Excel表格,然后将每列中的所有内容存储到其对应的List中。我希望它能够识别表格的标题并根据这些内容对内容进行分类。EPPlus - 读取Excel表格

例如,如果我的Excel表格是如下:

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

我希望数据在List<ExcelData>存储在那里

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

所以,我可以使用的标题名称叫出内容。例如,当我这样做:

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

它会给我这样的输出:

1JohnMale 
2MariaFemale 
3DanielUnknown 

这确实是我的一切:

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 

请帮助:( 我花了很长时间搜索有关此示例代码,以便我可以从中学习,但无济于事。我也了解ExcelTo 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指令或程序组装参考?)' –