我的表单中有一个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。
发布于 2013-07-19 22:22:38
您没有提供一行代码来指示cells变量的来源,但是如果您得到的行数是1,048,576,这就表明cells来自XFD.XFD1048576,这两个变量都表示工作表中的所有单元格(A1:IWorksheet 1048576)。
如果您试图在工作表中迭代某个较小的范围,则需要使用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中进入范围的调用是多余的,因为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工作。
发布于 2020-05-15 23:27:21
你应该使用
SpreadsheetGear.IRange cells = worksheet.UsedRange;发布于 2013-07-18 18:42:13
除非您确定范围始终为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;
}
}https://stackoverflow.com/questions/17720717
复制相似问题