Moicko

Introducing xlsx-kaku: A Library for Writing Excel Files in Node.js

Cover Image for Introducing xlsx-kaku: A Library for Writing Excel Files in Node.js

Overview

I created a library for Node.js called "xlsx-kaku".

"kaku" means "writing" in Japanese. True to its name, this library can output Excel xlsx files. It does not support input. The reason for this is that by making it output-only, it reduces bugs and keeps the build size small.

In this article, I would like to introduce this library.

Features

Pros

ES module is supported. Even as more features are added, it is expected that unused code will be tree-shaken, keeping the bundle size small.

Keeping the bundle size simall is particularly important when used on the client-side. Of course, xlsx-kaku works both on the cilent-side and the server-side.

Cons

As of now, it does not support CommonJS.
Being a newer library, I thought it was important to first support ES module. Also, this is to avoid compilications.

How to Use

I will introduce how to use it on both client-side and server-side.

Server-Side

First, install the dependencies. I'll write in TypeScript code. In addition to xlsx-kaku, install @types/node.

npm i xlsx-kaku
npm i -D typescript @types/node

Since it will be used as ES module, add "type":"module" to package.json.
The package.json will look like this.

{
  "name": "xlsx-kaku-sample",
  "description": "",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "xlsx-kaku": "^0.10.0"
  },
  "devDependencies": {
    "@types/node": "^20.11.6",
    "typescript": "^5.3.3"
  }
}

Create an index.js file and write the code as follows.

import { writeFileSync } from "node:fs";
import { Workbook } from "xlsx-kaku";

const wb = new Workbook();
const ws = wb.addWorksheet("Sheet1");

ws.setCell(0, 0, { type: "string", value: "Hello," });
ws.setCell(0, 1, { type: "string", value: "World!" });

const xlsx = wb.generateXlsxSync();
writeFileSync("test.xlsx", xlsx);

When you run "node index.js", a file named "test.xlsx" is generated.
Please open this file in Excel. It should display correctly!.

server-side-result

Client-Side (Next.js)

This is a sample for creating and downloading an XLSX file.
First, we will create a Next.js project.

npx create-next-app@latest

Next, we will create the DownloadButton component.
Most of the code is unrelated to xlsx-kaku, but is is the boilerplate code nexessary for downloading files.

Since we are using onClick, don't forget to add "use client".

"use client";
import { Workbook } from "xlsx-kaku";

export default function DownloadButton() {
  const handleDownload = () => {
    const wb = new Workbook();
    const ws = wb.addWorksheet("Sheet1");

    ws.setCell(0, 0, { type: "string", value: "Hello" });
    ws.setCell(0, 1, { type: "number", value: 123 });

    const xlsx = wb.generateXlsxSync();

    const blob = new Blob([xlsx], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    });
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = url;
    link.download = "sample.xlsx";
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  };

  return (
    <div>
      <button onClick={handleDownload}>download xlsx</button>
    </div>
  );
}

We will add the DownloaButton component we created earlier to the Home component.
To make the code more readable, I have removed the demo code that was there from the beginnig.

import DownloadButton from "./DownloadButton";

export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
      <DownloadButton />
    </main>
  );
}

When you run "npm run dev", the DownloadButton will be displayed.

download-button

Since it's not styled with any classes, it's just a text button, but when you click it, an xlsx file will be downloaded.

When you open this file with Excel, it should display correctly.

client-side-result

Links

https://github.com/motinados/xlsx-kaku
https://www.npmjs.com/package/xlsx-kaku
twitter