Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i get actual used range for modified excels using Epplus?

I am reading data from excel to datable using EPPlus.

After reading an excel sheet with 10 rows of record, I modified the excel sheet by removing existing data and kept data for only one row. But when I am reading the modified excel it still reading 10 rows (1 with value and remaining as null fields) to data table.

How can limit this? I am using following code for reading Excel.

using (var pck = new OfficeOpenXml.ExcelPackage())
{
    using (var stream = File.OpenRead(FilePath))
    {
        pck.Load(stream);
    }
    var ws = pck.Workbook.Worksheets.First();                   
    bool hasHeader = true; // adjust it accordingly(this is a simple approach)
    foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
    {
        DSClientTransmittal.Tables[0].Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
    }
    var startRow = hasHeader ? 2 : 1;
    for (var rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
    {
        //var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
        var wsRow = ws.Cells[rowNum, 1, rowNum, DSClientTransmittal.Tables[0].Columns.Count];
        var row = DSClientTransmittal.Tables[0].NewRow();
        foreach (var cell in wsRow)
        {
            try
            {
                object cellValue = cell.Value;
                //row[cell.Start.Column - 1] = cell.Text;
                row[cell.Start.Column - 1] = cellValue.ToString().Trim();
                //cell.Style.Numberformat.Format = "@";
                //row[cell.Start.Column - 1] = cell.Text;
            }
            catch (Exception ex) { }
        }
        DSClientTransmittal.Tables[0].Rows.Add(row);
    }
    pck.Dispose();
}   

When I was using Interop excel to read excel, same issue was overcame by clearformat() method like

ws.Columns.ClearFormats();
xlColCount = ws.UsedRange.Columns.Count;

Is there any equivalent for this in Epplus open xml? How can I get actual used range for modified excels?

like image 515
AcAnanth Avatar asked Dec 04 '15 13:12

AcAnanth


People also ask

Does EPPlus require Excel?

No, it does not require Excel to be installed on the server, as you can read in the docs: EPPlus is a . NET library that reads and writes Excel files using the Office Open XML format (xlsx).

What is EPP Plus?

EPPlus is a . NET library that reads and writes Excel 2007/2010/2013 files using the Open Office Xml format (xlsx). EPPlus supports: Cell Ranges.


2 Answers

There is no built-in way of indicating that a row shouldn't be accounted for when only deleting data in some cells.

Dimension is as close as you can get, but rows are included in the Dimension if any column contains data or if any row above or below contains data.

You could however try to find out if you should skip a row in the for loop. For example if you always delete data in the first 4 columns only, then you could try:

if(!ws.Cells[rowNum, 1, rowNum, 4].All(c => c.Value == null))
{
    //Continue adding the row to the table
}

The description isn't indicating the criteria for skipping a row, but you get the idea.

like image 186
Philip Bijker Avatar answered Oct 09 '22 09:10

Philip Bijker


To start with, I am not a C# programmer, but I think I have a solution that works using an Excel VBA script. You may be able to run this Excel VBA code with C, or get insight in how to accomplish the same thing with C+.

The problem you are having is related to the way Excel handles the working size of a worksheet. If you enter data in the 1 millionth row and then delete that cell, Excel still shows the worksheet as having 1 million rows.

I tested out this Excel VBA code and it successfully deleted all rows that were completely empty, and then reset the worksheet size.

Sub DelEmptyRowsResizeWorksheet()
  Dim i As Long, iLimit As Long
    iLimit = ActiveSheet.UsedRange.Rows.Count
  For i = iLimit To 1 Step -1
    If Application.CountA(Cells(i, 1).EntireRow) = 0 Then
       Cells(i, 1).EntireRow.Delete
    End If
  Next i
   iLimit = ActiveSheet.UsedRange.Rows.Count   ' resize the worksheet based on the last row with data
End Sub

To do this manually without a script, first delete all empty rows at the bottom (or columns on the right side) of a worksheet, save it, then close and reopen the workbook. I found that this also resets the Excel workbook size.

like image 3
ChrisB Avatar answered Oct 09 '22 08:10

ChrisB