Search code examples
c#excelmodel-view-controllerepplus

MVC 5 How to upload Excel file and read rows till the last populated data row using EPPlus (OfficeOpenXml) ExcelPackage


I have a MVC file upload solution which uploads a Excel file, I am having an issue with the Excel Package where it reads my Excel docs row right to the end of the file using Dimension.End.Row property, I want to read till the last populated row and not the entire spreadsheet rows as it bombs out my code with a null reference error, the Excel is from an external source and it is a locked file which has about 7000 rows, but only about 3000 rows are populated with data, the Dimension.End.Row property reads the entire 7000 rows therefore when I loop though and map the rows and columns, after the last populated data row 3001 on wards it has null values. How can I enable this to read only the populated rows in the excel file, like I said I cannot modify this file as its locked and read-only, I can only read it and upload it. please see my code below.

[HttpPost]
    public ActionResult Upload(FormCollection formCollection)
    {
        if (Request != null)
        {
            HttpPostedFileBase file = Request.Files["UploadedFile"];
            if ((file != null && file.ContentLength > 0 && !string.IsNullOrEmpty(file.FileName)))
            {
                string fileName = file.FileName;
                string fileContentType = file.ContentType;
                byte[] filebytes = new byte[file.ContentLength];
                var data = file.InputStream.Read(filebytes, 0, Convert.ToInt32(file.ContentLength));

                var suppleirList = new List<CleanSupplierClaim>();

                using (var package = new ExcelPackage(file.InputStream))
                {
                    var currentSheet = package.Workbook.Worksheets;
                    var workSheet = currentSheet.First();
                    var noOfColumns = workSheet.Dimension.End.Column;
                    var noOfRows = workSheet.Dimension.End.Row;// Here is where my issue is

                    for (int rowIterator = 5; rowIterator < noOfRows; rowIterator++)
                    {
                        var claim = new CleanSupplierClaim();

                        claim.Action = workSheet.Cells[rowIterator, 1].ToString();
                        claim.Line_Number = workSheet.Cells[rowIterator, 2].Value.ToString();
                        claim.Total_Claim = workSheet.Cells[rowIterator, 3].Value.ToString();
                        claim.ClaimReference = workSheet.Cells[rowIterator, 4].Value.ToString();
                        claim.Supplier_Claim = workSheet.Cells[rowIterator, 5].Value.ToString();
                        claim.Currency = workSheet.Cells[rowIterator, 6].Value.ToString();

                        suppleirList.Add(claim);
                    }



                }
            }
        }
        return View("Index");

Solution

  • You can do something like this;

    for (int rowIterator = 5; rowIterator < noOfRows; rowIterator++)
    {
          if(workSheet.Cells[rowIterator, 1] == null)//can this be null?
          {
            break; //if it's null exit from the for loop
          }
    
          var claim = new CleanSupplierClaim();
    
          claim.Action = workSheet.Cells[rowIterator, 1].ToString();
          claim.Line_Number = workSheet.Cells[rowIterator, 2].Value.ToString();
          claim.Total_Claim = workSheet.Cells[rowIterator, 3].Value.ToString();
          claim.ClaimReference = workSheet.Cells[rowIterator, 4].Value.ToString();
          claim.Supplier_Claim = workSheet.Cells[rowIterator, 5].Value.ToString();
          claim.Currency = workSheet.Cells[rowIterator, 6].Value.ToString();
    
          suppleirList.Add(claim);
      }