LightCells の使用 API

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

Aspose.Cells は LightCells API を提供します。これは主に、(Cell コレクションなどを使用して) 完全なデータ モデル ブロックをメモリに構築することなく、セル データを 1 つずつ操作するように設計されています。イベント駆動モードで動作します。

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

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

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

LightCells API は XLSX および XLS ファイルに対して同じ方法でセルを処理します (実際にはすべてのセルをメモリにロードするのではなく、1 つのセルを処理してから破棄します)。 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) によってデータとプロパティが設定されます。このセルのデータが設定されると、このセルは生成されたスプレッドシート ファイルに直接保存され、次のセルがチェックされて処理されます。

次の例は、LightCells API がどのように機能するかを示しています。

次のプログラムは、データで満たされたワークシートに 100,000 レコードを含む巨大なファイルを作成します。ワークシートの特定のセルにハイパーリンク、文字列値、数値、および数式を追加しました。さらに、セルの範囲もフォーマットしました。

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java
public class LightCellsDataProviderDemo implements LightCellsDataProvider {
private final int sheetCount;
private final int maxRowIndex;
private final int maxColIndex;
private int rowIndex;
private int colIndex;
private final Style style1;
private final Style style2;
public LightCellsDataProviderDemo(Workbook wb, int sheetCount, int rowCount, int colCount) {
// set the variables/objects
this.sheetCount = sheetCount;
this.maxRowIndex = rowCount - 1;
this.maxColIndex = colCount - 1;
// add new style object with specific formattings
style1 = wb.createStyle();
Font font = style1.getFont();
font.setName("MS Sans Serif");
font.setSize(10);
font.setBold(true);
font.setItalic(true);
font.setUnderline(FontUnderlineType.SINGLE);
font.setColor(Color.fromArgb(0xffff0000));
style1.setHorizontalAlignment(TextAlignmentType.CENTER);
// create another style
style2 = wb.createStyle();
style2.setCustom("#,##0.00");
font = style2.getFont();
font.setName("Copperplate Gothic Bold");
font.setSize(8);
style2.setPattern(BackgroundType.SOLID);
style2.setForegroundColor(Color.fromArgb(0xff0000ff));
style2.setBorder(BorderType.TOP_BORDER, CellBorderType.THICK, Color.getBlack());
style2.setVerticalAlignment(TextAlignmentType.CENTER);
}
public boolean isGatherString() {
return false;
}
public int nextCell() {
if (colIndex < maxColIndex) {
colIndex++;
return colIndex;
}
return -1;
}
public int nextRow() {
if (rowIndex < maxRowIndex) {
rowIndex++;
colIndex = -1; // reset column index
if (rowIndex % 1000 == 0) {
System.out.println("Row " + rowIndex);
}
return rowIndex;
}
return -1;
}
public void startCell(Cell cell) {
if (rowIndex % 50 == 0 && (colIndex == 0 || colIndex == 3)) {
// do not change the content of hyperlink.
return;
}
if (colIndex < 10) {
cell.putValue("test_" + rowIndex + "_" + colIndex);
cell.setStyle(style1);
} else {
if (colIndex == 19) {
cell.setFormula("=Rand() + test!L1");
} else {
cell.putValue(rowIndex * colIndex);
}
cell.setStyle(style2);
}
}
public void startRow(Row row) {
row.setHeight(25);
}
public boolean startSheet(int sheetIndex) {
if (sheetIndex < sheetCount) {
// reset row/column index
rowIndex = -1;
colIndex = -1;
return true;
}
return false;
}
}
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java
public class Demo {
private static final String OUTPUT_FILE_PATH = Utils.getDataDir(LightCellsDataProviderDemo.class);
public static void main(String[] args) throws Exception {
// Instantiate a new Workbook
Workbook wb = new Workbook();
// set the sheet count
int sheetCount = 1;
// set the number of rows for the big matrix
int rowCount = 100000;
// specify the worksheet
for (int k = 0; k < sheetCount; k++) {
Worksheet sheet = null;
if (k == 0) {
sheet = wb.getWorksheets().get(k);
sheet.setName("test");
} else {
int sheetIndex = wb.getWorksheets().add();
sheet = wb.getWorksheets().get(sheetIndex);
sheet.setName("test" + sheetIndex);
}
Cells cells = sheet.getCells();
// set the columns width
for (int j = 0; j < 15; j++) {
cells.setColumnWidth(j, 15);
}
// traverse the columns for adding hyperlinks and merging
for (int i = 0; i < rowCount; i++) {
// The first 10 columns
for (int j = 0; j < 10; j++) {
if (j % 3 == 0) {
cells.merge(i, j, 1, 2, false, false);
}
if (i % 50 == 0) {
if (j == 0) {
sheet.getHyperlinks().add(i, j, 1, 1, "test!A1");
} else if (j == 3) {
sheet.getHyperlinks().add(i, j, 1, 1, "http://www.google.com");
}
}
}
// The second 10 columns
for (int j = 10; j < 20; j++) {
if (j == 12) {
cells.merge(i, j, 1, 3, false, false);
}
}
}
}
// Create an object with respect to LightCells data provider
LightCellsDataProviderDemo dataProvider = new LightCellsDataProviderDemo(wb, 1, rowCount, 20);
// Specify the XLSX file's Save options
OoxmlSaveOptions opt = new OoxmlSaveOptions();
// Set the data provider for the file
opt.setLightCellsDataProvider(dataProvider);
// Save the big file
wb.save(OUTPUT_FILE_PATH + "/DemoTest.xlsx", opt);
}
}

