Excel to SQL Converter
Upload Excel file to convert to SQL INSERT statements
Drop Excel file here or click to select file
What is Excel to SQL?
Excel to SQL is an online data format conversion tool that converts Excel (.xlsx/.xls) files into SQL INSERT statements for easy database import.
Excel is the most commonly used spreadsheet format, widely used for data storage and analysis. SQL is the standard query language for relational databases, and INSERT statements are used to insert data into database tables.
With this tool, you can quickly convert Excel spreadsheet data into executable SQL statements, supporting multiple sheet selection, custom table names, and quote styles for convenient data migration and import operations.
How to Use
How to use
- Upload an Excel file (.xlsx or .xls format)
- If multiple sheets exist, select the sheet to convert
- Set the table name (default is table_name)
- Choose whether to use the first row as field names
- SQL INSERT statements are auto-generated, copy with one click
SQL Generation Checks
- Inspect column names, data types, quotes, and NULL handling before running generated SQL against a real database.
- For production imports, test on a temporary table first and keep a backup of the original spreadsheet.
Use Cases
Technical Principle
The page parses the uploaded workbook with SheetJS - XLSX.read(arrayBuffer, {type: 'array'}) returns a workbook object whose worksheet has cells indexed by A1 keys, then XLSX.utils.sheet_to_json(sheet, {header: 1, defval: null}) walks the bounded !ref range into an array of arrays. The first non-empty row (when first-row-as-header is on) is taken as column names; otherwise SheetJS-style col1, col2, col3 are synthesized. Each remaining row is emitted as a single SQL statement of the form INSERT INTO `table` (`c1`, `c2`, ...) VALUES (v1, v2, ...);, with optional CREATE TABLE `table` (`c1` VARCHAR(255), ...); prepended. Identifier quoting varies by SQL dialect and is governed by the SQL:1992 standard and each vendor's deviation: standard SQL and PostgreSQL quote identifiers with double quotes ("col"), MySQL and MariaDB use backticks (`col`) by default and only accept double quotes when ANSI_QUOTES SQL mode is on, SQLite accepts both backticks and double quotes (and, for backwards compatibility, treats double-quoted identifiers that don't resolve as string literals - a well-known footgun documented in the SQLite Quirks page), SQL Server and Sybase use square brackets ([col]). Value quoting follows SQL string-literal rules: single quotes wrap the literal and are escaped by doubling them ('O''Brien'), per ISO/IEC 9075. Empty cells map to the unquoted literal NULL, not the empty string ''; numeric cells with cell.t === 'n' are emitted unquoted; booleans become 1/0 or TRUE/FALSE depending on dialect; dates require explicit handling. Date cells need special care because SheetJS preserves the underlying numeric serial: Excel stores dates as days since 1900-01-01 with the historical 1900-02-29 leap-year bug shifting pre-March-1900 dates by one day, and the Excel-for-Mac 1904 system uses 1904-01-01 as epoch instead. The conversion to ISO 8601 (YYYY-MM-DD HH:mm:ss, the format MySQL DATETIME and PostgreSQL TIMESTAMP both accept) is (serial - 25569) * 86400000 ms after the Unix epoch, then formatted in UTC. Type inference is purely lexical and shallow: a column whose first non-empty cell is integer becomes INT, decimal becomes DECIMAL(10,2), text becomes VARCHAR(255), and a column starting with 2024-01-01 may be exported as a string unless the source cell carries cell.t === 'd'. Bulk inserts are emitted as one INSERT per row, which is slow at scale; combining 100-500 rows into a single INSERT INTO t VALUES (...), (...), (...); reduces network round trips by ~100x, and wrapping the script in BEGIN; ... COMMIT; turns the import into one atomic transaction that rolls back on the first failed row.
- Identifier quoting by dialect: MySQL/MariaDB `col` (backticks, or "col" with ANSI_QUOTES on); PostgreSQL and standard SQL "col"; SQL Server [col]; SQLite accepts both (but "col" silently falls back to a string literal when col is not a known identifier).
- String literal escape (ISO/IEC 9075): wrap with single quotes and double internal single quotes (O'Brien → 'O''Brien'); never inline raw backslashes - PostgreSQL standard_conforming_strings defaults to on since 9.1.
- Excel date serial: days since 1900-01-01 with the 1900-02-29 bug (or 1904-01-01 if workbook.date1904 is true); ISO 8601 string = new Date((serial - 25569) * 86400000).toISOString().
- Type inference is lexical: integers → INT, decimals → DECIMAL(10,2), text → VARCHAR(255); dates that look like dates but aren't typed cell.t === 'd' export as strings; monetary cells with thousand separators export with the separator inside the string.
- NULL handling: an empty Excel cell becomes the unquoted literal NULL, not '' - the difference matters for NOT NULL columns and for COUNT(col) which skips NULLs but counts ''.
- Bulk insert: combining 100-500 rows into a single INSERT INTO t VALUES (...),(...),...; cuts network round trips ~100x versus one INSERT per row; MySQL's max_allowed_packet (default 64 MB) caps the per-statement size.
- Wrap the generated script in BEGIN;...COMMIT; (PostgreSQL/SQLite) or START TRANSACTION;...COMMIT; (MySQL InnoDB) so a single failed row rolls back the whole batch; MyISAM tables ignore the transaction and partially commit.
Examples
Excel sheet → INSERT statements
Sheet "users" (3 rows):
id | name | email | age
1 | Alice | alice@mail.com | 28
2 | Bob | bob@mail.com | 34
Generated SQL:
INSERT INTO users (id, name, email, age) VALUES (1, 'Alice', 'alice@mail.com', 28);
INSERT INTO users (id, name, email, age) VALUES (2, 'Bob', 'bob@mail.com', 34);Single multi-row INSERT (faster import)
Use the "combine rows" option for bulk loads:
INSERT INTO products (sku, name, price) VALUES
('A001', 'USB-C Cable', 9.90),
('A002', 'HDMI Adapter', 14.50),
('A003', 'Mouse Pad', 4.25);
Reduces 3 round trips to 1 — safer for batches of 100-500 rows.Quote escaping for names with apostrophes
Source cell: O'Brien
Generated SQL (single quotes doubled):
INSERT INTO customers (id, name) VALUES (42, 'O''Brien');
NULL handling — empty Excel cell becomes literal NULL, not '':
INSERT INTO customers (id, phone) VALUES (43, NULL);Wrap import in a transaction
BEGIN;
INSERT INTO orders (id, customer_id, total, created_at) VALUES (1001, 7, 199.50, '2026-06-01');
INSERT INTO orders (id, customer_id, total, created_at) VALUES (1002, 7, 42.00, '2026-06-02');
INSERT INTO orders (id, customer_id, total, created_at) VALUES (1003, 9, 78.30, '2026-06-03');
COMMIT;
If any row fails the whole batch rolls back.FAQ
Is the spreadsheet uploaded?
No. The file is parsed in your browser via SheetJS and the SQL is generated locally. Nothing is sent to a server, so even sensitive datasets stay on your device.
What SQL output does it produce?
A CREATE TABLE statement followed by individual INSERT INTO rows (one row per statement). The generated SQL uses the table name you entered and the quote style you selected (single, double, or backtick).
How are column types inferred?
The page samples each column and picks the narrowest type that fits: INTEGER, DECIMAL, VARCHAR(N), BOOLEAN, or DATE/DATETIME. You can override before generating SQL. Mixed-type columns fall back to VARCHAR.
What about Excel dates?
Excel dates are stored as serial numbers. The page outputs them as the raw value from the sheet. Check the generated SQL and adjust date literals to match your target database format if needed.
How are special characters and quotes escaped?
Single quotes are doubled (Smith's → Smith''s). Backslashes and Unicode pass through literally - this matches PostgreSQL standards-compliant strings. If you target MySQL with NO_BACKSLASH_ESCAPES disabled, you may need to escape backslashes manually.
Will the result work on MySQL, PostgreSQL, SQLite, MSSQL?
The basic INSERTs work on all four. The CREATE TABLE statement uses portable types (INT, VARCHAR, DECIMAL, DATE). For dialect-specific types (SERIAL, AUTO_INCREMENT, IDENTITY), edit the CREATE statement to match your target.
Are formulas evaluated?
No. The cached value Excel saved is used. Open the source workbook, recalculate, save, then re-upload if you need fresh formula values.