Skip to main content

CSVtoTable

CSVtoTable converts CSV, TSV, and Excel files into interactive HTML tables.

  • Single native binary with embedded frontend assets
  • Standalone HTML output that works offline — data, styles, and scripts all inlined
  • CSV, TSV, and Excel (.xlsx) input, gzip archives included
  • Local files, URLs, standard input, or several files combined into one table
  • BOM and UTF-16 detected automatically; --encoding, --delimiter, --quotechar for the rest
  • Search, per-column filters with clearable chips, sorting, pagination, and virtual scrolling
  • Copy, CSV, JSON, and print exports, plus column show/hide
  • Markdown or raw HTML page title and description, inline or read from a file
  • Five colour themes, switchable in the page or fixed with --theme
  • Themes are just CSS variables — define your own with --css and it joins the picker
  • --css and --js inline your own stylesheet and script, with the live table API exposed
  • Mobile-responsive layout

CSVtoTable demo

Try the live demo — a page built by CSVtoTable from the sample data, served as one static file.

Usage

# Write a standalone page
csvtotable input.csv page.html

# Combine files with the same columns
csvtotable input1.csv input2.csv page.html

# Gzip-compressed CSV files
csvtotable data.csv.gz data.html

# Read an Excel workbook
csvtotable sales.xlsx sales.html

# Fetch CSV directly from a URL
csvtotable https://raw.githubusercontent.com/vividvilla/csvtotable/master/demo/meteorite-landings-1.csv meteorites.html

# Open a temporary page in the default browser
csvtotable data.csv --serve

# Add a title and generate headers for headerless data
csvtotable data.csv data.html --title "Sales" --no-header

# Title and description accept Markdown
csvtotable data.csv data.html --title "Sales for **Q3**" --description "Pulled from \`warehouse\`. See the [runbook](https://example.com)."

# or pass a markdown file as decription
csvtotable data.csv data.html --title "Sales for **Q3**" --description @sales.md

# or use raw HTML instead of Markdown
csvtotable data.csv data.html --title-html '<span>Sales <b>Q3</b></span>'
csvtotable data.csv data.html --title-html '<span>Sales <b>Q3</b></span>' --description-html @description.html

# Paginate instead of showing every row
csvtotable data.csv data.html --page-size 50

# Open in a particular theme
csvtotable data.csv data.html --theme solarized

# Add your own CSS and JavaScript
csvtotable data.csv data.html --css brand.css --js setup.js

# Read stdin and write stdout
curl -L https://example.com/data.csv | csvtotable - - > data.html

# Explore all the available options
csvtotable --help

Install

uvx, pipx, or pip

Run without installing:

uvx csvtotable data.csv data.html

Or install it:

pipx install csvtotable
uv tool install csvtotable
pip install csvtotable  # inside a virtual environment

npx or npm

npx @vividvilla/csvtotable data.csv data.html   # run without installing
npm install --global @vividvilla/csvtotable     # or install globally

To run a particular published version:

uvx csvtotable@X.Y.Z data.csv data.html
npx @vividvilla/csvtotable@X.Y.Z data.csv data.html

Homebrew

brew install vividvilla/tap/csvtotable

Standalone binary

Download an archive from GitHub Releases, verify it with SHA256SUMS, and place csvtotable (csvtotable.exe on Windows) on your PATH.

Prebuilt binaries support Linux x86-64/ARM64, macOS 12+ x86-64/Apple Silicon, and Windows 10+ x86-64.

Styling

The page is plain semantic HTML, and every element CSVtoTable owns carries a csvtotable- class. These are the stable hooks:

Hook Element
.csvtotable <main>, the page root
.csvtotable-header <header> wrapping the title and description
.csvtotable-title <h1> page heading
.csvtotable-description description block
.csvtotable-table the <table>
.csvtotable-theme theme picker
.csvtotable-filters active-filter chip row
.csvtotable-chip one active filter, with -key, -value, and -remove parts
.csvtotable-clear the "clear all" control

A theme is nothing but a block of colour variables. Every rule in the stylesheet reads them, so a new theme is a copy of one block with different values — no rules to write and nothing else to touch:

[data-theme="my-theme"] {
  color-scheme: dark;      /* so scrollbars and dropdowns match */
  --ct-paper: #1a1b26;     /* page background */
  --ct-ink: #c0caf5;       /* body text */
  --ct-muted: #7f88b0;     /* labels, secondary text */
  --ct-rule: #232433;      /* row separators */
  --ct-rule-strong: #343b58;
  --ct-accent: #7aa2f7;    /* focus, active sort, filter chips */
  --ct-wash: #1f2335;      /* accent tint behind chips */
  --ct-hover: #1e2030;     /* row and control hover */
}

Switching themes is just swapping data-theme on <html>. Type and metrics sit outside the palettes in the --ct-text-* scale and --ct-sans/--ct-mono, since they do not vary by theme. Headings are styled by level (h1 to h6), so a Markdown heading in a description matches the same level elsewhere; start description headings at ## to keep one <h1> per page.

Nothing is styled through an ID, so a stylesheet loaded after the page's own <style> overrides any of the above with a single class selector. Classes beginning dt- come from DataTables and may change when it is upgraded.

Custom CSS and JavaScript

--css and --js inline a stylesheet and a script into the page, keeping the output a single self-contained file. Both take a file path:

csvtotable data.csv data.html --css brand.css --js setup.js

A leading @ is accepted too, for symmetry with --description, but means nothing here: --css @brand.css and --css brand.css are the same.

Placement is what makes them useful. The stylesheet goes last in <head>, after the built-in one, so a single class selector overrides anything above without !important. The script goes last in <body>, after the table is built, and CsvToTable.table holds the live DataTables API instance:

CsvToTable.table.order([2, "desc"]).draw();   // sort by the third column
CsvToTable.table.column(0).visible(false);    // hide the first column

The table's height is fitted on the next animation frame, so a script that measures layout should wrap the read in requestAnimationFrame. Column widths and the scroll height are set as inline styles, which a stylesheet cannot override — use --height for that.

A whole new palette is a stylesheet plus a matching --theme. The name does not have to be one of the built-ins as long as --css defines it, and the page's theme picker will list it alongside them:

csvtotable data.csv data.html --css custom.css --theme tokyonight

Selecting "Auto" in the picker unpins data-theme and falls back to the built-in light and dark palettes, so put anything that should survive that in :root or a class rule and keep [data-theme] blocks for the palette itself.

Both flags are trusted input: whatever the files contain runs for anyone who opens the page, so do not generate them from untrusted data. Content is escaped only so it cannot break out of its <style> or <script> element; it is not sanitised.

Run csvtotable --help for all options or csvtotable --version for the version. For compatibility with version 2, --caption, --display-length, --pagination, and --export still work; the last two disable those features.

Development

Building requires Go 1.25+ and Bun. Distribution packaging also requires Python and npm. table/dist is generated before the Go build and embedded in the final binary.

nix develop  # optional development environment
make build   # frontend and build/csvtotable
make test    # frontend, formatting, vet, and tests
make demo    # the published demo page under site/
make dist    # binary and host-platform packages under dist/
./build/csvtotable demo/meteorite-landings-1.csv demo/meteorite-landings-2.csv /tmp/meteorites.html

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

csvtotable-3.1.0-py3-none-win_amd64.whl (6.0 MB view details)

Uploaded Python 3Windows x86-64