大きな Excel ファイルの読み取り

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

このモードでワークブックを読み取る場合、ワークブック内のすべてのワークシートを読み取るときに startSheet() がチェックされます。シートの場合、startSheet() が true を返す場合、シートの行と列のセルのすべてのデータとプロパティがチェックされ、処理されます。行ごとに startRow() が呼び出され、処理が必要かどうかが確認されます。行を処理する必要がある場合、行のプロパティが最初に読み取られ、開発者は processRow() を使用してそのプロパティにアクセスできます。

行のセルも処理する必要がある場合、processRow() は true を返し、行内の既存のすべてのセルに対して startCell() が呼び出され、処理が必要かどうかが確認されます。存在する場合、processCell() が呼び出されます。

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

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java
public class LightCellsTest1 {
public static void main(String[] args) throws Exception {
String dataDir = Utils.getDataDir(LightCellsTest1.class);
LoadOptions opts = new LoadOptions();
LightCellsDataHandlerVisitCells v = new LightCellsDataHandlerVisitCells();
opts.setLightCellsDataHandler((LightCellsDataHandler) v);
Workbook wb = new Workbook(dataDir + "LargeBook1.xlsx", opts);
int sheetCount = wb.getWorksheets().getCount();
System.out.println("Total sheets: " + sheetCount + ", cells: " + v.cellCount + ", strings: " + v.stringCount
+ ", formulas: " + v.formulaCount);
}
}

LightCellsDataHandler インターフェイスを実装するクラス

// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-Java
public class LightCellsDataHandlerVisitCells implements LightCellsDataHandler {
public int cellCount;
public int formulaCount;
public int stringCount;
public LightCellsDataHandlerVisitCells() {
this.cellCount = 0;
this.formulaCount = 0;
this.stringCount = 0;
}
public int cellCount() {
return cellCount;
}
public int formulaCount() {
return formulaCount;
}
public int stringCount() {
return stringCount;
}
public boolean startSheet(Worksheet sheet) {
System.out.println("Processing sheet[" + sheet.getName() + "]");
return true;
}
public boolean startRow(int rowIndex) {
return true;
}
public boolean processRow(Row row) {
return true;
}
public boolean startCell(int column) {
return true;
}
public boolean processCell(Cell cell) {
this.cellCount = this.cellCount + 1;
if (cell.isFormula()) {
this.formulaCount = this.formulaCount + 1;
} else if (cell.getType() == CellValueType.IS_STRING) {
this.stringCount = this.stringCount + 1;
}
return false;
}
}