npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@onsvisual/accessible-xlsx

v0.2.0

Published

A library for creating accessible XLSX spreadsheets

Readme

Accessible XLSX

This library enables the creation of accessible XLSX spreadsheets compatible with Analysis Function best practice guidance. It can be used in client-side JavaScript and in Node.js.

Spreadsheets generated with this library should pass all of the tests in our XLSX Accessibility Checker tool.

How does it work?

This is a very simple wrapper for the Documonster Excel module that allows accessible spreadsheets to be created with minimal configuration.

The XLSX output generated by the script can be written to a file in Node.js or turned into a download in the browser.

Add it to your project

If you are using NPM (eg. in Svelte projects or for Node.js scripts):

npm install @onsvisual/accessible-xlsx

If you are loading it directly in a browser:

<script src="https://unpkg.com/@onsvisual/[email protected]/dist/accessible-xlsx.umd.js"></script>

In most cases, you'll want to download the JS file accessible-xlsx.umd.js and save it locally in your project.

Usage examples

A couple of client-side examples can be found here.

Generate a single-page spreadsheet in vanilla JS

<script src="https://unpkg.com/@onsvisual/[email protected]/dist/accessible-xlsx.umd.js"></script>
<script src="https://unpkg.com/[email protected]/dist/FileSaver.min.js"></script>
<script>
	const data = {
		sheetName: "Table name",
		sheetIntroText: ["Some introductory text."],
		columns: [
			{
				style: "text",
				heading: "Category",
				values: ["First category", "Second category"]
			},
			{
				style: "number_with_commas",
				heading: "Selected group",
				values: [12_345, 1_234_567]
			},
			{
				style: "number_1dp",
				heading: "England and Wales with a really long title",
				values: [45.6, 45.6]
			}
		]
	};
	// Beware: The generateXLSX function is asynchronous!
	generateXLSX(data).then((xlsx) => {
		const blob = new Blob([xlsx], {
			type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
		});
		saveAs(blob, "my_spreadsheet.xlsx");
	});
</script>

Note that the FileSaver "saveAs" function is used in the above example for brevity. The same basic save functionality can be achieved with following function:

function saveAs(blob, filename) {
	const url = window.URL || window.webkitURL || window;
	const link = url.createObjectURL(blob);
	const a = document.createElement("a");

	a.download = filename;
	a.href = link;
	document.body.appendChild(a);

	a.click();
	document.body.removeChild(a);
}

Generate a multi-page spreadsheet in Node.js

Note: You can also generate a single-page spreadsheet in Node.js or a multi-page spreadsheet in a web browser!

import accessibleXLSX from "@onsvisual/accessible-xlsx";
import { writeFileSync } from "node:fs";

const data = {
	coverSheetTitle: "An example spreadsheet",
	coverSheetContents: [
		"## Subtitle 1",
		"Text 1a",
		"Text 1b",
		"## Subtitle 2",
		"Text 2a",
		"Text 2b",
		"[Office for National Statistics](https://www.ons.gov.uk)"
	],
	notes: [
		{ name: "note_1", text: "Here is a note" },
		{ name: "another_note", text: "Here is another note" },
		{ name: "note C", text: "Another note" }
	],
	sheets: [
		{
			sheetName: "Sheet name",
			sheetIntroText: ["Some introductory text [another_note][note_1]"],
			columns: [
				{
					style: "text",
					heading: "Category [note_1]",
					values: ["First category [note_1]", "Second category"]
				},
				{
					style: "number_with_commas",
					heading: "Selected group",
					values: [12_345, 1_234_567]
				},
				{
					style: "number_1dp",
					heading: "England and Wales with a really long title",
					values: [45.6, 45.6]
				}
			]
		},
		{
			sheetName: "Another sheet",
			columns: [
				{
					style: "text",
					heading: "Category",
					values: ["First category", "Second category", "Really long looooooong category"]
				},
				{
					style: "number_1dp",
					heading: "Selected group",
					values: [12.3, 12.3, 78.9]
				},
				{
					style: "number_1dp",
					heading: "England and Wales with a really long title\n(units)",
					values: [45.6, null, 45.6]
				}
			]
		}
	]
};

const xlsx = await accessibleXLSX(data);
writeFileSync("./my_spreadsheet.xlsx", data);

Generate a spreadsheet in a Svelte app

In a client-side Svelte app (or any other app build using a JS bundler), the following import is used:

import accessibleXLSX from "@onsvisual/accessible-xlsx";

The rest of the code should be the same as the first vanilla JS example above.

Alternative ways to format data

The examples above include data within the column definitions. There are also two other options that may better suit your projects.

An array of rows

This is theoretically the most performant option, as it matches the expected input of Documonster and therefore requires no internal transformation.

const rows = [
	["First category", 12_345, 45.6],
	["Second category", 1_234_567, 78.9]
];
const data = {
	sheetName: "Age",
	sheetIntroText: ["Some introductory text."],
	columns: [
		{
			style: "text",
			heading: "Category"
		},
		{
			style: "number_with_commas",
			heading: "Selected group"
		},
		{
			style: "number_1dp",
			heading: "England and Wales with a really long title"
		}
	],
	rows
};

const xlsx = accessibleXLSX(data);
// Add code to write/download the XLSX output (see above examples)

An array of objects

This is likely to be more convenient for data visualisation projects where data is typically already in this format. Note that an additional key property is required for each column if the object keys in the data rows do not exactly match the human-readable column heading wanted in the spreadsheet.

const rows = [
	{ category: "First category", group: 12_345, value: 45.6 },
	{ category: "Second category", group: 1_234_567, value: 78.9 }
];
const data = {
	sheetName: "Age",
	sheetIntroText: ["Some introductory text."],
	columns: [
		{
			style: "text",
			heading: "Category",
			key: "category"
		},
		{
			style: "number_with_commas",
			heading: "Selected group",
			key: "group"
		},
		{
			style: "number_1dp",
			heading: "England and Wales with a really long title",
			key: "value"
		}
	],
	rows
};

const xlsx = accessibleXLSX(data);
// Add code to write/download the XLSX output (see above examples)

Why XLSX not ODS format?

Although the Analysis Function recommends ODS as an open format as opposed to XLSX, this library uses the latter for two reasons.

  1. XLSX is slightly more widely supported than ODS. For example, Apple Numbers does not support ODS.
  2. There is no Javascript library* that can generate ODS files that fully meet the Analysis Function accessibility guidance.

*We previously created this experimental library for generating accessible ODS files from scratch. However, it is not capable processing large volumes of data.