Home · Free tools · Excel to SQL
Excel to SQL
Drop a .xlsx or .csv, name the table, pick the database. You get a CREATE TABLE whose column types are inferred from the data — integers, decimals, dates, booleans, text sized to the longest value — and INSERT statements in batches you can paste into a console or run as a file. Reference numbers with leading zeros stay text, amounts with thousands separators become numbers, and nothing is uploaded.
Your spreadsheet
Drop .xlsx or .csv here, or click to choose
Nothing is uploaded. The file is read by JavaScript in this tab and never leaves your computer — no server sees it, and closing the tab throws it away.
How to convert an Excel sheet to SQL
- Drop the file. A .xlsx with several sheets shows a sheet picker; a CSV is read with its encoding detected, so accented text and CJK survive.
- Check the inferred types. The column table shows what each column became. A column of numbers with a leading zero is kept as text on purpose; change the header or the data if you want it numeric.
- Pick the dialect and batch size. Quoting, boolean literals and the maximum rows per INSERT differ between MySQL, PostgreSQL, SQLite and SQL Server; the output follows the one you chose.
- Copy or download. Copy the SQL to the clipboard for a console, or download the .sql file to run with your client of choice.
What the types are inferred from
Every value in a column is looked at, not just the first few rows. A column becomes an integer only if
every non-empty value is a whole number without a leading zero; a decimal if every value parses as a
number once currency symbols and thousands separators are removed; a date or timestamp if every
value is ISO-shaped (2026-09-06, optionally with a time); a boolean if every value is
true/false or yes/no. Anything else is text, sized to the longest value with headroom —
VARCHAR(50), VARCHAR(100) — and switched to TEXT when that
would exceed 255 characters. Empty cells become NULL in every type.
The one rule that surprises people is deliberate: 00012345 is text. Invoice numbers,
account numbers, postcodes and product codes carry their leading zeros as part of the identifier,
and a column that loses them on import is the first thing a reconciliation trips over later.
Four dialects, four sets of details
- MySQL / MariaDB — backtick-quoted identifiers,
DECIMAL(18,4)for money,TRUE/FALSE,VARCHARup to 255 thenTEXT. - PostgreSQL — double-quoted lower-case identifiers,
NUMERIC(18,4),TEXTfor strings (it costs nothing there),TIMESTAMPfor dates. - SQLite — its four storage classes:
INTEGER,REAL,TEXT; dates stay text, which is what SQLite itself recommends. - SQL Server — bracketed identifiers,
NVARCHARwithN'…'literals so non-Latin text survives,BITfor booleans, and INSERTs capped at 1,000 rows each because that is the server's own limit per statement.
Column names become identifiers
Headers are turned into safe identifiers: spaces and punctuation become underscores, everything is
lower-cased, a leading digit gets an underscore in front, and a repeated header gets a number
(amount, amount_2). Empty headers are named by position. The original
header text is not lost — it is visible in the column table above the SQL, so you can rename in the
sheet and drop it again if the generated name is not what you want.
What it does not do
- No primary keys, indexes or constraints are guessed; add them after the load, when you know which column is actually unique.
- Formulas are converted as the value Excel last calculated, not as the formula.
- Merged cells, formatting and comments are ignored; only the grid is read.
- Very large sheets work, but a million-row INSERT script is a slow way to load a database — for that size, export CSV and use the database's bulk loader.
Nothing leaves this tab
The file is parsed and the SQL is written by JavaScript in your browser. The customer list or price table you are about to load into a database is not uploaded to this site or anywhere else.
Questions people ask
How do I convert Excel to SQL insert statements?
Drop the workbook, pick the sheet, name the table, and the INSERT statements are generated in batches — 500 rows each by default — with a CREATE TABLE in front. Copy them or download the .sql file.
Does it work with CSV files?
Yes. A CSV is read with its delimiter and encoding detected, so a semicolon-separated export from a European locale or a GBK/Shift-JIS file comes through intact.
Why is my numeric column typed as VARCHAR?
One of three reasons: a value has a leading zero (kept as text on purpose), a value is not a number at all (a stray "n/a" or a note), or the numbers use a thousands separator that could not be told apart from a decimal point. Sort the column in the sheet and look at the ends; the odd value is usually there.
Can I load the file straight into the database instead?
For a one-off table this script is the quickest route. For a feed that arrives every week, the TableDI desktop app keeps the mapping and the types as a job and writes to PostgreSQL, MySQL or SQLite directly, so the second week is a drop-and-run.
Are my files uploaded anywhere?
No. The file is read by JavaScript running in this tab, using the browser's own
DecompressionStream to unzip .xlsx and a parser that runs on your machine. There is no
server call in the page — you can watch the network tab while you use it. Close the tab and the data is gone.
Does it work with old .xls files?
Not directly. The .xls format is a different, binary format from Excel 97. Open it in Excel, LibreOffice or Numbers and save as .xlsx or .csv, then come back. The tool tells you this rather than failing silently.
Related
Do this on your own machine instead
TableDI is a desktop spreadsheet workspace that runs entirely on your machine. Import the file, fix it, chart it — nothing is uploaded, and there is no account to create.
Free forever, not a trial — no account, no card. macOS today; a Windows build is in progress. What the paid tier adds.
Last reviewed 2026-09-01 by the TableDI team. Something wrong on this page? Tell us — it is one inbox, read by the people who build TableDI.