Data & CSV

Excel (XLSX) to CSV converter

Turn a sheet (or every sheet) of an Excel .xlsx workbook into CSV, with real dates, your choice of separator and quotes, and a report of formulas, merged cells and hidden sheets.

Excel (XLSX) to CSV converter
Esc to restore

Your inputs

An .xlsx file of up to 30 MB (up to 2,000 entries and 200 MB when unpacked, and 2 million filled cells per sheet). Old .xls, .xlsb, password-protected and OpenDocument files are not supported. Files are read in this browser only and are never uploaded.

Built-in sample workbooks so you can try the options. They are used only when no file is chosen.

The name of the sheet, or its position counted from 1 in the workbook (hidden sheets count). A sheet whose name is a number is found by name first.

A CSV cell that starts with = + - or @ is run as a formula when the file is opened in a spreadsheet. Turn this on if the workbook came from someone you do not trust and the CSV will be opened in Excel.

Results update as you type. Larger files run when you press Update result.

Your result

Your result will appear here.

More actions

Your inputs stay in this browser. Nothing is uploaded or saved.

A clear answer. Here’s how.

An .xlsx file is a ZIP of XML parts (ECMA-376). The tool unpacks it with fflate, checks the limits first (at most 2,000 entries and 200 MB unpacked, so a zip bomb is refused before anything is inflated), reads the sheet list and the date system from workbook.xml and the relationships, and reads each sheet row by row. Cell text comes from the shared string table (rich-text runs are joined and phonetic guides left out), inline strings, booleans (TRUE and FALSE), errors such as #DIV/0!, numbers, and the stored result of each formula; there is no calculation engine, so a formula that was saved without a result is left empty and counted. A number is a date or time when its cell format says so: the built-in formats 14 to 22, 27 to 36, 45 to 47 and 50 to 58, or a custom format code with y, m, d, h or s outside quotes and brackets (m means minutes after h or before s). Serials are converted with the 1900 system, in which day 1 is 1900-01-01 and day 60 is the 1900-02-29 that Excel wrongly believes in, or with the 1904 system when workbook.xml says date1904. Dates become ISO 8601 text (2023-03-15, 2023-03-15T14:30:00, 09:05:00), or stay serial numbers if you prefer. Other numbers are written as stored without their display format: a cell showing 25% is 0.25, a currency cell has no symbol. With “15 significant digits” a stored 0.30000000000000004 becomes 0.3 as Excel shows it; “exactly as stored” keeps every digit. Every row is padded to the last used column. Merged ranges keep their value in the top-left cell only, as Excel does. Time-only formats are written as HH:MM:SS (with milliseconds only when there are some) and elapsed times such as [h]:mm:ss as hours:minutes:seconds, so a day and a half is 36:00:00. While it was built the converter was compared with the dates and values that Microsoft Excel itself displays for workbooks Excel saved, and with openpyxl, on a range of real workbooks. Not supported: .xls, .xlsb, encrypted workbooks, formula text (only results), charts, pivot tables and cell styles.

How this is checked

5 reference checks passed These 5 cases were run when this page was built, on 20 October 2026, and all reproduce within the stated tolerance. The same cases are part of the automated tests that run on every change to Toolmoz. Engine version 1.

