Verwendung von LightCells API
Ereignisgesteuerte Architektur
Aspose.Cells stellt die LightCells API bereit, die hauptsächlich dafür ausgelegt sind, Zelldaten einzeln zu manipulieren, ohne einen vollständigen Datenmodellblock (unter Verwendung der Cell-Sammlung usw.) im Speicher zu erstellen. Es arbeitet in einem ereignisgesteuerten Modus.
Um Arbeitsmappen zu speichern, geben Sie beim Speichern den Zelleninhalt Zelle für Zelle an, und die Komponente speichert ihn direkt in der Ausgabedatei.
Beim Lesen von Vorlagendateien analysiert die Komponente jede Zelle und stellt deren Wert nacheinander bereit.
In beiden Verfahren wird ein Cell-Objekt verarbeitet und dann verworfen, das Workbook-Objekt enthält die Sammlung nicht. In diesem Modus wird also beim Importieren und Exportieren von Microsoft Excel-Dateien mit einem großen Datensatz, der sonst viel Speicher verbrauchen würde, Speicherplatz gespart.
Obwohl LightCells API die Zellen für XLSX- und XLS-Dateien auf die gleiche Weise verarbeitet (es lädt nicht alle Zellen in den Speicher, sondern verarbeitet eine Zelle und verwirft sie dann), spart es aufgrund von XLSX-Dateien effektiver Speicher als XLS-Dateien die unterschiedlichen Datenmodelle und Strukturen der beiden Formate.
Jedoch,für XLS Dateien , um mehr Speicher zu sparen, können Entwickler einen temporären Speicherort zum Speichern temporärer Daten angeben, die während des Speichervorgangs generiert werden. Häufig,Die Verwendung von LightCells API zum Speichern der Datei XLSX kann 50 % oder mehr Speicherplatz sparen als den üblichen Weg zu gehen,Durch das Speichern von XLS können etwa 20-40 % Speicher eingespart werden.
Schreiben großer Excel-Dateien
Aspose.Cells bietet eine Schnittstelle, LightCellsDataProvider, die in Ihrem Programm implementiert werden muss. Die Schnittstelle stellt einen Datenanbieter zum Speichern großer Tabellenkalkulationsdateien im Lightweight-Modus dar.
Beim Speichern einer Arbeitsmappe in diesem Modus wird startSheet(int) überprüft, wenn jedes Arbeitsblatt in der Arbeitsmappe gespeichert wird. Wenn für ein Blatt startSheet(int) wahr ist, dann werden alle Daten und Eigenschaften von Zeilen und Zellen dieses zu speichernden Blatts von dieser Implementierung bereitgestellt. Zunächst wird nextRow() aufgerufen, um den nächsten zu speichernden Zeilenindex zu erhalten. Wenn ein gültiger Zeilenindex zurückgegeben wird (der Zeilenindex muss in aufsteigender Reihenfolge vorliegen, damit die Zeilen gespeichert werden können), wird ein Row-Objekt, das diese Zeile darstellt, für die Implementierung bereitgestellt, um seine Eigenschaften durch startRow(Row) festzulegen.
Für eine Zeile wird zuerst nextCell() geprüft. Wenn ein gültiger Spaltenindex zurückgegeben wird (der Spaltenindex muss in aufsteigender Reihenfolge sein, damit alle Zellen einer Zeile gespeichert werden), wird ein Cell-Objekt bereitgestellt, das diese Zelle darstellt, um die Daten und Eigenschaften von startCell(Cell) festzulegen. Nachdem die Daten dieser Zelle festgelegt wurden, wird diese Zelle direkt in der generierten Tabellendatei gespeichert und die nächste Zelle wird überprüft und verarbeitet.
Das folgende Beispiel zeigt, wie die LightCells API funktioniert.
Das folgende Programm erstellt eine riesige Datei mit 100.000 Datensätzen in einem Arbeitsblatt, gefüllt mit Daten. Wir haben einigen Zellen im Arbeitsblatt einige Hyperlinks, Zeichenfolgenwerte, numerische Werte und auch Formeln hinzugefügt. Darüber hinaus haben wir auch eine Reihe von Zellen formatiert.
// 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); | |
} | |
} |
Große Excel-Dateien lesen
Aspose.Cells bieten eine Schnittstelle, LightCellsDataHandler, die in Ihrem Programm implementiert werden muss. Die Schnittstelle stellt den Datenanbieter zum Lesen großer Tabellenkalkulationsdateien in einem leichtgewichtigen Modus dar.
Beim Lesen einer Arbeitsmappe in diesem Modus wird startSheet() überprüft, wenn jedes Arbeitsblatt in der Arbeitsmappe gelesen wird. Wenn für ein Blatt startSheet() true zurückgibt, werden alle Daten und Eigenschaften der Zellen in den Zeilen und Spalten des Blatts geprüft und verarbeitet. Für jede Zeile wird startRow() aufgerufen, um zu prüfen, ob sie verarbeitet werden muss. Wenn eine Zeile verarbeitet werden muss, werden die Eigenschaften der Zeile zuerst gelesen und Entwickler können mit processRow() auf ihre Eigenschaften zugreifen.
Wenn auch die Zellen der Zeile verarbeitet werden müssen, gibt processRow() true zurück und startCell() wird für jede vorhandene Zelle in der Zeile aufgerufen, um zu prüfen, ob sie verarbeitet werden muss. Wenn dies der Fall ist, wird processCell() aufgerufen.
Der folgende Beispielcode veranschaulicht diesen Vorgang. Das Programm liest eine große Datei mit Millionen von Datensätzen. Es braucht ein wenig Zeit, um jedes Blatt in der Arbeitsmappe zu lesen. Der Beispielcode liest die Datei und ruft die Gesamtzahl der Zellen, die Anzahl der Zeichenfolgen und die Anzahl der Formeln für jedes Arbeitsblatt ab.
// 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); | |
} | |
} |
Eine Klasse, die die LightCellsDataHandler-Schnittstelle implementiert
// 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; | |
} | |
} |