Excel to SQL Converter
Generate SQL scripts from worksheet rows. Choose a dialect, review the output, then copy or download the script.
Drop your file here or click to upload
Supports .xlsx, .xls, .xlsm, .xlsb · up to 50MB · or paste a file from your clipboard
How to Convert Excel to SQL
- Upload an Excel workbook - .xlsx, .xls, .xlsm and .xlsb are read. The table name is seeded from the file name.
- Pick the sheet and dialect - PostgreSQL, MySQL or SQLite. The choice changes identifier quoting, the boolean literals and the inferred type names.
- Decide on headers and CREATE TABLE - Use row 1 for column names or fall back to
Column 1,Column 2; include or omit the CREATE TABLE statement. - Review the script and export - Read the generated SQL in the panel, then copy it or download a .sql file.
What the generated script contains
An optional CREATE TABLE with one column per header and an inferred type, then one INSERT INTO ... VALUES per data row, each carrying the full column list so the statements are order-independent and safe to reorder or split. Statements are separated by a blank line.
CREATE TABLE "sales_2024" (
"region" TEXT,
"revenue" DOUBLE PRECISION
);
INSERT INTO "sales_2024" ("region", "revenue") VALUES ('North', 42000);
INSERT INTO "sales_2024" ("region", "revenue") VALUES ('South', 36500.5);Nothing else is generated: no DROP TABLE, no BEGIN/COMMIT, no primary key, no indexes, no ON CONFLICT or ON DUPLICATE KEY UPDATE, and no schema qualifier. The script is meant to be read before it is run.
How the three dialects differ
| Dialect | Identifier quoting | Booleans | Numeric types |
|---|---|---|---|
| PostgreSQL | "name", inner quotes doubled | TRUE / FALSE | INTEGER, DOUBLE PRECISION |
| MySQL | `name`, inner backticks doubled | TRUE / FALSE | INT, REAL |
| SQLite | "name", inner quotes doubled | 1 / 0 | INTEGER, REAL |
How each cell becomes a literal
- Empty cells and empty strings become
NULL. There is no way to distinguish a blank cell from a deliberately empty string in the output - if that distinction matters, put a sentinel in the sheet first. - Numbers are written unquoted, with floating-point noise trimmed to twelve significant digits so
57.809999999999945is written as57.81, matching what Excel displays. An infinite or NaN value becomesNULL. - Text is wrapped in single quotes with any embedded single quote doubled, so
O'Brienis written'O''Brien'. - Booleans follow the dialect column above.
- Dates, times, currency and percentages arrive as their raw numbers:
45000,1234.5,0.15. - Formula cells contribute their cached result, never the formula text.
- Error cells such as
#N/AbecomeNULL.
Edge cases
- The header row sets the column count.With "first row as headers" on, the width of row 1 decides how many columns exist; cells further right on later rows are dropped. A sheet whose header row is shorter than its data needs the header filled in first.
- Short rows are padded with
NULL, so every INSERT has the same number of values. - Backslashes are not escaped. Correct for PostgreSQL and SQLite; a hazard on MySQL, where a backslash is an escape character by default.
- Merged cells lose their span. Only the top-left cell of a merged range holds the value; the rest of the range inserts as
NULL. - Numbers stored as text stay text. A column that Excel flags with the green triangle is a column of strings, so it is typed
TEXTand quoted in every INSERT. Fix it in the workbook with Convert Text to Number before exporting. - Blank leading rows count.The export starts at the sheet's used range, so a title row above the table becomes the header row unless you remove it first.
When to use a different tool
- Loading a very large sheet: export Excel to CSVand use your database's bulk loader (
COPY,LOAD DATA INFILE,.import) instead of row-by-row INSERTs. - Going the other way, from a dump back to a workbook: SQL to Excel.
- Feeding an API or a script rather than a database: Excel to JSON or Excel to JSONL.
- Messy headers, stray blank rows or duplicate keys before export: Excel Cleaner and Remove Duplicates.
Frequently Asked Questions
Excel stores a date as a number - 45000 is 15 March 2023 - and the format that displays it is not part of the value. The generator reads values, so date cells arrive as those serial numbers and the column is typed INTEGER. There is no DATE inference. If you need real dates, add a helper column in the workbook with =TEXT(A2,"yyyy-mm-dd"), export that, and cast it in the database, or ALTER the column after loading.
No. Single quotes are doubled ('' inside a literal), which is standard SQL and correct for PostgreSQL and SQLite. MySQL additionally treats a backslash as an escape character unless NO_BACKSLASH_ESCAPES is set, so a value such as C:\new\table would change meaning on the way in. Check any column holding Windows paths, regular expressions or LaTeX before running a MySQL script.
Each header is lowercased, every run of characters outside a-z, 0-9 and underscore becomes a single underscore, and leading and trailing underscores are removed - so 'Order Date' becomes order_date and 'Total ($)' becomes total. A name that would start with a digit, or that collides with one of the reserved words the generator knows (select, from, where, table, group, order, insert, update, delete, create, drop, index), gets a leading underscore. Duplicate names are numbered: name, name_2, name_3.
Per column, over the data rows only, ignoring blanks. All booleans gives BOOLEAN (INTEGER on SQLite); all whole numbers gives INTEGER, or INT on MySQL; all numbers with a decimal gives DOUBLE PRECISION on PostgreSQL and REAL elsewhere; anything else, including a column that mixes numbers and text, gives TEXT. A column that is entirely empty is TEXT. No lengths, keys, indexes or NOT NULL constraints are generated - the CREATE TABLE is a starting point, not a schema.
One INSERT statement is written per row, each with the full column list, and the whole script is held in the browser as a single string before you copy or download it. That is fine for thousands of rows and slow for hundreds of thousands. For very large sheets, split the workbook first or load the data as CSV with your database's bulk loader instead.
No, and it never asks for credentials. It writes a script you read and run yourself. There is no transaction wrapper, no DROP TABLE, and no ON CONFLICT clause, so review the output and add whatever your load process needs.