webdevpuneet.com

Table Export Menu — CSV, JSON & Print, Real Working Downloads (JS)

Table Export Menu (CSV/JSON/Print) · Tables · Plain HTML, CSS & JS · Live preview

CategoryTables

Copy & paste

Source Code

<div class="tem-wrap" id="temWrap">
  <div class="tem-bar">
    <h3>Inventory</h3>
    <div class="tem-menu" id="temMenu">
      <button type="button" class="tem-toggle" id="temToggle">Export <span class="tem-caret">▾</span></button>
      <div class="tem-drop" id="temDrop" hidden>
        <button type="button" class="tem-item" data-action="csv">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/></svg>
          Download CSV
        </button>
        <button type="button" class="tem-item" data-action="json">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/></svg>
          Download JSON
        </button>
        <button type="button" class="tem-item" data-action="print">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 6 2 18 2 18 9"/><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><rect x="6" y="14" width="12" height="8"/></svg>
          Print view
        </button>
      </div>
    </div>
  </div>
  <table class="tem-table" id="temTable">
    <thead><tr><th>SKU</th><th>Item</th><th>Warehouse</th><th class="tem-num">Qty</th></tr></thead>
    <tbody id="temBody"></tbody>
  </table>
  <p class="tem-note" id="temNote" hidden></p>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Real dropdown menu
Toggles open/closed, closes on outside click or Escape.
Working CSV export
RFC-4180 escaping and a UTF-8 BOM via a real Blob download.
Working JSON export
JSON.stringify on the actual row objects — matches the table exactly.
Working print view
A genuine window.print() call against dedicated @media print rules.
Print hides interactive chrome
The export menu and confirmation note disappear only in print output.
One data source, three outputs
CSV, JSON, and the table all render from the same ROWS array.
Export confirmation
A note confirms row count exported for CSV and JSON, then auto-dismisses.
No library
Blob, URL.createObjectURL, and window.print() — all native browser APIs.

About this UI Snippet

Table Export Menu — One Dropdown, Three Real Export Actions

Screenshot of the Table Export Menu (CSV/JSON/Print) snippet rendered live

Most tables eventually need more than one export format — a CSV for spreadsheets, JSON for another tool to consume, and a clean printable page for a physical record. This snippet builds a single "Export ▾" dropdown with all three actions genuinely wired up in plain HTML, CSS, and vanilla JavaScript: correctly-escaped CSV, structured JSON matching the row data, and a real window.print() call against dedicated @media print rules — every action produces a real file or a real print dialog, nothing is a decorative button.

A real dropdown menu, not a static list

The "Export ▾" button toggles a positioned .tem-drop panel, closes on an outside click or Escape, and stops the toggle click from immediately re-triggering the document-level close listener via stopPropagation(). This is the standard, dependency-free dropdown pattern — no library, just a hidden attribute and two listeners.

CSV: RFC-4180 escaping, not naive joining

exportCsv() reuses the same csvCell() escaping rule as a dedicated CSV export table: values containing a comma, quote, or newline are wrapped in quotes with internal quotes doubled. A UTF-8 BOM is prepended so Excel reads accented characters correctly, and the result is downloaded via a Blob + temporary <a download> — entirely client-side.

JSON: the same row data as an array of objects

exportJson() calls JSON.stringify(ROWS, null, 2) directly on the same object array that renders the table — not a re-shaped or hand-written copy — so the exported JSON is guaranteed to match what's on screen, keyed by the same field names (sku, item, warehouse, qty). This is the format another script, API, or tool would actually want to consume, as opposed to the flat rows CSV needs.

Print: real @media print rules, not a fake preview

exportPrint() calls the browser's native window.print(). The page defines an @media print block that hides the export menu and the confirmation note, removes shadows/borders/hover backgrounds, and forces black-on-white table text — so what prints is a clean report, not a screenshot of the interactive UI with a floating button baked in. Because it's real @media print CSS and a real window.print() call, it works in the browser's actual print preview and any physical printer, not just as a stylized "looks printable" mockup.

One source of truth, three outputs

All three actions read from the same ROWS/COLUMNS/KEYS — there's no separate hardcoded string for any format, so adding a column or row updates all three exports and the visible table simultaneously. Pair this with a data table for sorting/filtering before export, or a dedicated print view if print is your primary export format.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSAn inventory table renders with an "Export ▾" button in the header.
  2. 2
    Open the menuClick Export to reveal Download CSV, Download JSON, and Print view.
  3. 3
    Download CSVA correctly-escaped, UTF-8 BOM-prefixed .csv file downloads immediately.
  4. 4
    Download JSONA .json file downloads containing the exact row objects as an array.
  5. 5
    Use Print viewTriggers the browser's print dialog against dedicated @media print styling that hides the menu.
  6. 6
    Close the menuClick outside or press Escape to dismiss the dropdown without exporting.

Real-world uses

Common Use Cases

Admin dashboard exports
Offer spreadsheet, API-consumable and printable output from one Export menu, closing on outside click or Escape.
Warehouse printing
Let operations staff print a clean copy of a data table, using dedicated @media print rules that remove interface chrome.
JSON hand-off to tools
Feed another script with JSON.stringify of the real row objects, so the export matches the table exactly.
Finance and invoicing
Export line items in several formats from an invoice line items table, with CSV escaped per RFC 4180.
Compliance records
Print a dated, chrome-free report for audits, and see CSV export table for a single-format version.
Related: Table Row Density Toggle — Compact / Comfortable / Spacious, Persisted
See the Table Row Density Toggle — Compact / Comfortable / Spacious, Persisted for a related tables pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Yes. CSV and JSON both build a real Blob and trigger a genuine file download via a temporary anchor element — open the downloaded files and they contain the actual row data, correctly escaped for CSV and structured as an array of objects for JSON. Print calls the browser's real window.print() against dedicated @media print CSS, so it opens the actual print dialog, not a styled mockup.

Without @media print rules, printing the page would output the interactive UI as-is — the Export button, hover states, shadows, and colored backgrounds baked onto paper. The @media print block hides the menu and note entirely, strips shadows and borders, and forces plain black-on-white text so the printed page reads like a clean report.

Yes — exportJson() calls JSON.stringify directly on the same ROWS array of objects that renders the table body, with no reshaping. So the field names and values in the downloaded JSON are exactly what's rendered, keyed by sku/item/warehouse/qty.

Microsoft Excel doesn't assume UTF-8 by default and can mangle accented or non-Latin characters without a byte-order mark. Prepending \ufeff signals UTF-8 to Excel so names and text with accents open correctly, while remaining invisible to other tools like Google Sheets.

Keep drop-open state in a boolean, and put the exportCsv/exportJson/exportPrint logic in the menu item's click handlers — all three functions (Blob creation, anchor download, window.print) are plain browser APIs that work identically inside any framework's event handlers.