Guide to ExcelJS: An Excel Workbook Manager

ExcelJS is a helpful JavaScript package that acts as an Excel workbook manager. This guide will help you read, manipulate and write spreadsheet data to XLSX and JSON.

Written by Wai Foong Ng
Published on Dec. 21, 2022
Guide to ExcelJS: An Excel Workbook Manager
Image: Shutterstock / Built In
Brand Studio Logo

ExcelJS is a JavaScript package that acts as an Excel workbook manager. exceljs can read, manipulate and write spreadsheet data and styles to XLSX and JSON, according to its official documentation. It’s reverse-engineered from Excel spreadsheet files as a project.

It’s an extremely useful package that allows you to do the following:

  • Creating a workbook.
  • Creating a worksheet.
  • Handling headers and footers.
  • Setting frozen or split views.
  • Setting auto filters.
  • Data manipulation on rows and columns.
  • Adding data validation.
  • Adding styles.
  • Inserting images to a workbook.

In addition, exceljs is frequently updated and available for free. This tutorial covers the step-by-step installation process and a few examples of some of the most basic and commonly used features. Also, code snippets will be provided as reference to the readers.

What Is ExcelJS?

ExcelJS is a JavaScript package that works as an Excel workbook manager. It can read, manipulate and write spreadsheet data and styles to XLSX and JSON.  

Let’s proceed to the next section and start installing exceljs.


How to Install ExcelJS

The recommended installation process is via npm, which mainly works for node.js projects. If you intend to use it directly within a browser for a project outside of node.js, you have to import the package using the official content delivery network (CDN) link. Let’s have a look at the installation process for both methods.

More on JavaScript8 Common JavasScript Data Structures



Run the following command to install npm in your project:

npm install exceljs

Then, import it as follows:

const ExcelJS = require('exceljs');

For a node.js that is more than 10 years old, you have to import using ES5 transpiled code. Also, you need to import a few polyfills, as well:

// polyfills required by exceljs

const ExcelJS = require('exceljs/dist/es5');



For using it directly on your browser, simply head over to the official CDN page for ExcelJS and copy the corresponding script tag based on your needs:

For example, you can use the following script tag inside your HTML file:

src="" integrity="sha512-UnrKxsCMN9hFk7M56t4I4ckB4N/2HHi0w/7+B/1JsXIX3DmyBcsGpT3/BsuZMZf+6mAr0vP81syWtfynHJ69JA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>



Some of the features in exceljs are highly dependent on node.js built-in packages. For example, the save file functionality requires the fs module. This will throw an error when you call it within a non-node.js project.

Having said that, you can still utilize the file saving feature with just a few additional tricks. All you need to do is output the binary data as a buffer and save it using an external JavaScript library, such as FileSaver.js. Head over to the repository and copy the script tag based on your use cases.

Then, insert the script tag in your HTML as follows:

src="" integrity="sha512-Qlv6VSKh1gDKGoJbnyA5RMXYcvnpIqhO++MhIM2fStMcGT9i2T//tSwYFlcyoRRDcDZ+TYHpH8azBBCyhpSeqw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>


How to Use ExcelJS

In this section, you will learn the fundamentals concepts and the basics behind exceljs.


Creating a New Workbook

Let’s start by creating a new workbook, as follows:

const workbook = new ExcelJS.Workbook();


Workbook Properties

Once you have a workbook, you can play around with some of its properties:

workbook.creator = 'Ng Wai Foong';
workbook.lastModifiedBy = 'Bot';
workbook.created = new Date(2021, 8, 30);
workbook.modified = new Date();
workbook.lastPrinted = new Date(2021, 7, 27);


Adding a New Worksheet

Next, you can add a new worksheet to the workbook that you created earlier via the following code:

const worksheet = workbook.addWorksheet('New Sheet');


Worksheet Settings

You can initialize some configurations for your sheet as well by passing in an object:

// red tab colour
const worksheet = workbook.addWorksheet('New Sheet', {properties:{tabColor:{argb:'FFC0000'}}});

// hide grid lines
const worksheet = workbook.addWorksheet('New Sheet', {views: [{showGridLines: false}]});

// freeze first row and column
const worksheet = workbook.addWorksheet('New Sheet', {views:[{state: 'frozen', xSplit: 1, ySplit:1}]});

