Cómo y dónde usar enumeradores con JavaScript vía C++
Un enumerador es un objeto que proporciona la capacidad de recorrer un contenedor o colección. Los enumeradores se pueden usar para leer los datos en la colección, pero no se pueden usar para modificar la colección subyacente, mientras que Array es una interfaz que define un método enumerator que devuelve una interfaz IEnumerator, lo que, a su vez, permite el acceso de solo lectura a una colección.
Las API de Aspose.Cells proporcionan una serie de enumeradores, sin embargo, este artículo discute principalmente los tres tipos que se enumeran a continuación.
- Enumerador de celdas
- Enumerador de filas
- Enumerador de columnas
Cómo usar Enumeradores
Enumerador de celdas
Hay diversas formas de acceder al enumerador de celdas, y se puede utilizar cualquiera de estos métodos según los requisitos de la aplicación. Aquí están los métodos que devuelven el enumerador de celdas.
Todos los métodos mencionados anteriormente devuelven el enumerador que permite recorrer la colección de celdas que han sido inicializadas.
El siguiente ejemplo de código demuestra la implementación de la interfaz IEnumerator para una colección de Celdas.
<!DOCTYPE html>
<html>
<head>
<title>Aspose.Cells Example</title>
</head>
<body>
<h1>Aspose.Cells Example - Read Cell Values</h1>
<input type="file" id="fileInput" accept=".xls,.xlsx,.csv" />
<button id="runExample">Run Example</button>
<a id="downloadLink" style="display: none;">Download Result</a>
<div id="result"></div>
</body>
<script src="aspose.cells.js.min.js"></script>
<script type="text/javascript">
const { Workbook, SaveFormat } = AsposeCells;
AsposeCells.onReady({
license: "/lic/aspose.cells.enc",
fontPath: "/fonts/",
fontList: [
"arial.ttf",
"NotoSansSC-Regular.ttf"
]
}).then(() => {
console.log("Aspose.Cells initialized");
});
document.getElementById('runExample').addEventListener('click', async () => {
const fileInput = document.getElementById('fileInput');
if (!fileInput.files.length) {
document.getElementById('result').innerHTML = '<p style="color: red;">Please select an Excel file.</p>';
return;
}
const file = fileInput.files[0];
const arrayBuffer = await file.arrayBuffer();
// Instantiating a Workbook object by opening the uploaded Excel file
const workbook = new Workbook(new Uint8Array(arrayBuffer));
// Access the first worksheet
const worksheet = workbook.worksheets.get(0);
const resultLines = [];
// Iterate over all cells in the worksheet
const cellsEnumerator = worksheet.cells.getEnumerator();
for (const cell of cellsEnumerator) {
console.log(`${cell.name} ${cell.value}`);
resultLines.push(`${cell.name} ${cell.value}`);
}
// Iterate over the first row's cells
const firstRowEnumerator = worksheet.cells.rows.get(0).getEnumerator();
for (const cell of firstRowEnumerator) {
console.log(`${cell.name} ${cell.value}`);
resultLines.push(`${cell.name} ${cell.value}`);
}
// Iterate over a specific range A1:B10
const rangeEnumerator = worksheet.cells.createRange("A1:B10").getEnumerator();
for (const cell of rangeEnumerator) {
console.log(`${cell.name} ${cell.value}`);
resultLines.push(`${cell.name} ${cell.value}`);
}
document.getElementById('result').innerHTML = `<pre>${resultLines.join('\n')}</pre>`;
});
</script>
</html>
Enumerador de filas
El Enumerador de Filas puede accederse mientras se usa el método RowCollection.enumerator. El siguiente ejemplo de código demuestra la implementación de la interfaz IEnumerator para RowCollection.
<!DOCTYPE html>
<html>
<head>
<title>Aspose.Cells Example</title>
</head>
<body>
<h1>Aspose.Cells Example - List Row Indexes</h1>
<input type="file" id="fileInput" accept=".xls,.xlsx,.csv" />
<button id="runExample">Run Example</button>
<a id="downloadLink" style="display: none;">Download Result</a>
<div id="result"></div>
</body>
<script src="aspose.cells.js.min.js"></script>
<script type="text/javascript">
const { Workbook, SaveFormat } = AsposeCells;
AsposeCells.onReady({
license: "/lic/aspose.cells.enc",
fontPath: "/fonts/",
fontList: [
"arial.ttf",
"NotoSansSC-Regular.ttf"
]
}).then(() => {
console.log("Aspose.Cells initialized");
});
document.getElementById('runExample').addEventListener('click', async () => {
const fileInput = document.getElementById('fileInput');
if (!fileInput.files.length) {
document.getElementById('result').innerHTML = '<p style="color: red;">Please select an Excel file.</p>';
return;
}
const file = fileInput.files[0];
const arrayBuffer = await file.arrayBuffer();
// Instantiate Workbook from uploaded file
const workbook = new Workbook(new Uint8Array(arrayBuffer));
// Get RowCollection and iterate using index
const rows = workbook.worksheets.get(0).cells.rows;
const rowCount = rows.count;
// Traverse rows in the collection and display indexes
let output = '<p>Row indexes:</p><ul>';
for (let i = 0; i < rowCount; i++) {
const row = rows.get(i);
output += `<li>${row.index}</li>`;
console.log(row.index);
}
output += '</ul>';
document.getElementById('result').innerHTML = output;
});
</script>
</html>
Enumerador de columnas
El Enumerador de Columnas puede accederse mientras se usa el método ColumnCollection.enumerator. El siguiente ejemplo de código demuestra la implementación de la interfaz IEnumerator para ColumnCollection.
<!DOCTYPE html>
<html>
<head>
<title>Aspose.Cells Example</title>
</head>
<body>
<h1>Read Columns Indexes Example</h1>
<input type="file" id="fileInput" accept=".xls,.xlsx,.csv" />
<button id="runExample">Run Example</button>
<a id="downloadLink" style="display: none;">Download Result</a>
<div id="result"></div>
</body>
<script src="aspose.cells.js.min.js"></script>
<script type="text/javascript">
const { Workbook, SaveFormat } = AsposeCells;
AsposeCells.onReady({
license: "/lic/aspose.cells.enc",
fontPath: "/fonts/",
fontList: [
"arial.ttf",
"NotoSansSC-Regular.ttf"
]
}).then(() => {
console.log("Aspose.Cells initialized");
});
document.getElementById('runExample').addEventListener('click', async () => {
const fileInput = document.getElementById('fileInput');
if (!fileInput.files.length) {
document.getElementById('result').innerHTML = '<p style="color: red;">Please select an Excel file.</p>';
return;
}
const file = fileInput.files[0];
const arrayBuffer = await file.arrayBuffer();
// Instantiating a Workbook object from uploaded file
const workbook = new Workbook(new Uint8Array(arrayBuffer));
// Get columns collection from first worksheet
const columns = workbook.worksheets.get(0).cells.columns;
// Traverse columns using index
const count = columns.count;
let html = '<p>Columns indexes:</p><ul>';
for (let i = 0; i < count; i++) {
const col = columns.get(i);
html += `<li>${col.index}</li>`;
console.log(col.index);
}
html += '</ul>';
document.getElementById('result').innerHTML = html;
});
</script>
</html>
Dónde usar Enumeradores
Para discutir las ventajas de usar enumeradores, tomemos un ejemplo en tiempo real.
Escenario
Un requisito de la aplicación es recorrer todas las celdas en un Worksheet dado para leer sus valores. Podrían implementarse varias formas de lograr esto. Se muestran algunas a continuación.
Usando Rango de Visualización
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Aspose.Cells Example</title>
</head>
<body>
<h1>Read Max Display Range Example</h1>
<input type="file" id="fileInput" accept=".xls,.xlsx,.csv" />
<button id="runExample">Run Example</button>
<a id="downloadLink" style="display: none;">Download Result</a>
<div id="result"></div>
</body>
<script src="aspose.cells.js.min.js"></script>
<script type="text/javascript">
const { Workbook, SaveFormat } = AsposeCells;
AsposeCells.onReady({
license: "/lic/aspose.cells.enc",
fontPath: "/fonts/",
fontList: [
"arial.ttf",
"NotoSansSC-Regular.ttf"
]
}).then(() => {
console.log("Aspose.Cells initialized");
});
document.getElementById('runExample').addEventListener('click', async () => {
const fileInput = document.getElementById('fileInput');
const resultDiv = document.getElementById('result');
resultDiv.innerHTML = '';
if (!fileInput.files.length) {
resultDiv.innerHTML = '<p style="color: red;">Please select an Excel file.</p>';
return;
}
const file = fileInput.files[0];
const arrayBuffer = await file.arrayBuffer();
// Instantiating a Workbook object by opening the Excel file from the uploaded file
const workbook = new Workbook(new Uint8Array(arrayBuffer));
// Get Cells collection of first worksheet
const cells = workbook.worksheets.get(0).cells;
// Get the MaxDisplayRange
const displayRange = cells.maxDisplayRange;
// Loop over all cells in the MaxDisplayRange
let outputLines = [];
for (let row = displayRange.firstRow; row < displayRange.rowCount; row++) {
for (let col = displayRange.firstColumn; col < displayRange.columnCount; col++) {
// Read the Cell value (stringValue property)
const cell = displayRange.get(row, col);
outputLines.push(cell.stringValue);
console.log(cell.stringValue);
}
}
resultDiv.innerHTML = '<pre>' + outputLines.join('\n') + '</pre>';
});
</script>
</html>
Usando MaxDataRow y MaxDataColumn
<!DOCTYPE html>
<html>
<head>
<title>Aspose.Cells Example</title>
<meta charset="utf-8" />
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
#result { margin-top: 15px; max-height: 400px; overflow: auto; border: 1px solid #ddd; padding: 10px; }
.cell-value { padding: 2px 0; border-bottom: 1px dashed #eee; }
.error { color: red; }
</style>
</head>
<body>
<h1>Read Cells Example</h1>
<input type="file" id="fileInput" accept=".xlsx,.xls,.csv" />
<button id="runExample">Run Example</button>
<a id="downloadLink" style="display: none;">Download Result</a>
<div id="result"></div>
</body>
<script src="aspose.cells.js.min.js"></script>
<script type="text/javascript">
const { Workbook } = AsposeCells;
AsposeCells.onReady({
license: "/lic/aspose.cells.enc",
fontPath: "/fonts/",
fontList: [
"arial.ttf",
"NotoSansSC-Regular.ttf"
]
}).then(() => {
console.log("Aspose.Cells initialized");
});
function escapeHtml(text) {
if (text === null || text === undefined) return '';
return String(text)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
document.getElementById('runExample').addEventListener('click', async () => {
const fileInput = document.getElementById('fileInput');
const resultDiv = document.getElementById('result');
resultDiv.innerHTML = '';
if (!fileInput.files.length) {
resultDiv.innerHTML = '<p class="error">Please select an Excel file.</p>';
return;
}
const file = fileInput.files[0];
const arrayBuffer = await file.arrayBuffer();
// Instantiating a Workbook object by opening the Excel file from the uploaded file
const workbook = new Workbook(new Uint8Array(arrayBuffer));
// Get Cells collection of first worksheet
const cells2 = workbook.worksheets.get(0).cells;
const maxDataRow = cells2.maxDataRow;
const maxDataColumn = cells2.maxDataColumn;
const outputLines = [];
// Loop over all cells
for (let row = 0; row <= maxDataRow; row++) {
for (let col = 0; col <= maxDataColumn; col++) {
// Read the Cell value
const currentCell = cells2.checkCell(row, col);
if (currentCell) {
const cellText = currentCell.stringValue;
outputLines.push('<div class="cell-value">' + escapeHtml(cellText) + '</div>');
console.log(cellText);
}
}
}
if (outputLines.length === 0) {
resultDiv.innerHTML = '<p>No cell values found.</p>';
} else {
resultDiv.innerHTML = outputLines.join('');
}
});
</script>
</html>
Como puedes observar, ambos enfoques mencionados anteriormente utilizan más o menos una lógica similar; es decir, recorrer todas las celdas en la colección para leer los valores de las celdas. Esto podría ser problemático por varias razones, como se discute a continuación.
- Las APIs como maxRow, maxDataRow, maxColumn, maxDataColumn y maxDisplayRange requieren tiempo adicional para recopilar las estadísticas correspondientes. En caso de que la matriz de datos (filas x columnas) sea grande, usar estas APIs podría afectar el rendimiento.
- En la mayoría de los casos, no todas las celdas en un rango dado están instanciadas. En tales situaciones, verificar cada celda en la matriz no es tan eficiente en comparación con verificar solo las celdas inicializadas.
- Acceder a una celda en un bucle como Cells fila, columna hará que se instancien todos los objetos de celda en un rango, lo que eventualmente podría causar OutOfMemoryException.
Conclusión
Con base en los hechos mencionados anteriormente, los siguientes son los posibles escenarios en los que se deben usar los enumeradores.
- Se requiere acceso de solo lectura a la colección de celdas, es decir; el requisito es solo inspeccionar las celdas.
- Se deben recorrer un gran número de celdas.
- Solo se deben recorrer celdas/filas/columnas inicializadas.