Chapter 14 - Excel Spreadsheets (JavaScript)
Here's a JavaScript-flavoured version of the same concepts, with small JS/Node examples for each idea using the xlsx (SheetJS) package.
Intro and setup
- Goal: use
xlsx(SheetJS) to read/write.xlsxfiles, automating repetitive spreadsheet tasks from Node.js. - Like
openpyxl,xlsxworks on files, not the live Excel app. - Install with
npm install xlsx.
const XLSX = require("xlsx");
Reading Excel files
Workbooks, sheets, cells
Same structure: a workbook contains sheets, each sheet has columns (A, B, ...) and rows (1, 2, ...), and a cell is identified by address like B3.
Opening a workbook
const XLSX = require("xlsx");
const wb = XLSX.readFile("example3.xlsx");
console.log(typeof wb); // 'object'
Getting sheets from the workbook
console.log(wb.SheetNames); // ['Sheet1', 'Sheet2', 'Sheet3']
const sheet = wb.Sheets["Sheet1"]; // sheet object
wb.SheetNames is an array of names; wb.Sheets[name] gives the sheet object.
Getting cells from a sheet
const XLSX = require("xlsx");
const wb = XLSX.readFile("example3.xlsx");
const sheet = wb.Sheets["Sheet1"];
console.log(sheet["A1"].v); // cell value (e.g. date serial number)
console.log(sheet["B1"].v); // 'Apples'
console.log(sheet["C1"].v); // 73
Cell objects have .v (raw value), .w (formatted text), .t (type: 's' string, 'n' number, 'd' date).
You can also convert to a 2D array or JSON:
const data = XLSX.utils.sheet_to_json(sheet, { header: 1 });
console.log(data[0]); // ['2035-04-05...', 'Apples', 73]
Size of the used area
const range = XLSX.utils.decode_range(sheet["!ref"]);
console.log(range.e.r + 1); // max row (1-based)
console.log(range.e.c + 1); // max column (1-based)
Converting between column letters and numbers
const XLSX = require("xlsx");
console.log(XLSX.utils.encode_col(0)); // 'A' (0-based)
console.log(XLSX.utils.encode_col(26)); // 'AA'
console.log(XLSX.utils.decode_col("A")); // 0
console.log(XLSX.utils.decode_col("AA")); // 26
Note: SheetJS uses 0-based column indices internally.
Getting ranges as JSON
const rows = XLSX.utils.sheet_to_json(sheet);
for (const row of rows) {
console.log(row); // { Date: ..., Fruit: 'Apples', Quantity: 73 }
}
sheet_to_json uses the first row as headers by default.
Review checklist
To read a cell:
const XLSX = require("xlsx")const wb = XLSX.readFile(...)- Get sheet via
wb.Sheets[name] - Access cell via
sheet["B3"].vor convert to JSON withXLSX.utils.sheet_to_json(sheet)
Project: Gather Census Statistics
Same task: from a census spreadsheet, count tracts and total population per county.
const XLSX = require("xlsx");
const fs = require("fs");
const wb = XLSX.readFile("censuspopdata.xlsx");
const sheet = wb.Sheets["Population by Census Tract"];
const rows = XLSX.utils.sheet_to_json(sheet);
const countyData = {};
for (const row of rows) {
const state = row["State"]; // column header names
const county = row["County"];
const pop = row["Population"];
countyData[state] ??= {};
countyData[state][county] ??= { tracts: 0, pop: 0 };
countyData[state][county].tracts += 1;
countyData[state][county].pop += Number(pop);
}
fs.writeFileSync(
"census2010.json",
JSON.stringify(countyData, null, 2)
);
console.log("Done.");
Use ??= (nullish coalescing assignment) to ensure nested objects exist — equivalent to Python's setdefault.
Later:
const data = JSON.parse(fs.readFileSync("census2010.json", "utf-8"));
const anchorage = data["AK"]["Anchorage"];
console.log(anchorage.pop, anchorage.tracts);
Writing Excel documents
Creating and saving workbooks
const XLSX = require("xlsx");
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet([["Hello", "World"]]);
XLSX.utils.book_append_sheet(wb, ws, "Spam Bacon Eggs Sheet");
XLSX.writeFile(wb, "example_new.xlsx");
aoa_to_sheet converts a 2D array (array of arrays) into a sheet object.
Creating sheets with data
const XLSX = require("xlsx");
const wb = XLSX.utils.book_new();
const data = [
["Name", "Age"],
["Alice", 30],
["Bob", 25],
];
const ws = XLSX.utils.aoa_to_sheet(data);
XLSX.utils.book_append_sheet(wb, ws, "People");
XLSX.writeFile(wb, "people.xlsx");
Writing values to specific cells
const XLSX = require("xlsx");
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet([]);
XLSX.utils.book_append_sheet(wb, ws, "Sheet");
ws["A1"] = { v: "Hello, world!", t: "s" };
ws["!ref"] = "A1:A1"; // update range
XLSX.writeFile(wb, "hello.xlsx");
Or build from a 2D array and let SheetJS handle cell references automatically.
Project: Update a Spreadsheet
Same task: fix incorrect prices in a produce sales spreadsheet.
const XLSX = require("xlsx");
const wb = XLSX.readFile("produceSales3.xlsx");
const sheet = wb.Sheets["Sheet"];
const rows = XLSX.utils.sheet_to_json(sheet);
const PRICE_UPDATES = {
Garlic: 3.07,
Celery: 1.19,
Lemon: 1.27,
};
// Find the range to iterate cells directly
const range = XLSX.utils.decode_range(sheet["!ref"]);
for (let r = 1; r <= range.e.r; r++) { // skip header (row 0)
const nameCell = sheet[XLSX.utils.encode_cell({ r, c: 0 })]; // column A
const priceCell = XLSX.utils.encode_cell({ r, c: 1 }); // column B
if (nameCell && PRICE_UPDATES[nameCell.v] !== undefined) {
sheet[priceCell] = { v: PRICE_UPDATES[nameCell.v], t: "n" };
}
}
XLSX.writeFile(wb, "updatedProduceSales3.xlsx");
Styling cells: fonts
SheetJS Community Edition has limited styling. For full styling support, use xlsx-style or exceljs:
npm install exceljs
const ExcelJS = require("exceljs");
const wb = new ExcelJS.Workbook();
const ws = wb.addWorksheet("Sheet");
ws.getCell("A1").value = "Hello, world!";
ws.getCell("A1").font = { size: 24, italic: true };
ws.getCell("A3").value = "Bold Times New Roman";
ws.getCell("A3").font = { name: "Times New Roman", bold: true };
await wb.xlsx.writeFile("styles3.xlsx");
Useful font properties: name, size, bold, italic — same as Python's Font keyword args.
Formulas
SheetJS can write formula cells; Excel calculates them when opened.
const XLSX = require("xlsx");
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet([]);
XLSX.utils.book_append_sheet(wb, ws, "Sheet");
ws["A1"] = { v: 200, t: "n" };
ws["A2"] = { v: 300, t: "n" };
ws["A3"] = { f: "SUM(A1:A2)" }; // 'f' for formula
ws["!ref"] = "A1:A3";
XLSX.writeFile(wb, "writeFormula3.xlsx");
The f property holds the formula string (without the = prefix). SheetJS does not evaluate formulas — Excel does when you open the file.
Overall idea of the chapter
Chapter 14 shows how to automate Excel tasks from JavaScript: reading workbooks/sheets/cells with xlsx (SheetJS), building data structures from rows, writing and updating cells, and writing formulas. For styling, exceljs provides full font/color support. The key pattern is the same: load workbook → loop rows → read or write cells → save.