1

フォームに SpreadSheetGear WorkbookView があります。SpreadSheetGear WorkbookView は、10 行 10 列の Excel ファイルで埋められています。以下のコードを使用してセルからデータを取得したい:

 for (int i = 0; i < cells.Range.RowCount; i++)
 {
   for (int j = 0; j < cells.Range.ColumnCount; j++)
   {
     arrLstWorkBookView.Add(cells[i, j].Text);
     arrLstOutputData.Add(cells[i, j].Text);
   }
 }

デバッガーは、 のrowCount = 1048576代わりに10、のrowCount = 16384代わりに私を表示します10

WorkbookView の問題を解決し、Excel ファイルから適切な数の行と列を取得するには、行を 10、列を 10 にする必要があります。

4

4 に答える 4

5

cells変数がどこから来ているかを示すコード行を提供していませんが、1,048,576 の行数を取得している場合、これはcellsIWorksheet から来たことを示しています。Cells / Range、どちらもワークシート内のすべてのセルを表します (A1:XFD1048576)。

ワークシート内のより小さな範囲で反復しようとしている場合は、この範囲をIWorksheet.Cells["A1_Ref"]またはで指定する必要がありますIWorksheet.Cells[row1,col1,row2,col2]。例:

// The following two lines are equivalent
IRange cells = worksheet.Cells["A1:J10"];
IRange cells = worksheet.Cells[0, 0, 9, 9];
// ...the rest of your code...

ワークシートの「使用範囲」を反復処理する場合は、IWorksheet を使用します。代わりに使用範囲。例:

IRange cells = worksheet.UsedRange;

また、cells.Range.RowCount の Range への呼び出しは、IRange として冗長です。Rangeは単に指定された IRange を表します。あなたはただ使うことができますcells.RowCount

IRange インデクサー (IRange.Item(…)) のドキュメントを参照することも検討してください。これは、セルを参照するさまざまな方法を示しています: http://www.spreadsheetgear.com/support/help/spreadsheetgear.net. 7.0/#SpreadsheetGear2012.Core~SpreadsheetGear.IRange~Item.html

免責事項: 私は SpreadsheetGear で働いています。

于 2013-07-19T14:22:37.957 に答える
2

使用する必要があります

SpreadsheetGear.IRange cells = worksheet.UsedRange;
于 2020-05-15T15:27:21.033 に答える
0

データのグリッドを取得するもう 1 つの方法は、次のように datatable を使用することです。

スプレッドシート名の範囲

MyTable =Sheet1!$A$1:$J$11

これは MVC4 / Razor ですが、ASP.NET に変換する必要があります

<!-- language: c# -->
// Declare a DataTable variable
public DataTable myTable;

// Open the workbook.
String filename = HttpContext.Server.MapPath("myspreadsheet.xlsx");
SpreadsheetGear.IWorkbook workbook = SpreadsheetGear.Factory.GetWorkbook(filename);


//Get the table as a dataset:
DataSet dataSet = workbook.GetDataSet("MyTable", SpreadsheetGear.Data.GetDataFlags.FormattedText);
myTable = dataSet.Tables[0];

//Which can also be written as:
myTable = workbook.GetDataSet("MyTable", SpreadsheetGear.Data.GetDataFlags.FormattedText).Tables[0];

私のビューでは、DataTable の名前で部分ビューを呼び出します。

@Html.Partial("_DataTable", Model.myTable)

DataTable 部分ビューは次のようになります。

@using System.Data;
@model DataTable
<table>
@{DataRow rowHead = Model.Rows[0];
    <thead>
        <tr>
            @foreach (DataColumn colHead in Model.Columns)       
            {
                <th>@rowHead[colHead.ColumnName]</th> 
             }
        </tr> 
    </thead>
}
    <tbody>
        @{int rowCount = 1;}
        @foreach (DataRow row in Model.Rows)
            {
                <tr>
                    @foreach (DataColumn col in Model.Columns)
                    {
                        <td>@row[col.ColumnName]</td> 
                     }
                </tr>
               rowCount = rowCount + 1;
            } 
    </tbody>
</table>

このコードの奇妙な点は、範囲の最初の行がテーブルで使用できないことです。他の誰かがこれを説明する必要がありますが、範囲が最初に DataSet に供給され、最初の行が列名のために保持されているためだと思います。おそらく、私のコードよりもスマートなコードで、部分ビューでこれを抽出できます。

この例では、スプレッドシートの範囲から DataTable をレンダリングする方法も示しています。

SpreadsheetGear DataTable の例

于 2013-07-21T04:29:51.043 に答える
0

範囲が常に 10x10 であることが確実にわかっていない限り、その場合はループ条件を変更するだけの問題であり、連続する値を検出する方法が必要になります。

このコードスニペットは、そうするのに役立ちます

/// <summary>
/// gets the number of consecutive (without any empty cell) values vertically
/// </summary>
/// <param name="aRow"></param>
/// <param name="aColumn"></param>
/// <returns></returns>
public int GetNumberConsecValues(int aRow, int aColumn)
{
   int wCount = 0;
   while (this[aRow + wCount, aColumn] != null)
   {
     wCount++;
   }
   return wCount;
}

必要に応じて値を配列/行列に読み込むために使用します。

/// <summary>
/// Reads the vertical array from the specified cell
/// </summary>
/// <param name="aRow"></param>
/// <param name="aColumn"></param>
/// <returns></returns>
public int[] ReadArrayInt(int aRow, int aColumn)
{
  int wNbValues = this.GetNumberConsecValues(aRow, aColumn);
  if (wNbValues == 0)
     return null;

  int[] wArr = new int[wNbValues];
  for (int iRow = 0; iRow < wNbValues; iRow++)
  {
    wArr[iRow] = Convert.ToInt32(this[aRow + iRow, aColumn]);
  }

  return wArr;
}

範囲がわかっている場合は、この他のコード スニペットを使用できます

public object[,] ReadRange(int aColFrom, int aColTo, int aRowFrom, int aRowTo)
{
  this.BeginUpdate();
  try
  {
    SpreadsheetGear.IRange oRange = m_ViewLock.Workbook.ActiveWorksheet.Cells[aRowFrom, aColFrom, aRowTo, aColTo];

    object[,] oValues = new object[aRowTo - aRowFrom + 1, aColTo - aColFrom + 1];

    int iRCol = 0;
    for (int iCol = aColFrom; iCol <= aColTo; iCol++)
    {
      int iRRow = 0;
      for (int iRow = aRowFrom; iRow <= aRowTo; iRow++)
      {
        oValues[iRRow, iRCol] = oRange.Cells[iRRow, iRCol].Value;
        iRRow++;
      }
      iRCol++;
    }
    return oValues;
  }
  finally
  {
    this.EndUpdate();
  }
}

BeginUpdate と EndUpdate は次のように定義されます。

/// <summary>
/// Must be called before the grid is being modified
/// We also call it inside every method so that if the user forgets to call it is no big deal
/// For this reason the calls can be nested.
/// So if the user forgets to make the call it is safe
/// and if the user does not forget he/she gets the full speed benefits..
/// </summary>
public void BeginUpdate()
{
  if (m_ViewLockCount == 0)
    m_ViewLock = new CWorkbookViewLockHelper(this.Workbook);

  m_ViewLockCount++;
}

/// <summary>
/// Must be called after the grid has being modified
/// </summary>
public void EndUpdate()
{
  m_ViewLockCount--;
  if (m_ViewLockCount <= 0)
  {
    m_ViewLock.Dispose();
    m_ViewLock = null;
  }
}
于 2013-07-18T10:42:13.063 に答える