How to read excel using EPPlus
Asked Answered
W

3

7

using .net 4.5

I'm trying to read .xls/.xlsx file using EPPlus (v4.0.4), but get an error. SO has questions on the same error but none relate or solve my problem.

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

The error occurs at pck.Load(stream);

A disk error occurred during a write operation. (Exception from HRESULT: 0x8003001D (STG_E_WRITEFAULT)

Waistband answered 27/10, 2015 at 13:0 Comment(7)
I think there is much more easier way to read xlsx file using EPPLus. Have a lookBeckon
@Rob. At var existingFile = new FileInfo(path); , i get the error "Can not open the package. Package is an OLE compound document. If this is an encrypted package, please supply the password"Waistband
you tried to read xlsx file, am I right?Beckon
Yes you are right. Also tried with .xls. Same errorWaistband
How test.xlsx file looks like?Beckon
It has a header with 3 columns - name, age, salary & then 2 rows (abc, 30, 3000 ; def, 40, 4000)Waistband
Your code looks fine. Make sure it is a true xlsx and not a renamed 'xls' or 'csv'. Post your file somewhere if you cant figure it out.Randle
O
16

A simple example how you can use EPPlus to read excel file:

Reff : 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());
            }
        }
    }
}
Olin answered 22/8, 2018 at 9:29 Comment(2)
Unable to read xls file with above code, it gives exception of index out of range while accessing worksheets[1]Buchholz
@AtifAziz /ALL - I changed the package.Workbook.worksheet[1]; to package.Workbook.worksheet[0]; and it worked for me. (I can't edit it as the edit cue is full.)Cod
A
3

We can first convert the xls file to xlsx format using Microsoft.Office.Introp.excel, AFTER the conversion use new formatted file to read with 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;
        }
Appledorf answered 26/11, 2019 at 9:25 Comment(0)
N
1

With this code you won't get an error because a cell is null. it will also cast the data type according to the properties in your class!

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

How to call this function? please view below code.

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

Hope to help someone!

Northern answered 7/9, 2021 at 14:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.