Excel to SQL, with the escaping right in all four dialects
This generator reads a sheet from an .xlsx workbook and writes CREATE TABLE and INSERT statements for MySQL, PostgreSQL, SQLite or SQL Server. The four dialects quote identifiers differently: backticks for MySQL, double quotes for PostgreSQL and SQLite, square brackets for SQL Server. MySQL also treats a backslash as an escape character inside string literals and the other three do not, so a generator that only doubles single quotes produces output that is correct in three dialects and silently wrong in the most widely deployed one. Column types are inferred from every row and can be overridden. The workbook is never uploaded.
That backslash rule is worth a second sentence, because it breaks on ordinary data rather than on anything exotic. A cell holding C:\Users\ana\report.xlsx inserts correctly on MySQL only if each backslash is doubled. Double it on PostgreSQL and you have added a character that was never in the spreadsheet. There is no single output that is right everywhere, which is why the dialect selector changes the escaping as well as the quote marks.
Type inference scans the whole column instead of sampling the first row. Integers inside int32 give INT, wider ones give BIGINT, a fractional part gives DECIMAL sized to the widest value actually present, and everything else falls to VARCHAR. One text value on row 401 makes the whole column text. Inference is still a guess about intent, so every column can be changed before you generate: a column of 007, 012 and 045 reads as text to a person and as an integer to a scanner, and the person is right.
Two problems stop the generator rather than being patched over quietly. Duplicate column names are refused and both positions are named, because auto-suffixing the second one to region_2 produces a script that runs and is wrong, and you find that out at query time. An empty header is refused the same way, named by its column letter.
Nothing here touches a database. There is no connection string, no query runner and no network call, so what you get is text you take somewhere else. That makes escaping a correctness problem rather than a security boundary. A cell containing '); DROP TABLE users;-- has to round-trip into a string literal that inserts that exact text, because that is what the data says, and getting it wrong corrupts a table whether or not anybody meant harm.
Dates come out as dialect-correct literals, so PostgreSQL gets DATE '2024-01-01' and the other three get the quoted string. Underneath, the spreadsheet stored that date as the number 45292. The Excel serial date converter explains where that number comes from.