【问题标题】:How to read excel using EPPlus如何使用 EPPlus 读取 Excel
【发布时间】:2021-09-07 22:39:37
【问题描述】:

使用 .net 4.5

我正在尝试使用 EPPlus (v4.0.4) 读取 .xls/.xlsx 文件,但出现错误。 SO 对同一错误有疑问,但没有一个涉及或解决我的问题。

protected void Page_Load(object sender, EventArgs e)
    {
        GetDataTableFromExcel(@"D:\test.xlsx");
    }

private DataTable GetDataTableFromExcel(string path, bool hasHeader = true)
{
  using (var pck = new OfficeOpenXml.ExcelPackage())
   {
     using (var stream = File.OpenRead(path))
      {
        pck.Load(stream);
      }
     var ws = pck.Workbook.Worksheets[1];
     DataTable tbl = new DataTable();
     foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
     {
       tbl.Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
     }
     var startRow = hasHeader ? 2 : 1;
     for (int rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
     {
       var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
       DataRow row = tbl.Rows.Add();
       foreach (var cell in wsRow)
        {
          row[cell.Start.Column - 1] = cell.Text;
        }
     }
   return tbl;
  }
}

错误发生在pck.Load(stream);

写入操作期间发生磁盘错误。 (例外来自 HRESULT: 0x8003001D (STG_E_WRITEFAULT)

【问题讨论】:

  • 我认为使用 EPPLus 读取 xlsx 文件有更简单的方法。 Have a look
  • @Rob。在var existingFile = new FileInfo(path);,我收到错误“无法打开包。包是 OLE 复合文档。如果这是加密包,请提供密码”
  • 你试图读取 xlsx 文件,对吗?
  • 是的,你是对的。还尝试使用 .xls。同样的错误
  • 您的代码看起来不错。确保它是真正的xlsx,而不是重命名的“xls”或“csv”。如果您无法弄清楚,请将您的文件发布到某个地方。

标签: c# epplus


【解决方案1】:

一个如何使用EPPlus读取excel文件的简单例子:

参考:http://sforsuresh.in/reading-excel-file-using-epplus-package/

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

【讨论】:

  • 无法使用上述代码读取 xls 文件,在访问工作表时出现索引超出范围的异常[1]
  • @AtifAziz /ALL - 我更改了 package.Workbook.worksheet[1];到 package.Workbook.worksheet[0];它对我有用。 (我无法编辑它,因为编辑提示已满。)
【解决方案2】:

我们可以先使用 Microsoft.Office.Introp.excel 将 xls 文件转换为 xlsx 格式,转换后使用新格式的文件使用 EPPPLUS 读取。

 public static DataTable ReadExcelFileToDataTable(string filePath, bool isFirstRowHeader = true)
        {
            #region  Convert xls file to xlsx file
           // Convert xls file to xlsx file --to use below code Microsoft.Excel must installed on the system on which cod eis running

                var app = new Microsoft.Office.Interop.Excel.Application();
                var web = app.Workbooks.Open("");
                web.SaveAs(filePath + ".x", FileFormat: Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook);
                web.Close();
                app.Quit();

            #endregion
            var newFileName = filePath + ".x";
            DataTable tbl = new DataTable(); ;

            Excel.ExcelPackage xlsPackage = new Excel.ExcelPackage(new FileInfo(newFileName));  //using Excel = OfficeOpenXml;    <--EPPLUS
            Excel.ExcelWorkbook workBook = xlsPackage.Workbook;

            try
            {
                Excel.ExcelWorksheet wsworkSheet = workBook.Worksheets[0];

                    foreach (var firstRowCell in wsworkSheet.Cells[1, 1, 1, wsworkSheet.Dimension.End.Column]) 
                    {
                        var colName = "";
                        colName = firstRowCell.Text;
                        tbl.Columns.Add(isFirstRowHeader ? colName : string.Format("Column {0}", firstRowCell.Start.Column)); 
                    }
                    var startRow = isFirstRowHeader ? 2 : 1;
                    for (int rowNum = startRow; rowNum <= wsworkSheet.Dimension.End.Row; rowNum++)
                    {
                        var wsRow = wsworkSheet.Cells[rowNum, 1, rowNum, wsworkSheet.Dimension.End.Column];
                        DataRow row = tbl.Rows.Add();
                        foreach (var cell in wsRow)
                        {
                            row[cell.Start.Column - 1] = cell.Text;
                        }
                    }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return tbl;
        }

【讨论】:

    【解决方案3】:

    使用此代码,您不会收到错误,因为单元格为空。它还会根据你的类中的属性转换数据类型!

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.OleDb;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using OfficeOpenXml;
    
    public static class ReadExcel
        {
            public static List<T> ReadExcelToList<T>(this ExcelWorksheet worksheet) where T : new()
            {
                List<T> collection = new List<T>();
                try
                {
                    DataTable dt = new DataTable();
                    foreach (var firstRowCell in new T().GetType().GetProperties().ToList())
                    {
                        //Add table colums with properties of T
                        dt.Columns.Add(firstRowCell.Name);
                    }
                    for (int rowNum = 2; rowNum <= worksheet.Dimension.End.Row; rowNum++)
                    {
                        var wsRow = worksheet.Cells[rowNum, 1, rowNum, worksheet.Dimension.End.Column];
                        DataRow row = dt.Rows.Add();
                        foreach (var cell in wsRow)
                        {
                            row[cell.Start.Column - 1] = cell.Text;
                        }
                    }
                    
                    //Get the colums of table
                    var columnNames = dt.Columns.Cast<DataColumn>().Select(c => c.ColumnName).ToList();
                    
                    //Get the properties of T
                    List<PropertyInfo> properties = new T().GetType().GetProperties().ToList();
    
                    collection = dt.AsEnumerable().Select(row =>
                    {
                        T item = Activator.CreateInstance<T>();
                        foreach (var pro in properties)
                        {
                            if (columnNames.Contains(pro.Name) || columnNames.Contains(pro.Name.ToUpper()))
                            {
                                PropertyInfo pI = item.GetType().GetProperty(pro.Name);
                                pro.SetValue(item, (row[pro.Name] == DBNull.Value) ? null : Convert.ChangeType(row[pro.Name], (Nullable.GetUnderlyingType(pI.PropertyType) == null) ? pI.PropertyType : Type.GetType(pI.PropertyType.GenericTypeArguments[0].FullName)));
                            }
                        }
                        return item;
                    }).ToList();
    
                }
                catch (Exception ex)
                {
                    //Save error log
                }
    
                return collection;
            }
        }
    

    如何调用这个函数?请查看以下代码。

    public List<Users> GetStudentsFromExcel(HttpPostedFileBase file)
    {
        List<Users> list = new List<Users>();
        if (file != null)
        {
            try
            {
                using (ExcelPackage package = new ExcelPackage(file.InputStream))
                {
                    ExcelWorkbook workbook = package.Workbook;
                    if (workbook != null)
                    {
                        ExcelWorksheet worksheet = workbook.Worksheets.FirstOrDefault();
                        if (worksheet != null)
                        {
                            list = worksheet.ReadExcelToList<Users>();
                            //Your code
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //Save error log
            }
        }
        return list;
    }
    
    public class Users
    {
        public string Code { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public string Address { get; set; }
        public DateTime CreatedAt { get; set; }
    }
    

    希望能帮助到别人!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多