Skip to content
pdfconversionapi

XLSX to MD API

Send a workbook to POST /v2/convert/xlsx/to/md and get one Markdown file: a ## heading per worksheet followed by a pipe table of its cells. The sample's three sheets, the hidden one included, become a 1,776-byte file.

Endpoint
POST /v2/convert/xlsx/to/md
Accepts
xlsx
Sample timing
under 1 ms median of 5 runsHow we measure
Request size
Up to 10 MB on the Free plan or 100 MB on paid plans, all files together

Request and response

Every sample below ran against the API before this page was published. Set PDFCONVERSIONAPI_KEY to your key and run it as is.

curl -sS -X POST \
  https://api.pdfconversionapi.com/v2/convert/xlsx/to/md \
  -H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
  -F File=@tool-library-loans.xlsx \
  -o response.json

# FileData is base64. Save the first file in converted/,
# or print the JSON error.
if jq -e '.Files' response.json > /dev/null; then
  mkdir -p converted
  name=$(jq -r '.Files[0].FileName' response.json)
  jq -r '.Files[0].FileData' response.json \
    | base64 --decode > "converted/$name"
else
  cat response.json
fi
200 OKunder 1 ms median1 file, 1.7 KB
{
  "ConversionCost": 1,
  "ConversionTime": 0,
  "Files": [
    {
      "FileName": "tool-library-loans.md",
      "FileExt": "md",
      "FileSize": 1776,
      "FileData": "IyMgTG9hbnMKCnwgTG9hbiB8…"
    }
  ]
}

Response from our test run on 2026-11-03. ConversionTime shows the median of 5 runs. FileData is shortened here; the real response carries the whole file as base64.

The sample, converted

The same file the code sends. Download the input and the output and compare them yourself.

tool-library-loans.md, first 30 of 38 lines

## Loans| Loan | Item | Category | Member | Out | Due | Days | Deposit | Returned | Shelf || --- | --- | --- | --- | --- | --- | --- | --- | --- | --- || L-1041 | Cordless drill | Power tools | M-208 | 2026-09-01 | 2026-09-08 | 7 | 25 | true | B2 || L-1042 | Hedge trimmer | Garden | M-114 | 2026-09-02 | 2026-09-09 | 7 | 10 | true | D4 || L-1043 | Extension ladder, 24 ft | Ladders | M-301 | 2026-09-03 | 2026-09-06 | 3 | 15 | true | Yard || L-1044 | Orbital sander | Woodworking | M-208 | 2026-09-05 | 2026-09-12 | 7 | 20 | false | C1 || L-1045 | Leaf blower | Garden | M-077 | 2026-09-08 | 2026-09-15 | 7 | 10 | true | D2 || L-1046 | Tile saw | Power tools | M-152 | 2026-09-10 | 2026-09-17 | 7 | 25 | false | B5 || L-1047 | Pole saw | Garden | M-114 | 2026-09-12 | 2026-09-14 | 2 | 10 | true | D3 || L-1048 | Step ladder, 6 ft | Ladders | M-020 | 2026-09-14 | 2026-09-21 | 7 | 15 | true | Yard || L-1049 | Router, 1/4 in collet | Woodworking | M-266 | 2026-09-18 | 2026-09-25 | 7 | 20 | false | C3 || L-1050 | Pressure washer | Power tools | M-301 | 2026-09-21 | 2026-09-28 | 7 | 25 | true | B1 || L-1051 | Wheelbarrow | Garden | M-077 | 2026-09-24 | 2026-10-01 | 7 | 10 | false | Yard || L-1052 | Biscuit joiner | Woodworking | M-152 | 2026-09-28 | 2026-10-05 | 7 | 20 | false | C2 |## Summary| Loans by category, September 2026 |  |  || --- | --- | --- || Maple Street Tool Library is fictional. Sample workbook for pdfconversionapi.com, CC0 1.0. |  |  ||  |  |  || Category | Loans | Deposits held || Power tools | 3 | 25 || Garden | 4 | 10 || Ladders | 2 | 0 || Woodworking | 3 | 60 || All categories | 12 | 95 |
Input
tool-library-loans.xlsx (11 KB)
Output
tool-library-loans.md (1.7 KB)
Source
A fictional tool library's September loans workbook (three sheets, one of them hidden, with formulas and a chart) that we wrote for this site (CC0-1.0). How it was made
Made by
2026-11-04, API build 9eeeb0640aba