// pageSetup settings for A4 - landscape
const worksheet =  workbook.addWorksheet('New Sheet', {
  pageSetup:{paperSize: 9, orientation:'landscape'}

// headers and footers
const worksheet = workbook.addWorksheet('New Sheet', {
  headerFooter: {oddFooter: "Page &P of &N";, oddHeader: 'Odd Page'}

You can also set the configurations manually after you have initialized the worksheet object. For example, you can set a footer for odd pages, as follows:

//Set footer (default centered), result: "Page 2 of 16"
worksheet.headerFooter.oddFooter = "Page &P of &N";

&P and &N are part of the script commands


How to Set Auto Filters in ExcelJS

Moreover, there is support for auto filters as well. The following code snippet allows you to set an auto filter from A1 to C1:

worksheet.autoFilter = 'A1:C1';

You can use the following code instead, which is a lot more explicit compared to the standard form:

worksheet.autoFilter = {
 from: 'A1',
 to: 'C1',


Creating Columns

It’s good practice to set the columns with the corresponding mapping header and key.

worksheet.columns = [
 { header: 'Id', key: 'id' },
 { header: 'Name', key: 'name' },
 { header: 'Age', key: 'age' }

Header represents the text that will be displayed, while key represents the property name mapping when you add a new row using an object. Please note that the order is important, as it will affect the final output when you save the workbook as an excel file.


Accessing a Column

You can access each column individually via:

  • key: The mapping key declared when creating the column (ID, name, age, etc.).
  • letter: The corresponding letter for the column (A, B, C, etc.).
  • column number: Index number (starts from one).
const idCol = worksheet.getColumn('id');
const nameCol = worksheet.getColumn('B');
const ageCol = worksheet.getColumn(3);


Iterating Each Cell

You can easily iterate all current cells in the column that is not empty:

ageCol.eachCell(function(cell, rowNumber) {


If you want to iterate over empty cells, simply set the includeEmpty property to true as follows:

dobCol.eachCell({ includeEmpty: true }, function(cell, rowNumber) {


How to Add a Row in ExcelJS

Once you have declared the corresponding columns, you can start to add data to it by calling the addRow function. There are multiple ways to add a row to the worksheet.


Adding a New Row Using Key-Value Object

For example, you can pass in key-value object that matched the header columns:

const row = worksheet.addRow({id: 1, name: 'John Doe', age: 35});


Adding a New Row Using Array

You can use an array as well to add new data. It will assign to the columns in order (A, B, C):

const row = worksheet.addRow([2, 'Mary Sue', 22]);


Adding Rows of Data

In addition, you can call addRows function and pass in an array of row objects instead. This allows you to add rows of data with just a single line of code:

const rows = [
 {id:4, name: 'Margaret', age: 32}


Adding Page Break

There is also a function called addPageBreak that adds a new page break below the row. You can call it as follows:



Iterating Each Row

You can easily go through each row by utilizing eachRow function on your worksheet:

worksheet.eachRow(function(row, rowNumber) {


Iterating Each Cell

Similar to column, you can iterate over each cell of the row via the following

row.eachCell(function(cell, colNumber) {



There are a few built-in metrics for getting the number of rows and total number of cells:

const rowSize = row.cellCount;
const numValues = row.actualCellCount;


Data Validation

You can easily incorporate data validation to your worksheet programmatically via dataValidation. For example, you can set a dropdown with a list of values via the following code:

worksheet.getCell('A1').dataValidation = {
 type: 'list',
 allowBlank: true,
 formulae: ['"One,Two,Three,Four"']

Here’s another example that limits the input to be in between 2.5 and seven. You can add a tooltip message to guide the users by setting the prompt property.

worksheet.getCell('A1').dataValidation = {
 type: 'decimal',
 operator: 'between',
 allowBlank: true,
 showInputMessage: true,
 formulae: [2.5, 7],
 promptTitle: 'Decimal',
 prompt: 'The value must between 2.5 and 7'


Styling in ExcelJS

exceljs supports a rich set of styling and formatting for cells, rows and columns. It comes with the following properties:

  • numFmt
  • font
  • alignment
  • border
  • fill



You can easily format the number, as follows:

// display value as '1 3/5'
worksheet.getCell('A1').value = 1.6;
worksheet.getCell('A1').numFmt = '# ?/?';
// display value as '1.60%'
worksheet.getCell('B1').value = 0.016;
worksheet.getCell('B1').numFmt = '0.00%';

With the exception of numFmt, which accepts a string, the rest of the style takes in a JavaScript object.



For example, you can set the font via the following code snippet:

worksheet.getCell('A1').font = {
 name: 'Arial Black',
 color: { argb: 'FF00FF00' },
 family: 2,
 size: 14,
 italic: true



On the other hand, you can easily set the alignment to top right, as follows:

worksheet.getCell('A1').alignment = { vertical: 'top', horizontal: 'left' };
You can also set alignment for text wrapping and indentation via the following code:
// set cell wrap-text
worksheet.getCell('A1').alignment = { wrapText: true };
// set cell indent to 1
worksheet.getCell('A1').alignment = { indent: 1 };



To style the border of a cell based on your desired color, use the following code instead:

worksheet.getCell('A1').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'}}

The underlying style property accepts the following:

  • thin
  • dotted
  • dashDot
  • hair
  • dashDotDot
  • slantDashDot
  • mediumDashed
  • mediumDashDotDot
  • mediumDashDot
  • medium
  • double
  • thick



For filling a particular cell, simply pass in an object with the following property:

worksheet.getCell('A1').fill = {
 type: 'pattern',

fgColor refers to the foreground color, while bgColor refers to the back end color.

The complete list for pattern types is as follows:

  • none
  • solid
  • darkGray
  • mediumGray
  • lightGray
  • gray125
  • gray0625
  • darkHorizontal
  • darkVertical
  • darkDown
  • darkUp
  • darkGrid
  • darkTrellis
  • lightHorizontal
  • lightVertical
  • lightDown
  • lightUp
  • lightGrid
  • lightTrellis



Please note that when you set a specific style to a row or column, exceljs will internally apply the same style to all existing cells in that row or column. Newly created cells will inherit the style as well.

As a result,it’s recommended to add cells before you set the style. The following code snippet illustrates an example of setting all the headers to bold after cells creation:

// arrayObj is an array of objects
worksheet.getRow(1).font = { bold: true };


File I/O

exceljs provides a few helper functions for reading and loading a file depending on the use cases. Generally, it’s categorized into:

  • file
  • stream
  • buffer

Please note that File I/O related operations return a Promise and have to be called together with the await keyword. If you are using it inside a function, make sure to set the function to async.



Assuming that you have a local excel file, you can perform reading and writing as follows:

// file reading
await workbook.xlsx.readFile(filename);
// file writing
await workbook.xlsx.writeFile(filename);



If you have a stream of data, use the following code snippet:

// stream reading
// stream writing
await workbook.xlsx.write(stream);



When dealing with buffer, you should call load and writeBuffer function instead:

// buffer reading
await workbook.xlsx.load(data);
// buffer writing
const buffer = await workbook.xlsx.writeBuffer();

Here’s an example of reading an uploaded excel file. fileList is a FileList object obtained from input tag. Simply instantiate a new binary large object (BLOB) and get the underlying buffer. Then, pass it to the load function as follows:

const blob = new Blob([fileList[0]], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' });
const buffer = await blob.arrayBuffer();

const workbook = new ExcelJS.Workbook();
await workbook.xlsx.load(buffer);
A tutorial on how to work with XLSX in JavaScript. | Video: Vincent Lab

More on JavaScriptJavaScript Call Stacks: An Introduction


File I/O for a Non-Node.js Project

As mentioned earlier, the read and write file functions rely on the fs module, which will throw an error if you’re using it on a browser. In order to resolve this, simply call the writeBuffer function and save the output buffer data into a BLOB. Then, save it using FileSaver.js.

const blob = new Blob([fileList[0]], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' });
const buffer = await blob.arrayBuffer();

const workbook = new ExcelJS.Workbook();
await workbook.xlsx.load(buffer);

Make sure you import the appropriate script tag for FileSaver.js. Check the installation section for more information on this.

Hiring Now
BAE Systems
Aerospace • Hardware • Information Technology • Security • Software • Cybersecurity • Defense