Användning av LightCells API
Händelsestyrd arkitektur
Aspose.Cells tillhandahåller LightCells API, främst utformat för att manipulera celldata en i taget utan att bygga en komplett datamodellblock (med hjälp av Cell-samlingen etc.) i minnet. Det fungerar i ett händelsestyrt läge.
För att spara arbetsböcker, ange cellinnehållet cell för cell vid sparande, och komponenten sparar det till utdatafilen direkt.
När du läser mallfiler parsa komponenten varje cell och tillhandahåller deras värde en i taget.
I båda procedurerna bearbetas sedan en Cell-objekt och kastas sedan bort, Workbook-objektet håller inte samlingen. I detta läge sparas därför minnet när Microsoft Excel-fil med en stor datamängd importeras och exporteras, vilket annars skulle använda mycket minne.
Även om LightCells API bearbetar cellerna på samma sätt för XLSX- och XLS-filer (det läser inte faktiskt in alla celler i minnet utan bearbetar en cell och kastar sedan bort den), sparar det minnet effektivare för XLSX-filer än XLS-filer på grund av de olika datamodellerna och strukturerna för de två formaten.
För XLS-filer kan utvecklare dock för att spara minne specificera en temporär plats för att spara temporära data som genereras under sparandeprocessen. Vanligtvis kan användning av LightCells API för att spara XLSX-fil spara 50 % eller mer minne än att använda det vanliga sättet, sparande XLS-fil kan spara cirka 20-40 % minne.
Skrivning av stora Excel-filer
Aspose.Cells tillhandahåller en gränssnitt, LightCellsDataProvider, som måste implementeras i ditt program. Gränssnittet representerar Dataprovider för att spara stora kalkylbladsfiler i lättviktigt läge.
När du sparar en arbetsbok i detta läge kontrolleras startSheet(int) när varje kalkylblad i arbetsboken sparas. För ett ark, om startSheet(int) är sant, då tillhandahålls all data och egenskaper för rader och celler i detta ark som ska sparas av denna implementation. Först kallas nextRow() för att få nästa radindex som ska sparas. Om ett giltigt radindex returneras (radindexet måste vara i stigande ordning för rader som ska sparas), tillhandahålls en Row-objekt som representerar denna rad för implementationen för att ange dess egenskaper med startRow(Row).
För en rad kontrolleras nästaCell() först. Om ett giltigt kolumnindex returneras (kolumnindexet måste vara i stigande ordning för alla celler i en rad som ska sparas), tillhandahålls en Cell-objekt som representerar denna cell för att ange data och egenskaper med startCell(Cell). Efter att data för denna cell har angetts, sparas denna cell direkt till den genererade kalkylbladsfilen och nästa cell kontrolleras och bearbetas.
Följande exempel visar hur LightCells API fungerar.
Programmet skapar en stor fil med 100 000 poster i ett kalkylblad, fyllt med data. Vi har lagt till några hyperlänkar, strängvärden, numeriska värden och också formler till vissa celler i kalkylbladet. Dessutom har vi formaterat en rad celler också.
// 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); | |
} | |
} |
Läsning av stora Excel-filer
Aspose.Cells tillhandahåller ett gränssnitt, LightCellsDataHandler, som måste implementeras i ditt program. Gränssnittet representerar dataprovider för att läsa stora kalkylbladsfiler i lättviktigt läge.
Vid läsning av en arbetsbok i detta läge kontrolleras startSheet() när varje kalkylblad i arbetsboken läses. För ett ark, om startSheet() returnerar true, då kontrolleras och bearbetas all data och egenskaper för cellerna i arkets rader och kolumner. För varje rad kallas startRow() för att kontrollera om den måste bearbetas. Om en rad måste bearbetas, läses först radens egenskaper och utvecklare kan komma åt dess egenskaper med processRow().
Om radens celler också måste bearbetas, då returnerar processRow() true och startCell() kallas för varje befintlig cell i raden för att kontrollera om den måste bearbetas. Om den måste det, kallas processCell().
Följande exempelkod illustrerar denna process. Programmet läser en stor fil med miljontals poster. Det tar lite tid att läsa varje kalkylblad i arbetsboken. Exempelkoden läser filen och hämtar det totala antalet celler, antal strängar och antal formler för varje kalkylblad.
// 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); | |
} | |
} |
En klass som implementerar LightCellsDataHandler-gränssnittet
// 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; | |
} | |
} |