xlsx-ui-pipeline
v1.0.0
Published
Simple, focused utilities to produce Excel (.xlsx) templates and validate uploaded Excel files in browser environments. This package is small but powerful for web apps that need to:
Readme
xlsx-ui-pipeline
Simple, focused utilities to produce Excel (.xlsx) templates and validate uploaded Excel files in browser environments. This package is small but powerful for web apps that need to:
- Generate downloadable templates (empty or pre-filled) with typed columns, lists, boolean choices, numeric validations and styling.
- Accept uploaded Excel files and validate rows against a ruleset, returning separate ValidData and InvalidData results (with error messages and row indexes).
It's designed to be used in browser/ESM environments and works well with bundlers (Vite, Webpack, Bun, etc.). Install
Install with your package manager of choice:
# npm
npm install xlsx-ui-pipeline
# bun
bun add xlsx-ui-pipeline
# pnpm
pnpm add xlsx-ui-pipelineQuick start (browser)
Below are copy-pasteable examples showing the two primary flows: generating/downloading a template and uploading/validating a filled file.
Important: the examples reference validator helper functions from rules-js-kt for readability. Replace those imports with the actual rule functions you use from rules-js-kt in your project.
- Generate / download an Excel template
This example creates a file with a colored header row, column validations (lists, booleans, numbers), and optional pre-filled rows.
import { downloadXlsxFromHeadersAndData, type XlsxHeader } from "xlsx-ui-pipeline";
const headers: XlsxHeader[] = [
{ text: "Name", key: "name", type: "string", required: true, rules: [rules.required("Name"), rules.name("Name")] },
{ text: "Age", key: "age", type: "number", rules: [rules.number("Age", 130, 18)] },
{ text: "Active", key: "active", type: "boolean" },
{ text: "Role", key: "role", type: "list", list: ["admin", "editor", "viewer"], required: true, rules: [rules.required("Role")] },
];
const sampleData = [
{ name: "Amira", age: 28, active: true, role: "editor" },
{ name: "Omar", age: 34, active: false, role: "admin" },
];
// Trigger download (creates a browser file save dialog)
downloadXlsxFromHeadersAndData({
headers,
data: sampleData,
title: "users-template.xlsx",
color: "#1F8A70",
});Notes on generated template behavior:
- Header row is styled and the worksheet tab color is set using the
colorvalue. - For boolean columns, the template uses a localized list formula (
نعم,لا) to allow Yes/No selection. - For list columns, a dropdown with the provided values is added.
- Number columns get a decimal validation.
- Column widths are auto-adjusted based on header and content.
- Upload / validate a filled Excel file
On upload, the library maps Excel columns by header text to your internal keys, runs each header's rules, and returns two arrays:
- ValidData: rows that passed all rules (each item includes an
indexrepresenting the original row index in the parsed data array). - InvalidData: rows with one or more rule errors; each includes an
errorsarray with{ message }objects and theindex.
Example usage in a browser page with a file input:
import { uploadXlsxFromHeadersAndData, type XlsxHeader } from "xlsx-ui-pipeline";
// Example rule functions from rules-js-kt (adjust names to match that package's API)
import { required, isNumber, min, inList } from "rules-js-kt";
const headers: XlsxHeader[] = [
{ text: "Name", key: "name", type: "string", required: true, rules: [rules.required("Name"), rules.name("Name")] },
{ text: "Age", key: "age", type: "number", rules: [rules.number("Age", 130, 18)] },
{ text: "Active", key: "active", type: "boolean" },
{ text: "Role", key: "role", type: "list", list: ["admin", "editor", "viewer"], required: true, rules: [rules.required("Role")] },
];
const input = document.querySelector<HTMLInputElement>('#xlsxFile')!;
input.addEventListener('change', async (e) => {
if (!input.files?.length) return;
const file = input.files[0];
try {
const result = await uploadXlsxFromHeadersAndData({ headers, file });
console.log('Valid rows: ', result.ValidData);
console.log('Invalid rows: ', result.InvalidData);
// you can assign the results to as reactive state so tables could show them for example or do what ever
// Example: show errors in UI or download invalid records as a report
} catch (err) {
console.error('Failed to parse or validate the uploaded Excel file:', err);
}
});TypeScript types
The package exports a small set of types to help with static typing:
XlsxHeader— describes a column in the spreadsheet and its validation rules.UploadResponse<T>— the response shape fromuploadXlsxFromHeadersAndData:ValidData: (T & { index: number })[]InvalidData: (T & { index: number } & { errors: { message: string }[] })[]
XlsxHeader shape (summary):
text: string— the column header text as it appears in the Excel file (used to map uploaded columns).key: string— the property name output when mapping rows to objects.type: 'string' | 'number' | 'boolean' | 'list'— used to add appropriate Excel validations in the template.list?: string[]— fortype: 'list', the allowed values used in the template dropdown.required?: boolean— whether the template allows blank values (affects cell validations when generating templates).rules?: Array<(value: any) => undefined | true | string>— validation rules executed on upload; a rule should returnundefinedortruefor pass, or astringerror message for failure.
Rules and rules-js-kt
The library expects rules with the signature (value) => undefined | true | string. For convenience we show examples using validators from rules-js-kt. If you use another validator library, adapt to produce the same signature.
Example rule behavior expected by the library:
- Return
undefinedortruewhen the value passes. - Return a string (the error message) when the value fails.
Notes, tips and edge-cases
- Header matching for upload uses the human-readable
textproperty. Make sure your generated template headers match the headers your user will upload (including language/diacritics). - The library maps each Excel row to an object using
xlsx.utils.sheet_to_json. Empty rows may be omitted by that utility; test uploads to ensure indexes line up with your expectations. The returnedindexis the record index within the parsedrecordsarray. - The library performs only the rules you pass; it does not perform server-side sanitization or further type coercion. Coerce or sanitize values after upload if required.
- For boolean columns the downloadable template uses a localized list (
نعم,لا) in the dropdown. On upload you'll receive the literal cell value — consider mapping that to booleans in your app (e.g.value === 'نعم').
Developer notes
downloadXlsxFromHeadersAndDatausesexceljsto build a workbook andfile-saver'ssaveAsto trigger the browser file save dialog.uploadXlsxFromHeadersAndDatausesxlsxto parse the uploaded workbook andsheet_to_jsonto convert the first sheet into an array of records.
Try it locally
Install and run the demo script (if present) — this project uses Bun for local scripts; otherwise use your bundler/development server.
bun install
bun run index.tsLicense
MIT
Credits
Built with exceljs and xlsx. Example rule functions in the README reference rules-js-kt as a convenient rules provider; replace with your preferred rule library or your own helpers.