csvtotable-3.1.0-py3-none-musllinux_1_2_x86_64.whl (5.9 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

csvtotable-3.1.0-py3-none-musllinux_1_2_aarch64.whl (5.4 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

csvtotable-3.1.0-py3-none-manylinux_2_17_x86_64.whl (5.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

csvtotable-3.1.0-py3-none-manylinux_2_17_aarch64.whl (5.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

csvtotable-3.1.0-py3-none-macosx_12_0_x86_64.whl (6.0 MB view details)

Uploaded Python 3macOS 12.0+ x86-64

csvtotable-3.1.0-py3-none-macosx_12_0_arm64.whl (5.6 MB view details)

Uploaded Python 3macOS 12.0+ ARM64

File details

Details for the file csvtotable-3.1.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: csvtotable-3.1.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 6.0 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for csvtotable-3.1.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 d31573d57828e1af62684694452bba239ff7304b889ed19f3502278a0bf0d2f6
MD5 d2bec721a3a1c879d258a8841e018c35
BLAKE2b-256 57205afa45834c52278dd78c1de0f21443e3079ae806c7433a585d9aa12054cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for csvtotable-3.1.0-py3-none-win_amd64.whl:

Publisher: release.yml on vividvilla/csvtotable

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file csvtotable-3.1.0-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for csvtotable-3.1.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 0658276ca01b5f4ecdc94043de19acad41dfca64e9ed438c387d88710db7dc5d
MD5 056ad62e43e2abb79645a5996fb1d49b
BLAKE2b-256 e17a1f3e68585fe9704e0bf9fa9e9eb31d058bc64a9b277194d1691a5c7f03df

See more details on using hashes here.

Provenance

The following attestation bundles were made for csvtotable-3.1.0-py3-none-musllinux_1_2_x86_64.whl:

Publisher: release.yml on vividvilla/csvtotable

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file csvtotable-3.1.0-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for csvtotable-3.1.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 90dd94b775f7d7c7c298d90f05402f025f5b76e988524aa3295d6d63f5505569
MD5 947946f603fb7736cdf18202471caa7a
BLAKE2b-256 bc270e7e30e601697a62295df8929e54117c4375f268eaf47ab71a1179141bd0

See more details on using hashes here.

Provenance

The following attestation bundles were made for csvtotable-3.1.0-py3-none-musllinux_1_2_aarch64.whl:

Publisher: release.yml on vividvilla/csvtotable

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file csvtotable-3.1.0-py3-none-manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for csvtotable-3.1.0-py3-none-manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 1b9188c454f3bd7996c4323b0fa83afc5a1106b03675bad0360db967a6857e0a
MD5 03c773dc5fff6aca280597c88e0f7d49
BLAKE2b-256 c794ce82202fcade335b32e2ade4a316594fef0729016e468bf532cdf7842264

See more details on using hashes here.

Provenance

The following attestation bundles were made for csvtotable-3.1.0-py3-none-manylinux_2_17_x86_64.whl:

Publisher: release.yml on vividvilla/csvtotable

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file csvtotable-3.1.0-py3-none-manylinux_2_17_aarch64.whl.

File metadata

File hashes

Hashes for csvtotable-3.1.0-py3-none-manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 44015e7029d102ca394e1df88be23d43c3365c646536c7eca1af0dcea76ff0dc
MD5 f67c0f1049f69260b2e6b1583f042bea
BLAKE2b-256 ad275da91eaab7112c04d77a84ef28fe2583d808c3f3c8bebf1e4c19637e0eb8

See more details on using hashes here.

Provenance

The following attestation bundles were made for csvtotable-3.1.0-py3-none-manylinux_2_17_aarch64.whl:

Publisher: release.yml on vividvilla/csvtotable

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file csvtotable-3.1.0-py3-none-macosx_12_0_x86_64.whl.

File metadata

File hashes

Hashes for csvtotable-3.1.0-py3-none-macosx_12_0_x86_64.whl
Algorithm Hash digest
SHA256 4ad73e4623e0d9d3cf3bd0d809a54987820327b2bde3770184d6fee991977d43
MD5 c1743bef31b7c9ecb457c2545edfafd9
BLAKE2b-256 bac065a78ca738c78d28a018529c1464c06c8f8f73227d0d42ae101e64d49403

See more details on using hashes here.

Provenance

The following attestation bundles were made for csvtotable-3.1.0-py3-none-macosx_12_0_x86_64.whl:

Publisher: release.yml on vividvilla/csvtotable

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file csvtotable-3.1.0-py3-none-macosx_12_0_arm64.whl.

File metadata

File hashes

Hashes for csvtotable-3.1.0-py3-none-macosx_12_0_arm64.whl
Algorithm Hash digest
SHA256 154a9ec3b6677f772e418a98e6825219f036be7c91c0ef6f000d487a5c5f2c79
MD5 cd7b2756c8dec866aa90278b405d00f1
BLAKE2b-256 205ee5b788b951f657dd451b8ca3e3bb2628e2979b0de7b110df2d83adedf81d

See more details on using hashes here.

Provenance

The following attestation bundles were made for csvtotable-3.1.0-py3-none-macosx_12_0_arm64.whl:

Publisher: release.yml on vividvilla/csvtotable

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

3.2.0

7 files

This release

3.1.0 This release

7 files

3.0.0

7 files

2.1.1

2 files

2.1.0

2 files

2.0.0

2 files

1.1.4

1 file

1.1.3

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page