SheetJS Spreadsheet data parser and writer for multiple formats including Excel, CSV, and OpenDocument
Low-level utilities for working with individual cells, cell addresses, and ranges. These functions provide precise control over cell manipulation, address conversion, and value formatting.
Convert cell coordinates to Excel A1 notation for display and reference purposes.
/**
* Convert cell address object to A1 notation string
* @param cell - Cell address with row and column numbers
* @returns A1 notation string (e.g., "A1", "B5", "AA100")
*/
function encode_cell(cell: CellAddress): string;
/**
* Convert row number to A1 notation
* @param row - Row number (0-indexed)
* @returns Row string (e.g., "1", "5", "100")
*/
function encode_row(row: number): string;
/**
* Convert column number to A1 notation
* @param col - Column number (0-indexed)
* @returns Column string (e.g., "A", "B", "AA")
*/
function encode_col(col: number): string;
/**
* Convert range object to A1 notation string
* @param range - Range object with start and end addresses
* @returns A1 range string (e.g., "A1:C5", "B2:D10")
*/
function encode_range(range: Range): string;
/**
* Convert range coordinates to A1 notation string
* @param s - Start cell address
* @param e - End cell address
* @returns A1 range string
*/
function encode_range(s: CellAddress, e: CellAddress): string;Usage Examples:
import { utils } from "xlsx";
// Encode cell addresses
const cellA1 = utils.encode_cell({ r: 0, c: 0 }); // "A1"
const cellB5 = utils.encode_cell({ r: 4, c: 1 }); // "B5"
const cellAA100 = utils.encode_cell({ r: 99, c: 26 }); // "AA100"
// Encode rows and columns separately
const row10 = utils.encode_row(9); // "10" (0-indexed input)
const colZ = utils.encode_col(25); // "Z" (0-indexed input)
// Encode ranges
const range1 = utils.encode_range(
{ r: 0, c: 0 }, // A1
{ r: 4, c: 2 } // C5
); // "A1:C5"
const rangeObj = {
s: { r: 1, c: 1 }, // B2
e: { r: 9, c: 3 } // D10
};
const range2 = utils.encode_range(rangeObj); // "B2:D10"
// Dynamic range creation
function createDynamicRange(startRow: number, startCol: number, numRows: number, numCols: number) {
return utils.encode_range(
{ r: startRow, c: startCol },
{ r: startRow + numRows - 1, c: startCol + numCols - 1 }
);
}
const dynamicRange = createDynamicRange(0, 0, 10, 5); // "A1:E10"Convert Excel A1 notation strings back to numeric coordinates for programmatic access.
/**
* Convert A1 notation string to cell address object
* @param address - A1 notation string (e.g., "A1", "B5", "AA100")
* @returns CellAddress object with row and column numbers
*/
function decode_cell(address: string): CellAddress;
/**
* Convert A1 row string to number
* @param row - Row string (e.g., "1", "5", "100")
* @returns Row number (0-indexed)
*/
function decode_row(row: string): number;
/**
* Convert A1 column string to number
* @param col - Column string (e.g., "A", "B", "AA")
* @returns Column number (0-indexed)
*/
function decode_col(col: string): number;
/**
* Convert A1 range string to range object
* @param range - A1 range string (e.g., "A1:C5", "B2:D10")
* @returns Range object with start and end addresses
*/
function decode_range(range: string): Range;Usage Examples:
import { utils } from "xlsx";
// Decode cell addresses
const addr1 = utils.decode_cell("A1"); // { r: 0, c: 0 }
const addr2 = utils.decode_cell("B5"); // { r: 4, c: 1 }
const addr3 = utils.decode_cell("AA100"); // { r: 99, c: 26 }
// Decode rows and columns
const rowNum = utils.decode_row("10"); // 9 (0-indexed output)
const colNum = utils.decode_col("Z"); // 25 (0-indexed output)
// Decode ranges
const range1 = utils.decode_range("A1:C5");
// { s: { r: 0, c: 0 }, e: { r: 4, c: 2 } }
const range2 = utils.decode_range("B2:D10");
// { s: { r: 1, c: 1 }, e: { r: 9, c: 3 } }
// Use decoded addresses for cell access
const workbook = utils.book_new();
const worksheet = utils.aoa_to_sheet([["A", "B", "C"], [1, 2, 3]]);
const cellAddr = utils.decode_cell("B2");
const cellValue = worksheet[utils.encode_cell(cellAddr)];
console.log(cellValue?.v); // 2
// Range iteration
const range = utils.decode_range("A1:C2");
for (let r = range.s.r; r <= range.e.r; r++) {
for (let c = range.s.c; c <= range.e.c; c++) {
const cellRef = utils.encode_cell({ r, c });
const cell = worksheet[cellRef];
console.log(`${cellRef}: ${cell?.v}`);
}
}Format and display cell values according to number formats and display preferences.
/**
* Format cell value for display
* @param cell - Cell object to format
* @param v - Optional value override
* @param opts - Formatting options
* @returns Formatted string representation
*/
function format_cell(cell: CellObject, v?: any, opts?: any): string;
/**
* Set number format for a cell
* @param cell - Cell object to modify
* @param fmt - Number format string or format index
* @returns Modified cell object
*/
function cell_set_number_format(cell: CellObject, fmt: string | number): CellObject;Usage Examples:
import { utils } from "xlsx";
// Create sample cells
const numberCell: CellObject = { v: 1234.567, t: "n" };
const dateCell: CellObject = { v: new Date("2023-06-15"), t: "d" };
const percentCell: CellObject = { v: 0.1234, t: "n" };
// Basic formatting
const formatted1 = utils.format_cell(numberCell);
console.log(formatted1); // "1234.567"
// Set number formats
const currencyCell = utils.cell_set_number_format(numberCell, "$#,##0.00");
const formattedCurrency = utils.format_cell(currencyCell);
console.log(formattedCurrency); // "$1,234.57"
const percentFormatted = utils.cell_set_number_format(percentCell, "0.00%");
const formattedPercent = utils.format_cell(percentFormatted);
console.log(formattedPercent); // "12.34%"
const dateFormatted = utils.cell_set_number_format(dateCell, "mm/dd/yyyy");
const formattedDate = utils.format_cell(dateFormatted);
console.log(formattedDate); // "06/15/2023"
// Custom formatting with built-in format codes
const scientificCell = utils.cell_set_number_format(numberCell, "0.00E+00");
const timeCell = utils.cell_set_number_format(dateCell, "hh:mm:ss");
const fractionCell = utils.cell_set_number_format(numberCell, "# ?/?");Add hyperlinks and internal links to cells for navigation and external references.
/**
* Set external hyperlink for a cell
* @param cell - Cell object to modify
* @param target - URL or external reference
* @param tooltip - Optional tooltip text
* @returns Modified cell object with hyperlink
*/
function cell_set_hyperlink(cell: CellObject, target: string, tooltip?: string): CellObject;
/**
* Set internal workbook link for a cell
* @param cell - Cell object to modify
* @param target - Internal reference (sheet name, cell address)
* @param tooltip - Optional tooltip text
* @returns Modified cell object with internal link
*/
function cell_set_internal_link(cell: CellObject, target: string, tooltip?: string): CellObject;Usage Examples:
import { utils } from "xlsx";
// Create cells with text
const urlCell: CellObject = { v: "Visit Google", t: "s" };
const emailCell: CellObject = { v: "Contact Us", t: "s" };
const internalCell: CellObject = { v: "Go to Summary", t: "s" };
// Add external hyperlinks
const webLink = utils.cell_set_hyperlink(urlCell, "https://www.google.com", "Google Search");
const mailLink = utils.cell_set_hyperlink(emailCell, "mailto:support@example.com", "Send Email");
// Add internal links
const sheetLink = utils.cell_set_internal_link(internalCell, "Summary!A1", "Go to Summary Sheet");
const rangeLink = utils.cell_set_internal_link(internalCell, "Data!A1:C10", "View Data Range");
// Apply to worksheet
const worksheet = utils.aoa_to_sheet([
["Links Example"],
["Visit Google", "Contact Us", "Go to Summary"]
]);
// Set hyperlinks on specific cells
worksheet["A2"] = webLink;
worksheet["B2"] = mailLink;
worksheet["C2"] = sheetLink;
// Create workbook with linked worksheet
const workbook = utils.book_new();
utils.book_append_sheet(workbook, worksheet, "Links");
// Add summary sheet for internal link
const summarySheet = utils.aoa_to_sheet([["Summary Data"], ["Item 1"], ["Item 2"]]);
utils.book_append_sheet(workbook, summarySheet, "Summary");Add comments and annotations to cells for documentation and collaboration.
/**
* Add comment to a cell
* @param cell - Cell object to modify
* @param text - Comment text content
* @param author - Optional author name
*/
function cell_add_comment(cell: CellObject, text: string, author?: string): void;Usage Examples:
import { utils } from "xlsx";
// Create cells with data
const dataCell: CellObject = { v: 1000, t: "n" };
const formulaCell: CellObject = { v: 2000, t: "n", f: "SUM(A1:A10)" };
// Add comments
utils.cell_add_comment(dataCell, "This value was manually entered on 2023-06-15", "Alice");
utils.cell_add_comment(formulaCell, "Formula calculates total revenue\nLast updated: Q2 2023", "Bob");
// Create worksheet with commented cells
const worksheet = utils.aoa_to_sheet([
["Revenue Data"],
["Q1 Revenue", 1000],
["Q2 Revenue", 2000]
]);
// Apply commented cells
worksheet["B2"] = dataCell;
worksheet["B3"] = formulaCell;
// Comments are preserved in Excel output
const workbook = utils.book_new();
utils.book_append_sheet(workbook, worksheet, "Revenue");
// Comments will be visible when opening in Excel/SheetsWorking with cell ranges, iteration, and bulk operations.
import { utils, readFile } from "xlsx";
// Load existing workbook
const workbook = readFile("data.xlsx");
const worksheet = workbook.Sheets[workbook.SheetNames[0]];
// Get worksheet range
const wsRange = worksheet["!ref"];
console.log(`Worksheet range: ${wsRange}`); // e.g., "A1:E10"
if (wsRange) {
const range = utils.decode_range(wsRange);
// Iterate through all cells in range
for (let r = range.s.r; r <= range.e.r; r++) {
for (let c = range.s.c; c <= range.e.c; c++) {
const cellAddress = utils.encode_cell({ r, c });
const cell = worksheet[cellAddress];
if (cell) {
// Process cell
console.log(`${cellAddress}: ${cell.v} (type: ${cell.t})`);
// Apply formatting based on cell type
if (cell.t === "n" && cell.v > 1000) {
utils.cell_set_number_format(cell, "$#,##0.00");
} else if (cell.t === "d") {
utils.cell_set_number_format(cell, "mm/dd/yyyy");
}
}
}
}
}
// Find specific cells
function findCellsWithValue(worksheet: any, searchValue: any) {
const results: string[] = [];
const range = worksheet["!ref"];
if (range) {
const decodedRange = utils.decode_range(range);
for (let r = decodedRange.s.r; r <= decodedRange.e.r; r++) {
for (let c = decodedRange.s.c; c <= decodedRange.e.c; c++) {
const cellAddress = utils.encode_cell({ r, c });
const cell = worksheet[cellAddress];
if (cell && cell.v === searchValue) {
results.push(cellAddress);
}
}
}
}
return results;
}
// Usage
const matchingCells = findCellsWithValue(worksheet, "Total");
console.log(`Found "Total" in cells: ${matchingCells.join(", ")}`);Working with cell ranges for bulk operations and data analysis:
import { utils } from "xlsx";
// Create range utilities
function getCellsInRange(worksheet: any, rangeStr: string) {
const range = utils.decode_range(rangeStr);
const cells: any[] = [];
for (let r = range.s.r; r <= range.e.r; r++) {
for (let c = range.s.c; c <= range.e.c; c++) {
const cellAddress = utils.encode_cell({ r, c });
const cell = worksheet[cellAddress];
if (cell) {
cells.push({ address: cellAddress, ...cell });
}
}
}
return cells;
}
function sumRange(worksheet: any, rangeStr: string): number {
const cells = getCellsInRange(worksheet, rangeStr);
return cells
.filter(cell => cell.t === "n")
.reduce((sum, cell) => sum + (cell.v || 0), 0);
}
// Usage with actual worksheet
const workbook = utils.book_new();
const data = [
["Product", "Q1", "Q2", "Q3", "Q4"],
["Widget", 100, 150, 200, 175],
["Gadget", 80, 120, 160, 140],
["Tool", 60, 90, 110, 100]
];
const worksheet = utils.aoa_to_sheet(data);
// Calculate totals for ranges
const q1Total = sumRange(worksheet, "B2:B4"); // Sum Q1 column
const widgetTotal = sumRange(worksheet, "B2:E2"); // Sum Widget row
console.log(`Q1 Total: ${q1Total}`); // 240
console.log(`Widget Total: ${widgetTotal}`); // 625Install with Tessl CLI
npx tessl i tessl/npm-xlsx