EPPlus - 阅读Excel表格

Lir*_*Yeo 23 c# excel c#-4.0 epplus epplus-4

使用EPPlus,我想读取一个excel表,然后将每列的所有内容存储到相应的列中List.我希望它能识别表的标题并根据它对内容进行分类.

例如,如果我的excel表如下:

Id    Name     Gender
 1    John     Male
 2    Maria    Female
 3    Daniel   Unknown
Run Code Online (Sandbox Code Playgroud)

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

public class ExcelData
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Gender { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这样我就可以使用标题名称调出内容.例如,当我这样做时:

foreach (var data in ThatList)
{
     Console.WriteLine(data.Id + data.Name + data.Gender);
}
Run Code Online (Sandbox Code Playgroud)

它会给我这个输出:

1JohnMale
2MariaFemale
3DanielUnknown
Run Code Online (Sandbox Code Playgroud)

这真的是我得到的:

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
Run Code Online (Sandbox Code Playgroud)

请帮助:(我花了很长时间搜索关于此的示例代码,以便我可以从中学习但无济于事.我也理解ExcelToLinQ设法做到这一点,但它无法识别表.

Sur*_*shi 23

不知道为什么,但是以上解决方案都不适合我。因此,分享有效的方法:

public void readXLS(string FilePath)
{
    FileInfo existingFile = new FileInfo(FilePath);
    using (ExcelPackage package = new ExcelPackage(existingFile))
    {
        //get the first worksheet in the workbook
        ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
        int colCount = worksheet.Dimension.End.Column;  //get Column Count
        int rowCount = worksheet.Dimension.End.Row;     //get row count
        for (int row = 1; row <= rowCount; row++)
        {
            for (int col = 1; col <= colCount; col++)
            {
                Console.WriteLine(" Row:" + row + " column:" + col + " Value:" + worksheet.Cells[row, col].Value?.ToString().Trim());
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ern*_*e S 21

没有本地人,但如果你使用我在这篇文章中添加的内容会怎么样:

如何使用EPPlus将excel行解析回类型

如果您只想将其指向一个表,则需要对其进行修改.这样的事情应该这样做:

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 start = table.Address.Start;
    var end = table.Address.End;
    var cells = new List<ExcelRangeBase>();

    //Have to use for loops insteadof worksheet.Cells to protect against empties
    for (var r = start.Row; r <= end.Row; r++)
        for (var c = start.Column; c <= end.Column; c++)
            cells.Add(table.WorkSheet.Cells[r, c]);

    var groups = cells
        .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))
                {
                    if (!string.IsNullOrWhiteSpace(val?.ToString()))
                    {
                        //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;
}
Run Code Online (Sandbox Code Playgroud)

这是一种测试方法:

[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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在控制台中给出了这个:

1JohnMale
2MariaFemale
3DanielUnknown
Run Code Online (Sandbox Code Playgroud)

如果你的Id字段是excel中的数字或字符串,请小心,因为类期望字符串.