web-dev-qa-db-ja.com

Epplusを使用して変更されたexcelの実際の使用範囲を取得するにはどうすればよいですか?

EPPlusを使用してExcelからデータブルにデータを読み取っています。

10行のレコードを含むExcelシートを読み取った後、既存のデータを削除してExcelシートを変更し、1行のデータのみを保持しました。しかし、変更されたExcelを読み取っているときは、データテーブルに10行(1つは値があり、残りはnullフィールド)です。

これをどのように制限できますか?私は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();
}   
_

Interop Excelを使用してExcelを読み取っていたとき、同じ問題は次のようなclearformat()メソッドによって克服されました。

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

Epplus open xmlにこれに相当するものはありますか?変更されたエクセルの実際の使用範囲を取得するにはどうすればよいですか?

14
Athul

一部のセルのデータのみを削除する場合に、行を考慮しないように指示する組み込みの方法はありません。

Dimensionは可能な限り近いですが、any列にデータが含まれている場合、またはany上の行の場合、行はDimensionに含まれます以下にデータが含まれています。

ただし、forループの行をスキップする必要があるかどうかを確認することはできます。たとえば、常に最初の4列のデータのみを削除する場合は、次のことを試してください。

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

説明は行をスキップするための基準を示していませんが、あなたは考えを理解します。

10
Philip Bijker

そもそも、私はC#プログラマーではありませんが、ExcelVBAスクリプトを使用して機能するソリューションがあると思います。このExcelVBAコードをCで実行したり、C +で同じことを実現する方法についての洞察を得ることができる場合があります。

あなたが抱えている問題は、Excelがワークシートの作業サイズを処理する方法に関連しています。 100万行目にデータを入力してからそのセルを削除すると、Excelではワークシートが100万行であると表示されます。

このExcelVBAコードをテストしたところ、完全に空のすべての行が正常に削除され、ワー​​クシートのサイズがリセットされました。

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

スクリプトを使用せずに手動でこれを行うには、最初にワークシートの下部にあるすべての空の行(または右側の列)を削除して保存し、次にワークブックを閉じて再度開きます。これにより、Excelブックのサイズもリセットされることがわかりました。

4
ChrisB