Usando LightCells API
Arquitectura impulsada por eventos
Aspose.Cells proporciona LightCells API, diseñado principalmente para manipular datos de celda uno por uno sin construir un bloque de modelo de datos completo (usando la colección Cell, etc.) en la memoria. Funciona en un modo controlado por eventos.
Para guardar libros de trabajo, proporcione el contenido de la celda celda por celda al guardar, y el componente lo guarda directamente en el archivo de salida.
Al leer archivos de plantilla, el componente analiza cada celda y proporciona su valor uno por uno.
En ambos procedimientos, se procesa un objeto Cell y luego se descarta, el objeto Workbook no contiene la colección. En este modo, por lo tanto, se ahorra memoria al importar y exportar Microsoft un archivo de Excel que tiene un gran conjunto de datos que, de lo contrario, usaría mucha memoria.
Aunque LightCells API procesa las celdas de la misma manera para los archivos XLSX y XLS (en realidad no carga todas las celdas en la memoria sino que procesa una celda y luego la descarta), ahorra memoria de manera más efectiva para los archivos XLSX que para los archivos XLS debido a los diferentes modelos de datos y estructuras de los dos formatos.
Sin embargo,para archivos XLS , para ahorrar más memoria, los desarrolladores pueden especificar una ubicación temporal para guardar los datos temporales generados durante el proceso Guardar. Comúnmente,usar LightCells API para guardar el archivo XLSX puede ahorrar un 50% o más de memoria que usar la forma común,guardar XLS puede ahorrar entre un 20 y un 40 % de memoria.
Escribir archivos grandes de Excel
Aspose.Cells proporciona una interfaz, LightCellsDataProvider, que debe implementarse en su programa. La interfaz representa el proveedor de datos para guardar archivos de hojas de cálculo grandes en modo ligero.
Al guardar un libro de trabajo en este modo, startSheet (int) se verifica al guardar cada hoja de trabajo en el libro de trabajo. Para una hoja, si startSheet(int) es verdadero, esta implementación proporciona todos los datos y propiedades de las filas y celdas de esta hoja que se van a guardar. En primer lugar, se llama a nextRow() para obtener el índice de la siguiente fila que se guardará. Si se devuelve un índice de fila válido (el índice de fila debe estar en orden ascendente para que se guarden las filas), se proporciona un objeto Row que representa esta fila para que la implementación establezca sus propiedades mediante startRow(Row).
Para una fila, nextCell() se verifica primero. Si se devuelve un índice de columna válido (el índice de columna debe estar en orden ascendente para que se guarden todas las celdas de una fila), se proporciona un objeto Cell que representa esta celda para establecer los datos y las propiedades mediante startCell(Cell). Después de configurar los datos de esta celda, esta celda se guarda directamente en el archivo de hoja de cálculo generado y la siguiente celda se verificará y procesará.
El siguiente ejemplo muestra cómo funciona LightCells API.
El siguiente programa crea un archivo enorme con 100 000 registros en una hoja de trabajo, llena de datos. Hemos agregado algunos hipervínculos, valores de cadena, valores numéricos y también fórmulas a ciertas celdas en la hoja de trabajo. Además, también hemos formateado un rango de celdas.
// 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); | |
} | |
} |
Leer archivos grandes de Excel
Aspose.Cells proporciona una interfaz, LightCellsDataHandler, que debe implementarse en su programa. La interfaz representa el proveedor de datos para leer grandes archivos de hojas de cálculo en un modo ligero.
Al leer un libro de trabajo en este modo, startSheet() se verifica al leer cada hoja de trabajo en el libro de trabajo. Para una hoja, si startSheet() devuelve verdadero, entonces todos los datos y propiedades de las celdas en las filas y columnas de la hoja se verifican y procesan. Para cada fila, se llama a startRow() para verificar si es necesario procesarla. Si es necesario procesar una fila, primero se leen las propiedades de la fila y los desarrolladores pueden acceder a sus propiedades con processRow().
Si las celdas de la fila también deben procesarse, entonces processRow() devuelve verdadero y se llama a startCell() para cada celda existente en la fila para verificar si es necesario procesarla. Si lo hace, se llama a processCell().
El siguiente código de ejemplo ilustra este proceso. El programa lee un archivo grande con millones de registros. Se necesita un poco de tiempo para leer cada hoja del libro de trabajo. El código de ejemplo lee el archivo y recupera el número total de celdas, el recuento de cadenas y el recuento de fórmulas para cada hoja de cálculo.
// 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); | |
} | |
} |
Una clase que implementa la interfaz 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; | |
} | |
} |