SpreadSheetGear WorkbookView - Cells

时间:2013-07-18 10:18:38

标签: c# spreadsheetgear

我的表单中有一个SpreadSheetGear WorkbookView。 SpreadSheetGear WorkbookView已经用excel文件填充了10行和10列。 我想使用以下代码从单元格中获取数据:

 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 个答案:

答案 0 :(得分:3)

您没有提供一行代码来指示cells变量的来源,但如果您的行数为1,048,576,这表明cells来自IWorksheet 。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。UsedRange。例如:

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工作。

答案 1 :(得分:1)

您应该使用

SpreadsheetGear.IRange cells = worksheet.UsedRange;

答案 2 :(得分: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;
  }
}

答案 3 :(得分:0)

获取数据网格的另一种方法是通过数据表如下:

在电子表格名称中有一个范围

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 example