See the checks and where each expected answer comes from
  1. Case 1

    Inputs
    The tool’s default inputs
    Expected, and what Toolmoz gave
    Sheet converted expected Orders, Toolmoz OrdersRows expected 7, Toolmoz 7Columns expected 6, Toolmoz 6Filled cells expected 31, Toolmoz 31Merged ranges expected 1, Toolmoz 1Formulas expected 3, Toolmoz 3Formulas without a stored result expected 1, Toolmoz 1Date and time cells converted expected 4, Toolmoz 4Date system expected 1900, Toolmoz 1900Sheets in the workbook expected 3, Toolmoz 3text expected Order ID,Customer,Ordered,Amount (GBP),Paid,Notes 1001,Ada Lovelace,2023-03-15,1234.5,TRUE,Rich bold text 1002,"Smith, John",2023-03-16T14:30:00,99.99,FALSE,"line1 line2" 1003,Zoë Müller,2024-02-29,0.3,TRUE,"said ""hi""" ,Total,,1334.79,, ,Opens at,09:05:00,#DIV/0!,, Merged note,,0.255,,, , Toolmoz Order ID,Customer,Ordered,Amount (GBP),Paid,Notes 1001,Ada Lovelace,2023-03-15,1234.5,TRUE,Rich bold text 1002,"Smith, John",2023-03-16T14:30:00,99.99,FALSE,"line1 line2" 1003,Zoë Müller,2024-02-29,0.3,TRUE,"said ""hi""" ,Total,,1334.79,, ,Opens at,09:05:00,#DIV/0!,, Merged note,,0.255,,,
    Where the expected answer comes from
    The workbook was written with openpyxl 3.1.5 from the Python values listed in the sample (and edited by a script to add shared strings and two cached formula results); the expected CSV was built in Python from those same values with the RFC 4180 quoting rules, 15 significant digits (format .15g) and ISO dates, not read back from the file. The 31 filled cells, 3 formulas, 1 formula without a stored result (=D5*2), 1 merged range (A7:B7) and 4 date or time cells (C2, C3, C4, C6) are counted by hand from that data
    Allowed difference
    exact
  2. Case 2

    Inputs
    Sheet name or number Summary
    Expected, and what Toolmoz gave
    Sheet converted expected Summary, Toolmoz SummaryRows expected 3, Toolmoz 3Columns expected 2, Toolmoz 2text expected Metric,Value Orders,3 Revenue,1334.79 , Toolmoz Metric,Value Orders,3 Revenue,1334.79
    Where the expected answer comes from
    The Summary sheet holds the Python rows [Metric, Value], [Orders, 3], [Revenue, 1334.79]; selecting a sheet by name must give exactly that table
    Allowed difference
    exact
  3. Case 3

    Inputs
    Convert allHidden sheets skip
    Expected, and what Toolmoz gave
    Sheets converted expected 2, Toolmoz 2Sheets in the workbook expected 3, Toolmoz 3Rows expected 7, Toolmoz 7
    Where the expected answer comes from
    The workbook has three sheets, one of them (Hidden) hidden; skipping hidden sheets leaves two, and the longest of them, Orders, has 7 rows
    Allowed difference
    exact
  4. Case 4

    Inputs
    Column separator ;Quote fields nonnumericLine endings crlfDates and times serial
    Expected, and what Toolmoz gave
    text expected "Order ID";"Customer";"Ordered";"Amount (GBP)";"Paid";"Notes" 1001;"Ada Lovelace";45000;1234.5;TRUE;"Rich bold text" 1002;"Smith, John";45001.6041666667;99.99;FALSE;"line1 line2" 1003;"Zoë Müller";45351;0.3;TRUE;"said ""hi""" ;"Total";;1334.79;; ;"Opens at";0.378472222222222;"#DIV/0!";; "Merged note";;0.255;;; , Toolmoz "Order ID";"Customer";"Ordered";"Amount (GBP)";"Paid";"Notes" 1001;"Ada Lovelace";45000;1234.5;TRUE;"Rich bold text" 1002;"Smith, John";45001.6041666667;99.99;FALSE;"line1 line2" 1003;"Zoë Müller";45351;0.3;TRUE;"said ""hi""" ;"Total";;1334.79;; ;"Opens at";0.378472222222222;"#DIV/0!";; "Merged note";;0.255;;;
    Where the expected answer comes from
    Expected text built in Python: serial 45000 is 2023-03-15 (Excel and openpyxl agree), 45351 is 351 days later, 2024-02-29, and 0.378472222222222 is 09:05 as a fraction of a day (545 / 1440); semicolon separator, every text cell quoted and numbers and booleans bare, CRLF line ends
    Allowed difference
    exact
  5. Case 5

    Inputs
    If no file is chosen, convert mac1904
    Expected, and what Toolmoz gave
    Date system expected 1904, Toolmoz 1904Rows expected 5, Toolmoz 5text expected Label,When epoch,1904-01-01 same day as 45000 in the 1900 system,2023-03-15 leap day,2024-02-29 with a time,2023-03-15T18:00:00 , Toolmoz Label,When epoch,1904-01-01 same day as 45000 in the 1900 system,2023-03-15 leap day,2024-02-29 with a time,2023-03-15T18:00:00
    Where the expected answer comes from
    Written by openpyxl with its 1904 calendar (serial 0 is 1904-01-01, serial 43538 is 2023-03-15, 1462 days less than the 1900-system serial 45000); the expected CSV is the list of Python dates
    Allowed difference
    exact

What this shows: the engine reproduces independently worked values for these cases. It does not prove every possible input is right. To test an answer you were given, see how to check a number; to see what is and is not checked across Toolmoz, see the accuracy ledger.

See a worked example

Worked example

A fixed demonstration, separate from the values you enter above.

If no file is chosen, convert
Sample: orders (three sheets, one hidden)
Sheet name or number
1
Convert
One sheet
Hidden sheets
Include hidden sheets
Dates and times
ISO 8601 text (2023-03-15, 2023-03-15T14:30:00)
Numbers
As Excel shows them: 15 significant digits
Column separator
Comma
Quote fields
Only when needed
Line endings
LF (Unix, macOS)
UTF-8 byte order mark
None
Protect against spreadsheet formulas
Exact text

Example result

First 5 rows of the example result
ABCDEF
Order IDCustomerOrderedAmount (GBP)PaidNotes
1001Ada Lovelace2023-03-151234.5TRUERich bold text
1002Smith, John2023-03-16T14:30:0099.99FALSEline1 line2
1003Zoë Müller2024-02-290.3TRUEsaid "hi"
Total1334.79

No file was chosen, so the built-in sample workbook was converted. Choose your own .xlsx file above to convert it instead. Hidden sheets in this workbook: Hidden. 1 formula cell has no stored result (the workbook was saved without calculating, for example by a script), so it is left empty. Open the workbook in Excel and save it again to store the results. 1 merged range: as in Excel, only the top-left cell of a merged range holds the value. Dates and times use ISO 8601 and numbers are written as stored, without their display format (a cell showing 25% is 0.25). Cached formula results are used.