SpreadSheetGear WorkbookView - Ячейки

У меня в форме есть 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.


person Ventsislav Vulchev    schedule 18.07.2013    source источник


Ответы (4)


Вы не предоставляете строку кода, которая указывает, откуда берется переменная cells, но если вы получаете количество строк 1 048 576, это указывает мне, что cells пришло из IWorksheet. Ячейки / 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;

Кроме того, ваш вызов в Range в ячейках. IRange ~ Range.html "rel =" nofollow "> Range просто представляет указанный IRange. Вы можете просто использовать cells.RowCount.

Вы также можете просмотреть нашу документацию по индексатору IRange (IRange.Item (…)), который демонстрирует несколько различных способов ссылки на ячейки: http://www.spreadsheetgear.com/support/help/spreadsheetgear.net.7.0/#SpreadsheetGear2012.Core~SpreadsheetGear.IRange~Item.html

Отказ от ответственности: я работаю в SpreadsheetGear.

person Tim Andersen    schedule 19.07.2013

Вы должны использовать

SpreadsheetGear.IRange cells = worksheet.UsedRange;
person Pradeep Gudlanur    schedule 15.05.2020

Если вы не знаете наверняка, что диапазон всегда равен 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;
  }
}
person Michael Moreno    schedule 18.07.2013

Другой способ получить сетки данных - использовать 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

person Xcheque    schedule 21.07.2013