Postgres to Excel: Export Query Results as .xlsx
Last updated August 29, 2026 · By the SaturnSQL team
PostgreSQL has the best command-line export story of any database, and it still ends in a CSV that Excel is free to misread. This guide covers the four routes from Postgres to Excel, what each one costs you, and how to stop running the same export by hand every week.
The short version
If the data has leading zeros, long IDs, or dates in it, export a genuine .xlsx workbook rather than a CSV, so the cell types are written into the file instead of guessed by Excel. For scripted exports use \copy, not COPY. The general tradeoffs across all engines are in the export SQL to Excel guide.
Method 1: a one-click .xlsx download
SaturnSQL is a browser-based SQL editor. Connect Postgres with a read-only user, run the query, open the export menu above the results grid, and pick XLSX. The file is a real workbook with a header row: numbers stay numbers, dates stay dates, and Excel opens it without an import dialog or a type-conversion warning.
On PostgreSQL the export streams, so there is no row cap; the only bound is the query timeout. Most grid-based clients export only the rows the grid fetched, which is rarely the whole result.
Method 2: psql and \copy
The canonical scriptable export. \copy runs client-side, needs no special privileges, and works on RDS, Cloud SQL, Supabase, and every other managed host:
\copy (SELECT id, name, created_at FROM customers ORDER BY 1)
TO 'customers.csv' WITH (FORMAT csv, HEADER)Don’t confuse it with server-side COPY ... TO, which writes files on the database server and needs pg_write_server_files or superuser, so it fails on managed hosts. Either way the output is CSV: Excel will type-guess every column when it opens the file, so leading zeros and 19-digit IDs are still at risk. The failure modes are catalogued in the general guide.
Method 3: pgAdmin’s CSV download
pgAdmin’s query tool has a save-results button (F8) that downloads the current result set as CSV. It is fine for a quick one-off on simple data. There is no .xlsx option, so the CSV caveats above apply unchanged. If you want a genuine workbook from a desktop client, DBeaver’s Export resultset → XLSX does it, though on some builds the XLSX exporter is a separate “Office Formats” extension.
Method 4: stop exporting, schedule it
Most people who export a Postgres query to Excel once end up exporting the same query every week. In SaturnSQL you save the query, attach a schedule with a cron cadence and an IANA timezone, and each run writes the fresh rows to the destination. Hourly refresh is included in the €19/mo base plan.
Where scheduled runs deliver
Scheduled runs deliver to a Google Sheet or to Slack. SaturnSQL does not email an .xlsx attachment on a timer. For Excel users a Sheet is one click away (File → Download → Microsoft Excel (.xlsx)), and unlike a mailed file the URL stays stable, so pivot tables and formulas pointing at it keep working run after run. The full setup is in the Postgres to Google Sheets guide.
Frequently asked questions
How do I export PostgreSQL query results to Excel?
Use a client that writes a genuine .xlsx. In SaturnSQL, run the query and pick XLSX from the export menu; the export streams with no row cap on Postgres. \copy and pgAdmin produce CSV instead, which lets Excel guess every column’s type on open.
How do I export Postgres to Excel automatically?
Put the saved query on a schedule. SaturnSQL runs it on a cron cadence and writes the rows to a Google Sheet or Slack; the Sheet is one click from an .xlsx download and the link stays stable. Scheduled delivery is to Sheets or Slack, not an emailed attachment.
What’s the difference between COPY and \copy?
COPY runs on the database server and writes files there, which needs elevated rights and fails on managed hosts. \copy is a psql client command that streams the same data to your own machine with ordinary permissions. For exports, use \copy.
How many rows can I export?
Excel stops at 1,048,576 rows per worksheet. SaturnSQL streams Postgres exports with no cap of its own, bounded only by the query timeout. Grid-based clients usually export only what the grid fetched.
Export a real .xlsx from Postgres in one click, or put the query on a schedule and stop exporting it at all.