Guide

How to export a table from a website to Excel or CSV

Updated 6 November 2026 • AppStudio Desk

Copying a table off a web page and pasting it into Excel usually produces one of two results: everything crammed into a single column, or a mangled grid that takes longer to fix than retyping. The cause is almost always that the page is not using a real HTML <table>, or that the clipboard carries formatting Excel misreads. This guide covers four methods, in order of effort, and the specific problems each one does and does not solve.

First, check whether it is really a table

Open DevTools (F12 or Ctrl+Shift+I), go to the Console, and run:

document.querySelectorAll('table').length

A number above zero means the page contains real table markup, and the simple methods below will work. If it returns 0, the page is built from <div> elements laid out in a grid. Copy-paste will fight you, and only a grid-aware extractor will get clean rows out of it.

Method 1: copy and paste (small, simple tables)

Select the table with the mouse, copy, then in Excel use Paste Special → Text rather than a normal paste. That drops the page's styling and keeps the cell boundaries. In Google Sheets, paste normally and then use Data → Split text to columns if everything lands in one column.

This works well up to roughly a screen of rows. It breaks down when the table is wider than the window, when rows are collapsed behind a “show more” button, or when the page renders rows as you scroll.

Method 2: a console snippet that builds CSV

This is the most reliable free method for a real <table>. Run it in DevTools on the page, then paste the result into a text file saved as .csv and open that in Excel:

const t = document.querySelector('table');
const rows = [...t.rows].map(r =>
  [...r.cells]
    .filter(c => c.offsetParent !== null)
    .map(c => '"' + c.innerText.trim().replace(/"/g, '""') + '"')
    .join(',')
);
copy(rows.join('\n'));

The offsetParent filter drops hidden cells, which is what you want when a site collapses columns behind a toggle. The quotes and doubled quotes handle commas and quotation marks inside cell text, which is the usual reason a hand-made CSV breaks in Excel.

To write the file directly instead of copying, replace the last line with a download:

const blob = new Blob([rows.join('\n')], {type: 'text/csv'});
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'table.csv';
a.click();

Caveats: this only captures rows currently in the DOM, and it does not follow pagination or infinite scroll.

Method 3: Google Sheets IMPORTXML / IMPORTHTML

If the page is public and you want the data to refresh, use a formula:

=IMPORTHTML("https://example.com/page", "table", 1)

The final 1 is the index of the table on the page. This keeps the sheet live but has real limits: it cannot pass cookies or log in, so anything behind a session fails, it times out on large pages, and Google caps the number of import formulas per sheet. It is best for small public reference tables you want to monitor.

Method 4: an extractor that handles pagination and div grids

The cases the first three methods miss are the ones that matter in practice: a table split across 40 pages, a grid built from <div>s, or a report you need to pull every week. That is what a dedicated extractor is for — it walks the pagination, detects tabular structure in non-table markup, and writes a real .xlsx rather than a CSV you have to re-import.

We build one: TableSnap Pro. It runs locally, exports unlimited rows on the free tier, and copies any table straight to Markdown if you need it for documentation. It is not the only option in this category, and you should compare before paying anyone — see the Table Capture comparison.

The five problems that actually break an export

  1. Merged cells. A cell spanning three columns becomes three identical values, or one value and two blanks, depending on the tool. Check the first rows after import.
  2. Hidden rows and columns. Copy-paste respects visibility; DOM scrapers do not unless you filter. This is the most common silent data error.
  3. Pagination. No clipboard method can see page 2. Confirm the total row count against what you exported.
  4. Numbers stored as text. Values with thousands separators or currency symbols import as text. Use Excel's Text to Columns or clean the column before analysis.
  5. Dates in ambiguous formats. 03/04/2026 is March or April depending on locale. Set the column format explicitly before you sort.

TableSnap Pro

Unlimited rows, real .xlsx output, and div-grid detection, all local in your browser.

See TableSnap Pro →

Common questions

Why does my pasted table all end up in one column?
The page is almost certainly not using a real table element, or the clipboard is carrying HTML that Excel flattens. Use Paste Special, then Data, then Text to Columns with comma as the delimiter, or use the console snippet above to build proper CSV.
Can I export a table that is behind a login?
Yes, with a browser-based method, because the browser already holds the session. The console snippet works on any page you are signed in to. Google Sheets IMPORTXML cannot, because Google's servers fetch the page without your cookies.
How do I export all pages of a paginated table?
Clipboard and formula methods only see the rows currently rendered. You need a tool that clicks through pagination, or the site's own CSV export if it offers one. Check for an export button before building anything.