What is exceljs?
The exceljs npm package is a comprehensive library for reading, writing, and manipulating Excel files in various formats such as XLSX, CSV, and more. It provides a wide range of functionalities to work with Excel documents programmatically, including creating new sheets, styling cells, adding formulas, and handling large datasets efficiently.
What are exceljs's main functionalities?
Reading Excel Files
This feature allows you to read existing Excel files. You can iterate through rows and cells, access values, and perform operations based on the data.
{"const ExcelJS = require('exceljs');
const workbook = new ExcelJS.Workbook();
workbook.xlsx.readFile('path/to/file.xlsx')
.then(() => {
const worksheet = workbook.getWorksheet('Sheet1');
worksheet.eachRow({ includeEmpty: true }, (row, rowNumber) => {
console.log('Row ' + rowNumber + ' = ' + JSON.stringify(row.values));
});
});"}
Writing Excel Files
This feature enables you to create new Excel files or modify existing ones. You can add worksheets, rows, and cells with data, and save the file to the disk.
{"const ExcelJS = require('exceljs');
const workbook = new ExcelJS.Workbook();
const sheet = workbook.addWorksheet('My Sheet');
sheet.addRow(['Name', 'Profession']);
sheet.addRow(['John Doe', 'Developer']);
workbook.xlsx.writeFile('path/to/newfile.xlsx');"}
Styling Cells
This feature allows you to apply various styles to cells, such as fonts, colors, borders, and fills. It helps in making the data more readable and visually appealing.
{"const ExcelJS = require('exceljs');
const workbook = new ExcelJS.Workbook();
const sheet = workbook.addWorksheet('My Sheet');
const row = sheet.addRow(['Name', 'Profession']);
row.getCell(1).font = { bold: true };
row.getCell(2).fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFFF0000' }
};
workbook.xlsx.writeFile('path/to/styledfile.xlsx');"}
Adding Formulas
This feature lets you insert formulas into cells. You can also pre-calculate the result of the formula and store it in the cell.
{"const ExcelJS = require('exceljs');
const workbook = new ExcelJS.Workbook();
const sheet = workbook.addWorksheet('My Sheet');
const row = sheet.addRow([100, 200, { formula: 'A1+B1', result: 300 }]);
workbook.xlsx.writeFile('path/to/formulafile.xlsx');"}
Handling Large Data Sets
This feature is particularly useful for handling large datasets without running out of memory. It streams the data to the file system as it's being processed.
{"const ExcelJS = require('exceljs');
const workbook = new ExcelJS.stream.xlsx.WorkbookWriter({ filename: 'path/to/largefile.xlsx' });
const sheet = workbook.addWorksheet('My Sheet');
for (let i = 0; i < 1000000; i++) {
sheet.addRow(['Row ' + i, 'Data']);
}
workbook.commit();"}
Other packages similar to exceljs
xlsx
The 'xlsx' package is another popular library for parsing and writing various spreadsheet formats. It is known for its simplicity and small bundle size, but it may not offer as many features for styling and manipulating data as exceljs.
sheetjs
SheetJS, also known as 'xlsx', is a powerful and comprehensive library that supports a wide range of spreadsheet formats. It is similar to exceljs in functionality but differs in API design and implementation details.
node-xlsx
The 'node-xlsx' package is a simpler alternative for parsing and building XLSX/CSV files. It focuses on basic functionality and is easier to use for simple tasks, but lacks the advanced features and fine control provided by exceljs.
ExcelJS
Read, manipulate and write spreadsheet data and styles to XLSX and JSON.
Reverse engineered from Excel spreadsheet files as a project.
Installation
npm install exceljs
New Features!
-
Bug Fixes
- Now handles 10 or more worksheets in one workbook
- theme1.xml file properly added and referenced
- Cell Borders
Coming Soon
- Column and Row Styles
- Fills
Contents
Interface
var Excel = require("exceljs");
Create a Workbook
var workbook = new Excel.Workbook();
Add a Worksheet
var sheet = workbook.addWorksheet("My Sheet");
Access Worksheets
workbook.eachSheet(function(worksheet, sheetId) {
});
var worksheet = workbook.getWorksheet("My Sheet");
var worksheet = workbook.getWorksheet(1);
Columns
worksheet.columns = [
{ header: "Id", key: "id", width: 10 },
{ header: "Name", key: "name", width: 32 },
{ header: "D.O.B.", key: "DOB", width: 10 }
];
var idCol = worksheet.getColumn("id");
var nameCol = worksheet.getColumn("B");
var dobCol = worksheet.getColumn(3);
dobCol.header = "Date of Birth";
dobCol.header = ["Date of Birth", "A.K.A. D.O.B."];
dobCol.key = "dob";
dobCol.width = 15;
Rows
worksheet.addRow({id: 1, name: "John Doe", dob: new Date(1970,1,1)});
worksheet.addRow({id: 2, name: "Jane Doe", dob: new Date(1965,1,7)});
worksheet.addRow([3, "Sam", new Date()]);
var rowValues = [];
rowValues[1] = 4;
rowValues[5] = "Kyle";
rowValues[9] = new Date();
worksheet.addRow(rowValues);
var row = worksheet.getRow(5);
row.height = 42.5;
row.getCell(1).value = 5;
row.getCell("name").value = "Zeb";
row.getCell("C").value = new Date();
row = worksheet.getRow(4).values;
expect(row[5]).toEqual("Kyle");
row.values = [1,2,3];
expect(row.getCell(1).value).toEqual(1);
expect(row.getCell(2).value).toEqual(2);
expect(row.getCell(3).value).toEqual(3);
var values = []
values[5] = 7;
values[10] = "Hello, World!";
row.values = values;
expect(row.getCell(1).value).toBeNull();
expect(row.getCell(5).value).toEqual(7);
expect(row.getCell(10).value).toEqual("Hello, World!");
row.values = {
id: 13,
name: "Thing 1",
dob: new Date()
};
worksheet.eachRow(function(row, rowNumber) {
console.log("Row " + rowNumber + " = " + JSON.stringify(row.values));
});
row.eachCell(function(cell, colNumber) {
console.log("Cell " + colNumber + " = " + cell.value);
});
## Handling Individual Cells
```javascript
// Modify/Add individual cell
worksheet.getCell("C3").value = new Date(1968, 5, 1);
// query a cell's type
expect(worksheet.getCell("C3").type).toEqual(Excel.ValueType.Date);
Merged Cells
worksheet.mergeCells("A4:B5");
worksheet.mergeCells("G10", "H11");
worksheet.mergeCells(10,11,12,13);
worksheet.getCell("B5").value = "Hello, World!";
expect(worksheet.getCell("A4").value).toBe(worksheet.getCell("B5").value);
expect(worksheet.getCell("A4")).toBe(worksheet.getCell("B5").master);
Cell Styles
Number Formats
ws.getCell("A1").value = 1.6;
ws.getCell("A1").numFmt = "# ?/?";
ws.getCell("B1").value = 0.016;
ws.getCell("B1").numFmt = "0.00%";
Fonts
ws.getCell("A1").font = {
name: "Comic Sans MS",
family: 4,
size: 16,
underline: true,
bold: true
};
ws.getCell("A2").font = {
name: "Arial Black",
color: { argb: "FF00FF00" },
family: 2,
size: 14,
italic: true
};
var font = { name: "Arial", size: 12 };
ws.getCell("A3").font = font;
font.size = 20;
Font Property | Description | Example Value(s) |
---|
name | Font name. | "Arial", "Calibri", etc. |
family | Font family. An integer value. | 1,2,3, etc. |
scheme | Font scheme. | "minor", "major", "none" |
charset | Font charset. An integer value. | 1, 2, etc. |
color | Colour description, an object containing an ARGB value. | { argb: "FFFF0000"} |
bold | Font weight | true, false |
italic | Font slope | true, false |
underline | Font underline style | true, false, "none", "single", "double", "singleAccounting", "doubleAccounting" |
strike | Font strikethrough | true, false |
outline | Font outline | true, false |
Alignment
ws.getCell("A1").alignment = { vertical: "top", horizontal: "left" };
ws.getCell("B1").alignment = { vertical: "middle", horizontal: "center" };
ws.getCell("C1").alignment = { vertical: "bottom", horizontal: "right" };
ws.getCell("D1").alignment = { wrapText: true };
ws.getCell("E1").alignment = { indent: 1 };
ws.getCell("F1").alignment = { textRotation: 30 };
ws.getCell("G1").alignment = { textRotation: -45 };
ws.getCell("H1").alignment = { textRotation: "vertical" };
Valid Alignment Property Values
horizontal | vertical | wrapText | indent | readingOrder | textRotation |
---|
left | top | true | integer | rtl | 0 to 90 |
center | middle | false | | ltr | -1 to -90 |
right | bottom | | | | vertical |
fill | distributed | | | | |
justify | justify | | | | |
centerContinuous | | | | | |
distributed | | | | | |
Borders
// set single thin border around A1
ws.getCell("A1").border = {
top: {style:"thin"},
left: {style:"thin"},
bottom: {style:"thin"},
right: {style:"thin"}
};
// set double thin green border around A3
ws.getCell("A3").border = {
top: {style:"double", color: {argb:"FF00FF00"}},
left: {style:"double", color: {argb:"FF00FF00"}},
bottom: {style:"double", color: {argb:"FF00FF00"}},
right: {style:"double", color: {argb:"FF00FF00"}}
};
// set thick red cross in A5
ws.getCell("A5").border = {
diagonal: {up: true, down: true, style:"thick", color: {argb:"FFFF0000"}}
};
Valid Border Styles
- thin
- dotted
- dashDot
- hair
- dashDotDot
- slantDashDot
- mediumDashed
- mediumDashDotDot
- mediumDashDot
- medium
- double
- thick
Reading XLSX
var workbook = new Excel.Workbook();
workbook.xlsx.readFile(filename)
.then(function() {
});
var workbook = new Excel.Workbook();
stream.pipe(workbook.xlsx.createInputStream());
Writing XLSX
var workbook = createAndFillWorkbook();
workbook.xlsx.writeFile(filename)
.then(function() {
});
workbook.xlsx.write(stream)
.then(function() {
});
Value Types
The following value types are supported.
Enum Name | Enum(*) | Description | Example Value |
---|
Excel.ValueType.Null | 0 | No value. | null |
Excel.ValueType.Merge | 1 | N/A | N/A |
Excel.ValueType.Number | 2 | A numerical value | 3.14 |
Excel.ValueType.String | 3 | A text value | "Hello, World!" |
Excel.ValueType.Date | 4 | A Date value | new Date() |
Excel.ValueType.Hyperlink | 5 | A hyperlink | { text: "www.mylink.com", hyperlink: "http://www.mylink.com" } |
Excel.ValueType.Formula | 6 | A formula | { formula: "A1+A2", result: 7 } |
Release History
Version | Changes |
---|
0.0.9 | |
0.1.0 | |
0.1.1 | - Bug Fixes
- More textual data written properly to xml (including text, hyperlinks, formula results and format codes)
- Better date format code recognition
- Cell Font Style
|
0.1.2 | - Fixed potential race condition on zip write
|
0.1.3 | |
0.1.4 | - Bug Fixes
- Now handles 10 or more worksheets in one workbook
- theme1.xml file properly added and referenced
- Cell Borders
|
Interface Changes
Every effort is made to make a good consistent interface that doesn't break through the versions but regrettably, now and then some things have to change for the greater good.
Interface Breaks in 0.1.0
Worksheet.eachRow
The arguments in the callback function to Worksheet.eachRow have been swapped and changed; it was function(rowNumber,rowValues), now it is function(row, rowNumber) which gives it a look and feel more like the underscore (_.each) function and prioritises the row object over the row number.
Worksheet.getRow
This function has changed from returning a sparse array of cell values to returning a Row object. This enables accessing row properties and will facilitate managing row styles and so on.
The sparse array of cell values is still available via Worksheet.getRow(rowNumber).values;
Interface Breaks in 0.1.1
cell.model
cell.styles renamed to cell.style