LightCells APIの使用

イベント駆動アーキテクチャ

Aspose.Cellsは、セルのコレクションなどの完全なデータモデルブロックをメモリに構築せずに、イベント駆動モードでセルデータを1つずつ操作するために、LightCells APIを提供しています。

ワークブックを保存するには、セルの内容を1つずつ提供し、コンポーネントがそれを直接出力ファイルに保存します。

テンプレートファイルを読み込む際に、コンポーネントはすべてのセルを解析し、その値を1つずつ提供します。

両手順ともに、1つのCellオブジェクトが処理され、その後破棄され、Workbookオブジェクトはコレクションを保持しません。そのため、このモードでは、大規模なデータセットを持つMicrosoft Excelファイルのインポートおよびエクスポート時にメモリを節約することができます。

LightCells APIは、XLSXファイルとXLSファイルでセルを同じように処理します(実際にはすべてのセルをメモリに読み込むのではなく、1つのセルを処理してから破棄します)が、XLSXファイルではXLSファイルよりもメモリを効果的に節約します。これは2つのフォーマットの異なるデータモデルと構造のためです。

ただし、XLSファイルの場合、より多くのメモリを節約するには、開発者が保存プロセス中に生成される一時データの保存に一時的な場所を指定することができます。通常、LightCells APIを使用してXLSXファイルを保存する場合、約50%以上のメモリを節約できますが、XLSを保存する場合は20-40%のメモリを節約できます。

大規模なExcelファイルの書き込み

Aspose.Cellsは、大規模なスプレッドシートファイルを軽量モードで保存するためにプログラムで実装する必要があるLightCellsDataProviderというインターフェースを提供しています。

このモードでワークブックを保存する場合、ワークブック内のすべてのワークシートを保存する際にStartSheet(int)がチェックされます。1つのシートについて、StartSheet(int)がtrueの場合、この実装によって保存されるこのシートのすべての行とセルのデータやプロパティが提供されます。まず、次の行インデックスを取得するためにNextRow()が呼び出されます。有効な行インデックスが返されると(行インデックスは保存する行の順序が昇順である必要があります)、この行を表すRowオブジェクトが提供され、そのプロパティをStartRow(Row)によって設定するために実装されます。

1行について、まずNextCell()がチェックされます。有効な列インデックスが返されると(列インデックスは1行のすべてのセルが保存されるために昇順である必要があります)、そのセルを表すCellオブジェクトが提供され、そのデータやプロパティをStartCell(Cell)によって設定するために実装されます。セルのデータが設定された後、セルは直接生成されたスプレッドシートファイルに保存され、次のセルがチェックされて処理されます。

大規模なExcelファイルの書き込み:例

LightCells APIの動作を確認するために、以下のサンプルコードを参照してください。必要に応じてコードセグメントを追加、削除、または更新してください。

プログラムはワークシート内に10,000(10000x30マトリックス)レコードを持つ巨大なファイルを作成し、それらをダミーデータで埋めます。Main()メソッド内のrowsCountとcolsCount変数を変更して、独自のマトリックスを指定することができます。

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET
public class WriteUsingLightCellsAPI
{
public static void Run()
{
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
// Specify your desired matrix
int rowsCount = 10000;
int colsCount = 30;
var workbook = new Workbook();
var ooxmlSaveOptions = new OoxmlSaveOptions();
ooxmlSaveOptions.LightCellsDataProvider = new TestDataProvider(workbook, rowsCount, colsCount);
workbook.Save(dataDir + "output.out.xlsx", ooxmlSaveOptions);
}
}
class TestDataProvider : LightCellsDataProvider
{
private int _row = -1;
private int _column = -1;
private int maxRows;
private int maxColumns;
private Workbook _workbook;
public TestDataProvider(Workbook workbook, int maxRows, int maxColumns)
{
this._workbook = workbook;
this.maxRows = maxRows;
this.maxColumns = maxColumns;
}
#region LightCellsDataProvider Members
public bool IsGatherString()
{
return false;
}
public int NextCell()
{
++_column;
if (_column < this.maxColumns)
return _column;
else
{
_column = -1;
return -1;
}
}
public int NextRow()
{
++_row;
if (_row < this.maxRows)
{
_column = -1;
return _row;
}
else
return -1;
}
public void StartCell(Cell cell)
{
cell.PutValue(_row + _column);
if (_row == 1)
{
}
else
{
cell.Formula = "=Rand() + A2";
}
}
public void StartRow(Row row)
{
}
public bool StartSheet(int sheetIndex)
{
if (sheetIndex == 0)
{
return true;
}
else
return false;
}
#endregion
}

大規模なExcelファイルの読み込み

Aspose.Cellsは、プログラムで実装する必要のあるLightCellsDataHandlerというインターフェースを提供します。このインターフェースは、軽量モードで大規模なスプレッドシートファイルを読み込むためのデータプロバイダを表します。

このモードでワークブックを読み込む際、ワークブック内のすべてのワークシートを読み込む際にStartSheetがチェックされます。ワークシートについて、StartSheetがtrueを返すと、そのシート内の行と列のセルのすべてのデータやプロパティがこのインターフェースの実装によってチェックされ、処理されます。各行については、処理が必要かどうかをチェックするためにStartRowが呼び出されます。行が処理が必要な場合、まずそのプロパティが読み取られ、開発者はProcessRowを使用してそのプロパティにアクセスすることができます。また、行のセルも処理する必要がある場合、ProcessRowはtrueを返し、その後、行内の各セルが処理されるためにStartCellが呼び出されます。1つのセルが処理される必要がある場合、ProcessCellが呼び出され、このインターフェースの実装によってセルが処理されます。

大規模なExcelファイルの読み込み:例

LightCells APIの動作を確認するために、以下のサンプルコードを参照してください。必要に応じてコードセグメントを追加、削除、または更新してください。

プログラムはワークシート内に数百万のレコードが含まれる巨大なファイルを読み込みます。ワークブック内の各シートを読み込むには少し時間がかかります。サンプルコードはファイルを読み込み、各ワークシートにおけるセルの総数、文字列の数、および数式の数を取得します。

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET
public class ReadUsingLightCellsApi
{
public static void Run()
{
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
LoadOptions opts = new LoadOptions();
LightCellsDataHandlerVisitCells v = new LightCellsDataHandlerVisitCells();
opts.LightCellsDataHandler = v;
Workbook wb = new Workbook(dataDir + "LargeBook1.xlsx", opts);
int sheetCount = wb.Worksheets.Count;
Console.WriteLine("Total sheets: " + sheetCount + ", cells: " + v.CellCount
+ ", strings: " + v.StringCount + ", formulas: " + v.FormulaCount);
}
}
class LightCellsDataHandlerVisitCells : LightCellsDataHandler
{
private int cellCount;
private int formulaCount;
private int stringCount;
internal LightCellsDataHandlerVisitCells()
{
cellCount = 0;
formulaCount = 0;
stringCount = 0;
}
public int CellCount
{
get { return cellCount; }
}
public int FormulaCount
{
get { return formulaCount; }
}
public int StringCount
{
get { return stringCount; }
}
public bool StartSheet(Worksheet sheet)
{
Console.WriteLine("Processing sheet[" + sheet.Name + "]");
return true;
}
public bool StartRow(int rowIndex)
{
return true;
}
public bool ProcessRow(Row row)
{
return true;
}
public bool StartCell(int column)
{
return true;
}
public bool ProcessCell(Cell cell)
{
cellCount++;
if (cell.IsFormula)
{
formulaCount++;
}
else if (cell.Type == CellValueType.IsString)
{
stringCount++;
}
return false;
}
}