Utilisation de LightCells API
Architecture pilotée par les événements
Aspose.Cells fournit les LightCells API, principalement conçus pour manipuler les données des cellules une par une sans créer un bloc de modèle de données complet (en utilisant la collection Cell, etc.) en mémoire. Il fonctionne en mode événementiel.
Pour enregistrer des classeurs, fournissez le contenu de la cellule cellule par cellule lors de l’enregistrement, et le composant l’enregistre directement dans le fichier de sortie.
Lors de la lecture des 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 supprimé, l’objet Workbook ne contient pas la collection. Dans ce mode, par conséquent, la mémoire est économisée lors de l’importation et de l’exportation du fichier Excel Microsoft contenant un grand ensemble de données qui, autrement, utiliserait beaucoup de mémoire.
Même si le LightCells API traite les cellules de la même manière pour les fichiers XLSX et XLS (il ne charge pas réellement toutes les cellules en mémoire mais traite une cellule puis la supprime), il économise de la mémoire plus efficacement pour les fichiers XLSX que pour les fichiers XLS en raison de les différents modèles et structures de données 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 lors du processus d’enregistrement. Communément,l’utilisation de LightCells API pour enregistrer le fichier XLSX peut économiser 50 % ou plus de mémoire que d’utiliser la voie commune,enregistrer XLS peut économiser environ 20 à 40% de mémoire.
Écrire 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 enregistrer des fichiers de feuille de calcul volumineux en mode léger.
Lors de l’enregistrement d’un classeur par ce mode, startSheet(int) est vérifié lors de l’enregistrement de chaque feuille de calcul dans le classeur. Pour une feuille, si startSheet(int) vaut true, alors toutes les données et propriétés des lignes et cellules de cette feuille à sauvegarder sont fournies par cette implémentation. En premier lieu, nextRow() est appelé pour obtenir l’index de la ligne suivante à enregistrer. Si un index de ligne valide est renvoyé (l’index de ligne doit être dans l’ordre croissant pour que les lignes soient enregistrées), 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 vérifié en premier. Si un index de colonne valide est renvoyé (l’index de colonne doit être dans l’ordre croissant pour que toutes les cellules d’une ligne soient enregistrées), un objet Cell représentant cette cellule est fourni pour définir les données et les propriétés par startCell(Cell). Une fois les données de cette cellule définies, cette cellule est enregistrée directement dans le fichier de feuille de calcul généré et la cellule suivante sera vérifiée et traitée.
L’exemple suivant montre comment fonctionne le LightCells API.
Le programme suivant crée un énorme fichier avec 100 000 enregistrements dans une feuille de calcul, rempli de données. Nous avons ajouté des hyperliens, 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 fournissent 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 fichiers de feuille de calcul volumineux en mode léger.
Lors de la lecture d’un classeur dans ce mode, startSheet() est vérifié lors de la lecture de chaque feuille de calcul dans le classeur. Pour une feuille, si startSheet() renvoie true, toutes les données et propriétés des cellules des lignes et des colonnes de la feuille sont vérifiées et traitées. Pour chaque ligne, startRow() est appelée pour vérifier si elle doit être traitée. Si une ligne doit être traitée, les propriétés de la ligne sont lues en premier 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 processRow() renvoie true et startCell() est appelée pour chaque cellule existante de la ligne pour vérifier si elle doit être traitée. Si c’est le cas, processCell() est appelé.
L’exemple de code suivant illustre ce processus. Le programme lit un gros fichier avec des millions d’enregistrements. Il faut un peu de temps pour lire chaque feuille du cahier. L’exemple de code 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; | |
} | |
} |