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.
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
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
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
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
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
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
| A | B | C | D | E | F |
|---|---|---|---|---|---|
| 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 |
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.