我的表单中有一个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.
答案 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。