Использование API LightCells с Node.js через C++
Архитектура, основанная на событиях
Aspose.Cells предоставляет API LightCells, преимущественно предназначенный для манипулирования данными ячейки одна за другой без построения полной модели данных (используя коллекцию Cell и т. д.) в памяти. Он работает в режиме событийного управления.
Для сохранения рабочих книг предоставьте содержание ячейки по ячейке при сохранении, и компонент сохранит его непосредственно в выходной файл.
При считывании файлов-шаблонов компонент анализирует каждую ячейку и предоставляет их значение по одной.
В обеих процедурах один объект Cell обрабатывается и затем удаляется; объект Workbook не содержит коллекцию. В этом режиме сохраняется память при импорте и экспорте файлов Microsoft Excel с большим набором данных, которые иначе занимали бы много памяти.
Несмотря на то, что API LightCells обрабатывает ячейки одинаково для файлов XLSX и XLS (он на самом деле не загружает все ячейки в память, а обрабатывает одну ячейку, а затем удаляет ее), он более эффективно экономит память для файлов XLSX, чем для файлов XLS из-за разных моделей данных и структур двух форматов.
Однако, для XLS файлов, чтобы сэкономить больше памяти, разработчики могут указать временное местоположение для сохранения временных данных, создаваемых в процессе сохранения. Обычно, использование API LightCells для сохранения XLSX файлов может сэкономить 50% или более памяти, чем стандартный способ; сохранение XLS может сэкономить около 20-40% памяти.
Создание большого файла Excel
Aspose.Cells предоставляет интерфейс LightCellsDataProvider
, который необходимо реализовать в вашей программе. Этот интерфейс представляет собой поставщика данных для сохранения больших файлов таблиц в легком режиме.
При сохранении рабочей книги в этом режиме, при сохранении каждого листа проверяется StartSheet(int)
. Если для листа он возвращает true, то все данные и свойства строк и ячеек этого листа предоставляются этой реализацией. В первую очередь вызывается NextRow()
для получения следующего индекса строки для сохранения. Если возвращается допустимый индекс строки (индекс строки должен быть в порядке возрастания для сохраняемых строк), то указывается объект Row, представляющий эту строку, для установки его свойств через StartRow(Row)
.
Для одной строки сначала проверяется NextCell()
. Если возвращается допустимый индекс столбца (он должен быть в порядке возрастания для всех ячеек одной строки), то объект Cell, представляющий эту ячейку, передается для установки данных и свойств через StartCell(Cell)
. После установки данных ячейки, ячейка сохраняется напрямую в сгенерированный файл таблицы, и проверяется и обрабатывается следующая ячейка.
Запись большого Excel-файла: пример
Пожалуйста, ознакомьтесь со следующим образцовым кодом, чтобы увидеть работу API LightCells. Добавьте, удалите или обновите сегменты кода в соответствии с вашими потребностями.
Программа создает огромный файл с 10 000 (матрица 10000x30) записей на листе и заполняет их тестовыми данными. Вы можете указать свою матрицу, изменяя переменные rowsCount
и colsCount
в методе Main()
.
const path = require("path");
const AsposeCells = require("aspose.cells.node");
class TestDataProvider {
constructor(workbook, maxRows, maxColumns) {
this._workbook = workbook;
this.maxRows = maxRows;
this.maxColumns = maxColumns;
this._row = -1;
this._column = -1;
}
isGatherString() {
return false;
}
nextCell() {
this._column++;
if (this._column < this.maxColumns) {
return this._column;
} else {
this._column = -1;
return -1;
}
}
nextRow() {
this._row++;
if (this._row < this.maxRows) {
this._column = -1;
return this._row;
} else {
return -1;
}
}
startCell(cell) {
cell.putValue(this._row + this._column);
if (this._row !== 1) {
cell.setFormula("=Rand() + A2");
}
}
startRow(row) {
}
startSheet(sheetIndex) {
return sheetIndex === 0;
}
}
const run = async () => {
const dataDir = path.join(__dirname, "data");
const rowsCount = 10000;
const colsCount = 30;
const workbook = new AsposeCells.Workbook();
const ooxmlSaveOptions = new AsposeCells.OoxmlSaveOptions();
ooxmlSaveOptions.setLightCellsDataProvider(new TestDataProvider(workbook, rowsCount, colsCount));
await workbook.saveAsync(path.join(dataDir, "output.out.xlsx"), ooxmlSaveOptions);
};
run();
Чтение больших файлов Excel
Aspose.Cells предоставляет интерфейс LightCellsDataHandler
, который необходимо реализовать в вашей программе. Этот интерфейс представляет поставщика данных для чтения больших файлов таблиц в легком режиме.
При чтении рабочей книги в этом режиме, при чтении каждого листа проверяется StartSheet
. Если он возвращает true, то все данные и свойства ячеек строк и столбцов этого листа проверяются и обрабатываются реализацией этого интерфейса. Для каждой строки вызывается StartRow
, чтобы определить, нужно ли её обрабатывать. Если строка должна обрабатываться, её свойства считываются сначала, и разработчик может получить доступ к её свойствам через ProcessRow
. Если ячейки строки также нужно обрабатывать, то ProcessRow
должен вернуть true, после чего для каждой существующей ячейки строки вызывается StartCell
, чтобы проверить, нужно ли её обрабатывать. Если ячейка должна обрабатываться, вызывается ProcessCell
для обработки ячейки этим интерфейсом.
Чтение больших Excel-файлов: пример
Пожалуйста, ознакомьтесь со следующим образцовым кодом, чтобы увидеть работу API LightCells. Добавьте, удалите или обновите сегменты кода в соответствии с вашими потребностями.
Программа читает огромный файл с миллионами записей в листе. Немного времени занимает чтение каждого листа в рабочей книге. В примере кода файл читается и определяется общее количество ячеек, количество строк и формул в каждом листе.
const AsposeCells = require("aspose.cells.node");
const path = require("path");
class LightCellsDataHandlerVisitCells {
constructor() {
this.cellCount = 0;
this.formulaCount = 0;
this.stringCount = 0;
}
get CellCount() {
return this.cellCount;
}
get FormulaCount() {
return this.formulaCount;
}
get StringCount() {
return this.stringCount;
}
StartSheet(sheet) {
console.log("Processing sheet[" + sheet.getName() + "]");
return true;
}
StartRow(rowIndex) {
return true;
}
ProcessRow(row) {
return true;
}
StartCell(column) {
return true;
}
ProcessCell(cell) {
this.cellCount++;
if (cell.isFormula()) {
this.formulaCount++;
} else if (cell.getType() === AsposeCells.CellValueType.IsString) {
this.stringCount++;
}
return false;
}
}
async function run() {
const dataDir = path.join(__dirname, "data");
const opts = new AsposeCells.LoadOptions();
const v = new LightCellsDataHandlerVisitCells();
opts.setLightCellsDataHandler(v);
const wb = new AsposeCells.Workbook(path.join(dataDir, "LargeBook1.xlsx"), opts);
const sheetCount = wb.getWorksheets().getCount();
console.log("Total sheets: " + sheetCount + ", cells: " + v.CellCount
+ ", strings: " + v.StringCount + ", formulas: " + v.FormulaCount);
}
run();