Home › Guides › Python

How to convert XLSX to CSV in Python

Convert Excel files to CSV with pandas or openpyxl: one sheet, every sheet, .xls/.xlsb/.ods engines, huge files, and why values differ from what Excel shows.

Python is the usual tool for converting Excel files to CSV in scripts and data pipelines. The two common routes are pandas, which is short and handles every sheet at once, and openpyxl, which streams huge files row by row. Both read the values stored in the file, not what Excel displays, which matters for dates, money and leading zeros. Here's how to get it right.

Convert XLSX to CSV with pandas

Install the libraries once:

pip install pandas openpyxl

Then one sheet is two lines:

import pandas as pd

df = pd.read_excel("workbook.xlsx", sheet_name="Orders", dtype=str, keep_default_na=False)
df.to_csv("orders.csv", index=False, encoding="utf-8")

Every sheet at once

Pass sheet_name=None to get a dictionary of all sheets:

import pandas as pd

sheets = pd.read_excel("workbook.xlsx", sheet_name=None, header=None, dtype=str, keep_default_na=False)
for name, df in sheets.items():
    df.to_csv(f"{name}.csv", index=False, header=False, encoding="utf-8-sig")

header=None plus header=False copies the rows exactly, without pandas treating the first row specially. utf-8-sig adds a BOM so Excel opens the files with accents intact. If a sheet name contains / or \, clean it before using it as a file name.

.xls, .xlsb and .ods files

pandas picks a reader (an “engine”) by file type, and each needs its own package:

FileInstallEngine
.xlsx, .xlsmpip install openpyxlopenpyxl (default)
.xlspip install xlrdxlrd (default)
.xlsbpip install pyxlsbpyxlsb
.odspip install odfpyodf
Any of these, fasterpip install python-calaminecalamine

Choose an engine with pd.read_excel("file.xlsb", engine="calamine"). The calamine engine reads all the formats above and is much faster on big files.

Huge files: stream with openpyxl

pandas loads the whole sheet into memory. For files with millions of cells, stream them instead:

import csv
from openpyxl import load_workbook

wb = load_workbook("workbook.xlsx", read_only=True, data_only=True)
for ws in wb.worksheets:
    with open(f"{ws.title}.csv", "w", newline="", encoding="utf-8") as f:
        writer = csv.writer(f)
        for row in ws.iter_rows(values_only=True):
            writer.writerow(["" if v is None else v for v in row])
wb.close()

read_only=True streams rows instead of loading everything, and data_only=True gives the last calculated value of each formula rather than the formula text. newline="" stops Windows adding blank lines between rows.

The catch: values, not what you see

Both pandas and openpyxl return the value stored in the cell and ignore its number format. So:

That's often what you want for a database. If you need the CSV to match what Excel shows, convert with xlsxtocsv.com, which applies each cell's number format, or with LibreOffice from the command line.

Skip the steps: convert every sheet to CSV in your browser, free.

Convert XLSX to CSV