Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .config/webpack/development.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,30 @@ module.exports.create = function create() {
commonjs: 'tiny-emitter',
amd: 'tiny-emitter',
},
exceljs: {
root: 'ExcelJS',
commonjs2: 'exceljs',
commonjs: 'exceljs',
amd: 'exceljs',
},
};
c.plugins.push(new WebpackBar({ name: ` ${PACKAGE_FILENAME}.js` }));
});

configFull.forEach(function(c) {
c.output.filename = `${PACKAGE_FILENAME}.full.js`;
// The 'full' bundle inlines HyperFormula's own dependencies, but exceljs is
// kept external: it is large and its transitive licenses would break the
// single-preamble bundle invariant. xlsx import/export in the UMD 'full'
// build therefore requires providing exceljs (global `ExcelJS`) separately.
c.externals = {
exceljs: {
root: 'ExcelJS',
commonjs2: 'exceljs',
commonjs: 'exceljs',
amd: 'exceljs',
},
};
c.plugins.push(new WebpackBar({ name: ` ${PACKAGE_FILENAME}.full.js` }));
});

Expand Down
134 changes: 93 additions & 41 deletions docs/guide/file-import.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,121 @@
# File import
# File import and export

Import XLSX and CSV files into HyperFormula.
Import and export XLSX files, and import CSV files, with HyperFormula.

## Overview

HyperFormula has no built-in file import functionality. But its [factory methods](../api/classes/hyperformula.md#factories) use standard JavaScript data types, for easy integration with any way of importing data.

## Import CSV files

To import CSV files, use a third-party [CSV parser](https://www.npmjs.com/search?q=csv) (e.g., [PapaParse](https://www.npmjs.com/package/papaparse) or [csv-parse](https://www.npmjs.com/package/csv-parse)). Then pass the result to HyperFormula as a JavaScript array.
HyperFormula can import and export `.xlsx` files out of the box, using the
[ExcelJS](https://www.npmjs.com/package/exceljs) library under the hood. Import
with the [`buildFromFile`](../api/classes/hyperformula.md#buildfromfile) factory
method and export with the [`toFile`](../api/classes/hyperformula.md#tofile)
method.

For any other format (for example CSV), HyperFormula's
[factory methods](../api/classes/hyperformula.md#factories) accept standard
JavaScript arrays, so you can plug in any third-party parser.

::: tip
Only **cell values and formulas** are imported and exported. Cell styling,
number formats, merged cells, charts, images, data validation, and other
Excel-specific features are **not** preserved — HyperFormula stores only
values and formulas. Formula import assumes the English (`en`) function dialect.
On export, formulas that use newer or dynamic-array Excel functions are written
without Excel's internal `_xlfn.` prefix, so they may not resolve when the
exported file is opened in real Excel.
:::

## Import XLSX files

To import XLSX files, use a third-party [XLSX parser](https://www.npmjs.com/search?q=xlsx) (e.g., [ExcelJS](https://www.npmjs.com/package/exceljs) or [xlsx](https://www.npmjs.com/package/xlsx)). Then pass the result to HyperFormula as a JavaScript array.

### Example: Import XLSX files in Node

This example uses [ExcelJS](https://www.npmjs.com/package/exceljs) to import XLSX files into HyperFormula.
Pass the file's bytes (an `ArrayBuffer` or `Uint8Array`) to the asynchronous
[`buildFromFile`](../api/classes/hyperformula.md#buildfromfile) factory method.
Reading the file itself is left to your environment, so the same API works in
both Node.js and the browser.

See full example on [GitHub](https://github.com/handsontable/hyperformula-demos/tree/3.1.x/read-excel-file).
### In Node.js

```js
const ExcelJS = require('exceljs');
const fs = require('fs');
const { HyperFormula } = require('hyperformula');

async function run(filename) {
const xlsxWorkbook = await readXlsxWorkbookFromFile(filename);
const sheetsAsJavascriptArrays = convertXlsxWorkbookToJavascriptArrays(xlsxWorkbook)
const hf = HyperFormula.buildFromSheets(sheetsAsJavascriptArrays, { licenseKey: 'gpl-v3' });
async function importXlsx(filePath) {
const data = fs.readFileSync(filePath); // a Buffer (a Uint8Array)
const hf = await HyperFormula.buildFromFile(data, { licenseKey: 'gpl-v3' });

console.log('Formulas:', hf.getSheetSerialized(0));
console.log('Values: ', hf.getSheetValues(0));
}

async function readXlsxWorkbookFromFile(filename) {
const workbook = new ExcelJS.Workbook();
await workbook.xlsx.readFile(filename);
return workbook;
return hf;
}
```

### In the browser

```js
import { HyperFormula } from 'hyperformula';

function convertXlsxWorkbookToJavascriptArrays(workbook) {
const workbookData = {};
// `file` is a File obtained from an <input type="file"> element.
async function importXlsx(file) {
const data = await file.arrayBuffer(); // an ArrayBuffer
const hf = await HyperFormula.buildFromFile(data, { licenseKey: 'gpl-v3' });

workbook.eachSheet((worksheet) => {
const sheetDimensions = worksheet.dimensions
const sheetData = [];
return hf;
}
```

for (let rowNum = sheetDimensions.top; rowNum <= sheetDimensions.bottom; rowNum++) {
const rowData = [];
If the bytes cannot be read as an `.xlsx` file, `buildFromFile` rejects with an
[`UnsupportedFileError`](../api/classes/unsupportedfileerror.md).

for (let colNum = sheetDimensions.left; colNum <= sheetDimensions.right; colNum++) {
const cell = worksheet.getCell(rowNum, colNum)
## Export XLSX files

const cellData = cell.formula ? `=${cell.formula}` : cell.value;
rowData.push(cellData);
}
The asynchronous [`toFile`](../api/classes/hyperformula.md#tofile) method returns
the workbook's bytes as a `Uint8Array`. Writing those bytes is left to your
environment.

sheetData.push(rowData);
}
### In Node.js

workbookData[worksheet.name] = sheetData;
})
```js
const fs = require('fs');

return workbookData;
async function exportXlsx(hf, filePath) {
const bytes = await hf.toFile();
fs.writeFileSync(filePath, bytes);
}
```

### In the browser

run('sample_file.xlsx');
```js
async function downloadXlsx(hf, fileName) {
const bytes = await hf.toFile();
const blob = new Blob([bytes], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});

const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
link.click();
URL.revokeObjectURL(url);
}
```

## Import CSV files

HyperFormula has no built-in CSV parser. Use a third-party
[CSV parser](https://www.npmjs.com/search?q=csv) (e.g.,
[PapaParse](https://www.npmjs.com/package/papaparse) or
[csv-parse](https://www.npmjs.com/package/csv-parse)), then pass the resulting
array to [`buildFromArray`](../api/classes/hyperformula.md#buildfromarray).

## Advanced: custom XLSX handling

If you need control over how the workbook is read or written (for example, to
read cached values instead of formulas, or to handle Excel features outside
HyperFormula's value-and-formula model), parse the file yourself with a
third-party [XLSX parser](https://www.npmjs.com/search?q=xlsx) such as
[ExcelJS](https://www.npmjs.com/package/exceljs) or
[xlsx](https://www.npmjs.com/package/xlsx), convert the result to JavaScript
arrays, and pass them to
[`buildFromSheets`](../api/classes/hyperformula.md#buildfromsheets). See a full
example on [GitHub](https://github.com/handsontable/hyperformula-demos/tree/3.1.x/read-excel-file).
Loading
Loading