Parameters

Send these as form fields next to the file. Names are case-insensitive. If you set one of the documented options below that we don't support yet, the request fails with a 400 that names it instead of returning a file made without it.

ParameterWhat it does
SheetHeadingsboolean, default trueWrite ## Loans, ## Summary and so on above each table. With false the tables follow each other without headings.
FirstRowIsHeaderboolean, default trueUse each sheet's first row as the table header. With false the header is the column letters (| A | B |) and the first row becomes data.
WorksheetNamestringConvert one sheet only, found without regard to case. WorksheetName=Loans gives a 1,305-byte file with just that table.
WorksheetIndexintegerOne sheet by position from 1; hidden sheets are counted.Values: 1 to the number of sheets
ActiveWorksheetOnlyboolean, default falseConvert only the tab that was open when the file was saved. The sample was saved on Summary, so the output is that one 345-byte table.
PasswordstringOpen password for an encrypted workbook. The locked copy of the sample converted to the same 1,776 bytes with it; without it the API answers 422.

Not supported yet

Setting one of these to anything but its default returns 400.

OptionWhat to do instead
CellValuesOnly formatted is accepted; raw and other values return 400 "CellValues=raw is not supported yet for spreadsheets to Markdown". Despite the name, cells hold the stored values today (25, not $25.00).
IncludeHiddenRowstrue returns 400. Hidden rows are included anyway: the sample's hidden row L-1047 is in the Loans table.
IncludeHiddenColumnstrue returns 400; hidden columns, such as the sample's Shelf column, are already included.
ImagesAny value other than embed returns 400 "Images is not supported yet for XLSX → MD". Charts and pictures are not written either way.

What carries over, and what doesn't

Kept

  • Every sheet, in tab order, under a heading with its name: Loans, Summary and the hidden Deposits sheet
  • Cell values as stored: 7 for the Days formula, 25 for the deposit, true and false for the Returned flags
  • Dates in ISO 8601: the 9/1/2026 cell becomes 2026-09-01
  • Pipes inside cells are escaped as \| and line breaks become <br>, so a cell never breaks the table
  • Empty cells as empty table cells, so each row has as many cells as the header

Lost or not yet supported

  • Number formats: currency, percent and thousands separators are not applied, so $25.00 is written as 25.
  • Hidden rows and columns are not removed, even though IncludeHiddenRows and IncludeHiddenColumns default to false.
  • Charts, pictures, comments, colors, borders and merged cells. A title row above a table becomes that table's header row, as on the sample's Summary sheet.
  • Formulas: only their stored results are written.

Limits

  • Requests up to 10 MB on the Free plan or 100 MB on paid plans; conversions that run longer than 120 seconds return 504.
  • A file the reader doesn't recognize returns 422 "the input file could not be read: Cannot detect file format".

Where teams use it

Spreadsheets in a knowledge base or a docs repository

Markdown tables render on GitHub, in wikis and static site generators, and their diffs show which cells changed from one version to the next.

Context for a language model

A sheet name heading plus a plain table is easy for a model to read, and much smaller than the XLSX package: 1,776 bytes of text for a 10,832-byte workbook in the sample.

Pasting data into an issue or a pull request

Turn a workbook attached to a ticket into a table you can quote in the discussion.

Questions

Are hidden sheets included?

Yes. Every sheet is converted, the hidden ones too: the sample's hidden Deposits sheet is the third table. To leave sheets out, convert the ones you want with WorksheetName or WorksheetIndex, one request each.

Why does the Markdown show 25 when Excel shows $25.00?

Cells are written with the value stored in the file, not the text Excel displays, so number formats such as currency are not applied. Dates are the exception: they are written as ISO dates like 2026-09-01.

How are line breaks and pipe characters in cells handled?

A | inside a cell is written as \| and a line break as <br>, so the table structure stays intact. In our test, "left | right" became left \| right.

Can I get the table without the sheet headings?

Send SheetHeadings=false. Combine it with WorksheetName to get a single bare table you can paste anywhere.

Convert your first XLSX file in a minute.