Convert Parquet to CSV

Converting Parquet to CSV writes the rows of a columnar file out as plain delimited text that anything can open. It is the direction that loses information rather than the safe one — the CSV has no schema to carry the column types — and it runs entirely in your browser.

  • Where it runs In your browser. The file is never uploaded.
  • Lossless Nothing is discarded. The CSV holds exactly what the Parquet held.
  • File size limit Up to 100 MB per file, free, without an account.

Up to 100 files at once. Mixed formats are fine.

The direction that feels safe and is the lossy one

Going the other way is obviously a conversion: text becomes typed columns, and everyone expects to check the result. This direction feels like an export — the data comes out, nothing is compressed, nothing is inferred — and that impression is wrong in one specific and expensive way.

Parquet carries a schema. Every column has a declared type, recorded in a footer, and a query engine reads that footer before it reads a row. A CSV carries a header row of names and nothing else. So the conversion moves the values across intact and throws away everything the file knew about them, and the next tool to read it will infer the types again from the text — differently, in all likelihood, from what the Parquet file actually declared.

What each column type looks like once it is text

Booleans arrive as `true` and `false`. Integers and floating point numbers are written in their decimal form. Strings are written as they were, quoted only where the value contains a comma, a double quote or a line break. Nulls become empty fields.

None of that is reversible into the original schema. A column that Parquet declared as a 32-bit integer and a column it declared as a double both look like digits with an optional dot, and a boolean column and a text column containing the word "true" become indistinguishable. If the CSV is going to be loaded somewhere with a schema of its own, take the column types out of the Parquet file first — `DESCRIBE` in DuckDB prints them in one line — and write them into the load definition rather than letting the next tool guess.

Timestamps become ISO 8601 strings

A timestamp column is written as an ISO 8601 string, so a value comes out looking like `2024-03-11T09:30:00.000Z`. That is the best available answer in a format with no date type: it is unambiguous about which number is the month, it sorts correctly as plain text, and every database and language parses it without being told a format.

It is still text. A date column in the CSV will not respond to date arithmetic until whatever reads it is told the column is a date, and a spreadsheet opening the file will apply its own interpretation. If the destination is a database, declaring the column as a timestamp on load is one line and preserves the meaning; if it is a person, the ISO form at least reads the same way in every country.

Large integers widen to text instead of rounding

Parquet has a 64-bit integer type, and JavaScript — which is what runs the conversion — represents whole numbers exactly only up to 53 bits. A value beyond that point cannot be carried as a number without losing precision.

Rather than round it, the conversion writes it as text. An order reference or a snowflake identifier therefore appears in the CSV with every digit intact, and a column that mixes safe and unsafe values will have some entries that were numbers and some that were strings, which in a CSV look identical anyway. The alternative — rounding — produces a file where an identifier is off by one, which looks exactly like a valid identifier and is the kind of error that survives several systems before anyone notices.

Lists, structs and maps become JSON inside one field

Parquet holds nested data natively: a column can be a list of strings, a struct with named members, or a map. A CSV cell holds a single scalar and has no syntax for anything else.

The conversion writes those values as JSON into the field, so a list column arrives as `["a","b"]` in one cell, quoted because the JSON contains commas. That is reversible if whatever reads the file parses it, and it is deeply awkward if the destination is a spreadsheet or an import screen. Binary columns get similar treatment for the same reason: a byte array with no text annotation is written as lowercase hexadecimal, which is at least reversible and obviously not prose. If the file has nested columns and the destination is a person, flatten or drop them in a query before converting rather than sending a CSV full of embedded JSON.

The file gets a great deal larger

Expect several times the size, and sometimes far more than that. Parquet writes values in their binary form, compresses each column separately, and stores a column of repeated values once as a dictionary with small references into it. A CSV has none of those: every value is written out as characters, on every row, uncompressed.

The columns that collapsed hardest going in are the ones that expand hardest coming out. A country code repeated across a million rows cost almost nothing in the Parquet file and costs a million copies in the CSV. It is worth knowing before you try to email the result, and worth remembering that gzipping the CSV recovers a good part of the difference if the destination will accept it.

Opening the result in Excel, and the encoding it assumes

The CSV is UTF-8 with no byte order mark and a plain newline between rows. That is correct for scripts, importers and version control, and it is the thing that makes accented names appear as mojibake when the file is opened by double-clicking on Windows, because Excel falls back to the system code page when there is no mark.

Importing through Data, Get Data, From Text/CSV and choosing UTF-8 avoids it, and gives you the chance to mark identifier columns as text at the same time — which matters, because Excel will otherwise apply its own numeric conversion to the columns whose types were discarded a moment ago. If the destination is genuinely a spreadsheet, converting the Parquet file to XLSX instead removes the encoding question and keeps the types.

