Convert Excel (XLSX) to Markdown Tables
.xlsx/.xls workbook in the browser, resolves shared strings and number formats, and writes each worksheet as a GFM pipe table. Dates stay dates, numeric columns right-align, and the file never leaves your machine.Processing happens 100% in your browser — nothing is uploaded.
Merged cells and formula caches
colspan, so a merged range keeps its value in the top-left cell and leaves the rest empty. Formula cells are exported as their cached result; a file written by a library without cached results will show those cells blank, and the converter tells you how many were affected.How to convert Excel to Markdown
- Drop: drag your .xlsx or .xls workbook onto the dropzone, or click to browse.
- Process: SheetJS unzips and parses every worksheet locally, computes column alignment, and escapes pipes.
- Copy: copy the GFM tables to your clipboard or download a .md file.
Why Convert Excel to Markdown with MD Convert?
Formatted values, not serial numbers
Excel stores a date as a number and its appearance as a style index. Cells are read as formatted text with dates enabled, so 2026-08-31 arrives as a date instead of as 46265, and currency symbols, thousands separators and percent signs survive the conversion.
Alignment derived from your data
Each column is inspected before the delimiter row is written: if every non-empty cell is numeric, the column gets `---:` and right-aligns. Currency, percentages and parenthesised negatives count as numeric; date columns stay left-aligned.
Every sheet, labelled and in order
Multi-sheet workbooks produce one H2 section per worksheet, named exactly as Excel names it, with a warning reporting the sheet count. Nothing is silently dropped and there is no picker to set wrong.
100% local — nothing is uploaded
The workbook is read through the File API and parsed by SheetJS in a Web Worker inside your tab. No fetch, no POST, no server copy — which is the only defensible way to convert salary data, client lists or unreleased financials.
Excel to Markdown: Before and After
Dates stay dates rather than becoming serial numbers, the number format survives, and the two numeric columns are right-aligned automatically. The sheet name becomes an H2 so multi-sheet workbooks stay navigable.
Sheet "Pipeline":
Region | Signed | Revenue | Share
EMEA | 2026-08-31 | 1,234.50 | 12.5%
APAC | 2026-09-01 | -98.25 | 40.0%
(Revenue is =SUM(...) with a cached result;
Signed cells are real dates, format yyyy-mm-dd)## Pipeline
| Region | Signed | Revenue | Share |
| --- | --- | ---: | ---: |
| EMEA | 2026-08-31 | 1,234.50 | 12.5% |
| APAC | 2026-09-01 | -98.25 | 40.0% |Understanding the Excel Format: ECMA-376 / ISO/IEC 29500
- Format
- Office Open XML Workbook (XLSX)
- Specification
- ECMA-376 / ISO/IEC 29500
- Media type
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet- Parser used
- SheetJS (xlsx)
An .xlsx file is not a spreadsheet in the way a CSV is a table — it is a ZIP archive containing a small XML filesystem. Inside are `xl/workbook.xml` (the sheet index), one `xl/worksheets/sheetN.xml` per sheet, `xl/sharedStrings.xml` (a deduplicated pool of every text value in the file), and `xl/styles.xml` (the number formats). A single cell is a `<c>` element carrying a reference like `B7`, an optional type, a value in `<v>`, and a style index pointing into the format table. Converting Excel to Markdown therefore means unzipping the archive, resolving three separate indirections per cell, and only then deciding what the cell should look like as text.
The legacy .xls format is a completely different animal: a BIFF8 compound binary document with its own record stream, not XML at all. SheetJS reads both and normalises them into the same in-memory workbook model, which is why this converter accepts .xls without a separate code path — and why an .xls file produced by Excel 97 still converts correctly today.
The detail that decides output quality is that Excel does not store a formatted string for most cells. It stores a raw number plus a format code. `2026-08-31` is stored as the number 46265 — days since the 1900 epoch — and the fact that it should be rendered as a date lives only in the style table. A converter that reads raw values and skips the style table will emit `46265` into your Markdown. It is valid output, it looks like plausible data, and it is wrong. This engine reads cells as formatted text so the value you see in Excel is the value that lands in the table.
How the browser reads an .xlsx without a server
When you drop a workbook onto the page, the file is read into an ArrayBuffer through the standard File API and handed to SheetJS, which is loaded on demand — the library is large, so it is dynamically imported the moment a spreadsheet conversion actually starts rather than shipped in the page bundle. SheetJS inflates the ZIP container, parses the worksheet XML, resolves shared strings, and hands back a workbook object. All of this is ordinary JavaScript running inside the tab, in a Web Worker so the interface stays responsive on a large file.
There is no upload step in that description because there is no upload. No fetch, no XHR, no multipart POST: the bytes move from your disk into the tab's memory and no further. That matters more for spreadsheets than for almost any other format, because spreadsheets are where salaries, customer lists, unreleased financials and clinical data live. A conversion tool that posts your workbook to a backend has, at minimum, created a copy you now have to reason about — retention windows, subprocessors, jurisdiction, breach notification. Converting in the browser removes the question rather than answering it.
The practical consequence is that this tool works on a locked-down machine with no outbound access to the converter's own API, and works offline once the page is cached. It also means the conversion cost scales with your CPU, not with a queue: a 5,000-row sheet finishes in well under a second on a modern laptop.
Formulas, cached values, and why they are almost always right
Excel stores two things for a formula cell: the formula itself (`=SUM(B2:B40)`) and the last result it calculated, cached in the file. SheetJS has no calculation engine — it does not evaluate `SUM` — so this converter exports the cached result. In practice that is exactly what you want: the number in the Markdown table is the number that was on screen when the workbook was last saved, which is the number a reader expects to see.
The failure mode is narrow and specific. If a file was generated by a library rather than by Excel, the producer may have written the formula without a cached result — many server-side writers do this deliberately and rely on Excel to calculate on open. Those cells have no value to export, so they come out blank. The converter counts them and raises an explicit warning telling you how many cells were affected and that opening the file in Excel or LibreOffice and saving it will populate them. Silence in that situation would be worse than the warning: an empty cell in a Markdown table looks like missing data, not like an unevaluated formula.
If you need the formula text itself rather than its result, no Markdown converter can help — Markdown has no formula concept. Copy the formulas into a column as text in the spreadsheet first, then convert, and they will come through as ordinary strings in a fenced-friendly table cell.
Multi-sheet workbooks, alignment, and pipe escaping
Every worksheet in the workbook is converted, in workbook order, as an H2 heading followed by its table. Nothing is dropped and nothing needs selecting: a three-sheet workbook produces three labelled sections in one Markdown document, and you delete the sections you do not want. The heading text is the sheet name exactly as Excel stores it, so `Q3 Summary` stays `Q3 Summary`. A warning reports the sheet count so a multi-sheet result is never a surprise.
Column alignment is computed from the data rather than guessed. For each column the converter inspects the body cells and, if every non-empty one is numeric, writes `---:` in the delimiter row so the column right-aligns — the convention every financial table follows, because right-aligned digits let you compare magnitudes down the column. Currency symbols, thousands separators, percent signs and accounting-style negatives in parentheses are recognised as numeric decoration; dates are not, so a date column stays left-aligned instead of being mistaken for numbers.
The pipe character is the one genuine hazard in Markdown tables, since a stray `|` inside a cell ends the cell early and shifts the rest of the row. Any pipe in your data is escaped as `\|`, and hard line breaks inside a cell — common in wrapped Excel text — are collapsed to spaces, because GFM tables cannot contain a literal newline inside a cell. Both transformations are lossless in the sense that they preserve the reading text; they only change how it is delimited.
Excel to Markdown versus CSV export, Pandoc, and copy-paste
Exporting to CSV and converting that is the most common workaround, and it costs you three things: the sheet names, the number formatting, and correctness on any cell containing a comma, a quote or a newline. CSV also collapses a workbook to a single sheet per file, so a five-sheet model becomes five exports. Reading the .xlsx directly avoids the delimiter question entirely — there is no delimiter to get wrong when you are parsing XML.
Pandoc is the reference tool for document conversion but does not read .xlsx at all; you would still be exporting to CSV first, and you would be installing a toolchain to do it. A Python pipeline with pandas and `to_markdown()` is a reasonable fit if the conversion is part of an automated job, but it needs an environment, and `read_excel` inherits the same date-serial pitfall unless you configure it carefully.
Copy-pasting the grid into a Markdown editor works for a five-row table and fails past that, because you are hand-building the delimiter row and hand-escaping pipes. The browser converter is the right tool when the task is ad hoc, the data is confidential, and you want the result in the clipboard in about two seconds. For scheduled or high-volume work, generate the Markdown in your own pipeline — the tradeoff is setup cost, not output quality.
Known limitations of Excel to Markdown conversion
Being explicit about what a converter cannot do saves you a wasted upload. These are the boundaries of what is recoverable from Excel programmatically:
- Merged cells cannot be represented: GFM tables have no colspan or rowspan, so the value lands in the top-left cell of the merged range and the remaining cells come through empty.
- Charts, pivot tables, images, conditional formatting, cell colours and comments are not converted. Markdown has no equivalent for any of them.
- The first row of each sheet is treated as the header row. A sheet whose first row is a title banner rather than column names will produce a table with that banner as its header — delete the banner row before converting.
- Formula cells with no cached result are exported blank, with a warning naming the count. There is no calculation engine in the browser to evaluate them.
- Very wide sheets stay wide: a 40-column table is valid Markdown but is painful to read in a rendered document. Trim columns in the spreadsheet first.
Who Converts Excel to Markdown?
Financial analyst
Pastes a quarterly model summary into a Confluence page or a GitHub release note without screenshotting the sheet.
Data analyst
Turns a stakeholder's workbook into a reviewable diff — Markdown tables show up line-by-line in pull requests, binary .xlsx files do not.
Technical writer
Maintains a compatibility or pricing matrix in a spreadsheet and publishes it into docs-as-code without hand-retyping the grid.
RAG pipeline engineer
Flattens tabular source data into Markdown so an embedding model reads a table instead of an unparsed binary attachment.
How You Can Verify the Privacy Claim
Zero server upload
Conversion runs inside your browser tab. Open DevTools, switch to the Network panel, and convert a file: for every format except URL to Markdown you will see no request carrying your document — because there is no endpoint to send it to.
Off the main thread
Heavy parsing is dispatched to a Web Worker, so a 500-page PDF or a large spreadsheet never freezes the interface. Everything is plain JavaScript — no native plugin, no WebAssembly toolchain, nothing to install.
Nothing to sign up for
No login, no quota, no paywall, and no tracking tied to your files. Analytics are cookieless and aggregate only. Read the privacy policy for the full data-flow breakdown, including the one proxied exception.
The parsers doing the work
No proprietary black box: each format is handled by a widely audited open-source library, running client-side at the version pinned in our lockfile.
Excel to Markdown — FAQ
Are formulas converted or just their values?
Values. Excel caches the last calculated result of every formula in the file, and that cached result is what lands in the Markdown table — the same number you saw on screen when the workbook was saved. There is no calculation engine in the browser, so a formula written by a third-party library without a cached result comes through blank, and the converter raises a warning naming the count. Opening the file in Excel or LibreOffice and re-saving it populates the cache.
What happens with multi-sheet workbooks?
Every worksheet is converted, in workbook order. Each becomes an H2 heading carrying the sheet name followed by its own GFM table, all in one Markdown document, and a warning reports how many sheets were found. Delete the sections you do not need — that is faster than re-running a conversion because a sheet selector defaulted to the wrong tab.
Why do my dates come out correctly here but as numbers elsewhere?
Because Excel stores dates as serial numbers — days since the 1900 epoch — with the date formatting held separately in the style table. Tools that read raw cell values without consulting that table emit 46265 instead of 2026-08-31. This converter reads cells as formatted text with date parsing enabled, so the displayed value is the exported value. The same applies to percentages, which are stored as fractions.
What happens to a cell containing a pipe character?
It is escaped as \| so the table row cannot break. A raw pipe inside a GFM table cell terminates that cell early and shifts every column after it, which is the most common way a converted table ends up mangled. Hard line breaks inside a cell are also collapsed to spaces, because GFM tables cannot contain a newline within a cell.
How large a workbook can it handle?
The practical limit is your device's memory, not a server quota — there is no upload cap because there is no upload. Parsing runs in a Web Worker so the page stays responsive, and sheets of several thousand rows convert in well under a second on a modern laptop. Very large files (tens of megabytes) will spike memory while SheetJS holds the workbook in RAM; if you only need part of the data, delete the unused sheets first.