Utilisation de l API LightCells

Architecture orientée événements

Aspose.Cells fournit l’API LightCells, principalement conçue pour manipuler les données de cellules une par une sans construire un bloc de modèle de données complet (en utilisant la collection Cell, etc.) en mémoire. Il fonctionne en mode orienté événements.

Pour enregistrer des classeurs, fournissez le contenu des cellules une par une lors de l’enregistrement, et le composant l’enregistre directement dans le fichier de sortie.

Lors de la lecture de fichiers de modèle, le composant analyse chaque cellule et fournit leur valeur une par une.

Dans les deux procédures, un objet Cell est traité puis jeté, l’objet Workbook ne détient pas la collection. Dans ce mode, donc, la mémoire est économisée lors de l’importation et de l’exportation d’un fichier Microsoft Excel qui a un grand ensemble de données et qui utiliserait autrement beaucoup de mémoire.

Bien que l’API LightCells traite les cellules de la même manière pour les fichiers XLSX et XLS (elle ne charge pas réellement toutes les cellules en mémoire mais traite une cellule puis la rejette), elle économise plus efficacement la mémoire pour les fichiers XLSX que pour les fichiers XLS en raison des différents modèles de données et structures des deux formats.

Cependant, pour les fichiers XLS, pour économiser davantage de mémoire, les développeurs peuvent spécifier un emplacement temporaire pour enregistrer les données temporaires générées pendant le processus d’enregistrement. Généralement, utiliser l’API LightCells pour enregistrer un fichier XLSX peut économiser 50% ou plus de mémoire que d’utiliser la méthode classique, enregistrer un fichier XLS peut économiser environ 20 à 40% de mémoire.

Écriture de gros fichiers Excel

Aspose.Cells fournit une interface, LightCellsDataProvider, qui doit être implémentée dans votre programme. L’interface représente le fournisseur de données pour sauvegarder de grands fichiers de feuilles de calcul en mode léger.

Lors de l’enregistrement d’un classeur dans ce mode, startSheet(int) est vérifié à chaque enregistrement de feuille de calcul dans le classeur. Pour une feuille, si startSheet(int) est vrai, alors toutes les données et propriétés des lignes et des cellules de cette feuille à sauvegarder sont fournies par cette implémentation. En premier lieu, nextRow() est appelée pour obtenir l’indice de la prochaine ligne à sauvegarder. Si un indice de ligne valide est retourné (l’indice de ligne doit être en ordre croissant pour les lignes à sauvegarder), alors un objet Row représentant cette ligne est fourni pour que l’implémentation définisse ses propriétés par startRow(Row).

Pour une ligne, nextCell() est d’abord vérifié. Si un indice de colonne valide est retourné (l’indice de colonne doit être en ordre croissant pour que toutes les cellules d’une ligne soient sauvegardées), alors un objet Cell représentant cette cellule est fourni pour définir les données et les propriétés par startCell(Cell). Après que les données de cette cellule ont été définies, cette cellule est directement sauvegardée dans le fichier de feuille de calcul généré et la cellule suivante est vérifiée et traitée.

L’exemple suivant montre comment fonctionne l’API LightCells.

Le programme suivant crée un fichier volumineux avec 100 000 enregistrements dans une feuille de calcul, remplie de données. Nous avons ajouté des liens hypertexte, des valeurs de chaîne, des valeurs numériques et également des formules à certaines cellules de la feuille de calcul. De plus, nous avons également formaté une plage de cellules.

// 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);
}
}

Lecture de gros fichiers Excel

Aspose.Cells fournit une interface, LightCellsDataHandler, qui doit être implémentée dans votre programme. L’interface représente le fournisseur de données pour la lecture de grands fichiers de feuilles de calcul en mode léger.

Lors de la lecture d’un classeur dans ce mode, startSheet() est vérifié à chaque lecture de feuille de calcul dans le classeur. Pour une feuille, si startSheet() renvoie vrai, alors toutes les données et propriétés des cellules dans les lignes et colonnes de la feuille sont vérifiées et traitées. Pour chaque ligne, startRow() est appelé pour vérifier s’il doit être traité. Si une ligne doit être traitée, les propriétés de la ligne sont d’abord lues et les développeurs peuvent accéder à ses propriétés avec processRow().

Si les cellules de la ligne doivent également être traitées, alors si processRow() renvoie vrai, startCell() est appelé pour chaque cellule existante de la ligne pour vérifier si elle doit être traitée. Si c’est le cas, processCell() est appelé.

Le code d’exemple suivant illustre ce processus. Le programme lit un fichier volumineux avec des millions d’enregistrements. Il faut un peu de temps pour lire chaque feuille dans le classeur. Le code d’exemple lit le fichier et récupère le nombre total de cellules, le nombre de chaînes et le nombre de formules pour chaque feuille de calcul.

// 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);
}
}

Une classe qui implémente l’interface 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;
}
}