How many rows this can pull out of a Parquet file

The reader materialises every row before anything is written, so the whole table exists in memory at once. Tens of megabytes of Parquet is comfortable; note that this is a compressed format, so a modest file can expand to a great deal of text and the ceiling arrives sooner than the file size suggests.

For a large extract the correct tool is DuckDB, which will read the Parquet file and write a CSV in one statement without holding either. It also lets you select the columns you actually need, which is usually the better answer anyway — most requests for "the data as a CSV" turn out to be requests for six columns of it.

The extract is read on this page and goes no further

The Parquet reader is a library loaded on demand by this page and the writing is plain JavaScript, so no request carries the file anywhere. That matters more here than for most pairs: a Parquet file is normally an artefact from the middle of a data platform, which is to say the version before the masking and the aggregation.

There is no queue, no account and no row limit other than your own memory. The only thing that decides whether the conversion works is whether the expanded table fits, which you can estimate from the row count in the footer.

When to send the Parquet file as it is

If the recipient has any modern data tooling at all, send the original. DuckDB, pandas, Polars, R with arrow, Spark and every warehouse read Parquet directly, and doing so preserves the types, keeps the file small and removes an entire step in which something can go wrong.

Convert to CSV when the recipient genuinely cannot — a finance colleague with a spreadsheet, an audit request that names the format, an upload screen with a fixed list. Those are real and common, and this conversion is for them. What it should not be is a habit: every CSV produced from a Parquet file is a copy that has forgotten what it contains.

How to turn a Parquet file into a CSV

  1. Drop the Parquet file onto this page, or click to choose one.
  2. The rows are read and written out as comma-separated text, in your browser.
  3. Note the column types from the source before handing the CSV on.

Parquet and CSV: a typed column store flattened into text

Parquet compared with CSV
ParquetCSV
Full nameApache ParquetComma-Separated Values
File extension.parquet.csv
Media typeapplication/vnd.apache.parquettext/csv
CompressionLossless — nothing is discarded
First published20131972
Published byApache Software Foundation
SpecificationRFC 4180
LicensingOpen standardOpen standard
Standing todayCurrentCurrent
Opens in a browserNo browserNo browser
Considered insteadJSONXLSX, JSON

What survives

Nothing is discarded. Parquet and CSV both store their content losslessly, so the conversion is a change of packaging rather than a change of quality, and it can be repeated without accumulating damage.

What the target format adds

CSV is a working format and Parquet is a finished one. What comes back is editable text and objects rather than a picture of a page, which is usually the reason for the conversion and also where its limits are.

Opening the result

pandas reads both Parquet and CSV, so there is a way to check the result against the original without a second tool.

What each format is for

CSV dates from 1972, specified as RFC 4180. Microsoft Excel, LibreOffice Calc and pandas all read it.

CSV was published in 1972 and Parquet in 2013. The older one is generally the safer file to hand to somebody; the newer one usually does the job in fewer bytes.

Parquet to CSV: types, size and nested columns

Are my Parquet files uploaded anywhere?

No. This conversion runs entirely inside your browser, so the file never leaves your device. You can confirm it yourself: open the network tab of your browser's developer tools and convert something. You will see the page load, plus the analytics and advertising the site is paid for with — and nothing carrying your file. The engine behind this particular pair is parquet-wasm, a WebAssembly build of the Apache Arrow reader; your browser fetches it once and caches it.

Is anything lost converting Parquet to CSV?

The schema. Parquet records the type of every column and CSV records none, so a column that was an integer, a boolean and a timestamp all arrive as text and whatever reads the file next has to guess again. The values themselves come across; the information about them does not.

What happens to timestamp columns?

They are written as ISO 8601 strings, so a timestamp becomes something like 2024-03-11T09:30:00.000Z. That is unambiguous and sorts correctly as text, which is the most a CSV can offer.

What about very large integers?

A 64-bit integer that fits safely becomes a number, and one that does not is written as text instead of being rounded. Silently rounding an order reference is worse than widening the column, so the conversion widens it.

What happens to a list or a struct column?

It is written as JSON inside a single field, because a CSV cell cannot hold a list. The field will be quoted, since the JSON contains commas, and whatever reads the file has to parse it back out.

How much bigger is the CSV?

Usually several times, sometimes far more. Parquet stores values in binary form, compresses each column and holds repeated values once; a CSV writes every value out as text on every row with none of that.

Is the Parquet file uploaded?

No. The reader runs in your browser, so the file stays on your machine, which matters because a Parquet extract is usually the unmasked table rather than a report.

More about these formats