Skip to content
pdfconversionapi

XLS to JSON API

Send an Excel 97-2003 file to POST /v2/convert/xls/to/json and get a sheet's rows as JSON objects named by its header row. The sample's Fuel sheet gives 11 objects: ten fill-ups and the Total row.

Endpoint
POST /v2/convert/xls/to/json
Accepts
xls
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/xls/to/json \
  -H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
  -F File=@van-fuel-log.xls \
  -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, 2.3 KB
{
  "ConversionCost": 1,
  "ConversionTime": 0,
  "Files": [
    {
      "FileName": "van-fuel-log.json",
      "FileExt": "json",
      "FileSize": 2367,
      "FileData": "WwogIHsKICAgICJDb3N0Ijog…"
    }
  ]
}

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.

van-fuel-log.json, first 30 of 112 lines

[  {    "Cost": 52.3838,    "Date": "2026-06-01",    "Gallons": 14.2,    "Miles per gallon": 16.619718309859156,    "Notes": null,    "Odometer": 48210,    "Price per gallon": 3.689,    "Van": "Van 1"  },  {    "Cost": 61.9752,    "Date": "2026-06-02",    "Gallons": 16.8,    "Miles per gallon": 15.595238095238095,    "Notes": null,    "Odometer": 61377,    "Price per gallon": 3.689,    "Van": "Van 2"  },  {    "Cost": 46.4875,    "Date": "2026-06-04",    "Gallons": 12.5,    "Miles per gallon": 18.24,    "Notes": null,    "Odometer": 30554,    "Price per gallon": 3.719,    "Van": "Van 3"
Input
van-fuel-log.xls (11 KB)
Output
van-fuel-log.json (2.3 KB)
Source
A fictional bakery's van fuel log in Excel 97-2003 format (two sheets, formulas, a cell note and a merged title) 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
WorksheetNamestringSheet to export, in any letter case (vans works). Left out, the first sheet in tab order is read.
WorksheetIndexintegerSheet position from 1. The sample has two sheets, so 3 returns 400 with "WorksheetIndex is 3, but the workbook has 2 worksheets".Values: 1 to the number of sheets
ActiveWorksheetOnlyboolean, default falseRead the sheet that was selected when the file was saved, taken from the workbook's window settings. In a test file saved on its second sheet, that sheet was read.
FirstRowIsHeaderboolean, default trueWith false, each row becomes an array in column order and the header row is the first array; the sample's output then drops from 2,367 to 1,457 bytes.
FileNamestringName of the JSON file, without the extension.

What carries over, and what doesn't

Kept

  • Number types as the .xls stores them: whole odometer readings such as 48210 and 13 gallons arrive as JSON integers, 14.2 gallons as a decimal
  • Dates as ISO 8601 text: 06/01/2026 in the sheet becomes "2026-06-01"
  • The line break inside the two-line note, as \n in the string
  • The Total row, as an object whose Date is "Total" and whose empty cells are null
  • Formula results stored in the file: Cost is 52.3838 for 14.2 gallons at $3.689

Lost or not yet supported

  • Display formats: a miles-per-gallon cell shown as 16.6 arrives with every digit, 16.619718309859156, and $52.38 arrives as 52.3838. Round in your code if you need the shown values.
  • Column order inside each object: keys come sorted alphabetically (Cost, Date, Gallons, ...).
  • The cell note, the drop-down list, the conditional highlight and the second sheet; one sheet is read per request.

Limits

  • Password-protected .xls files can't be read here: with the password the API returns 400 "password-protected XLS files can't be converted to JSON yet", without it 422. Re-save them with /v2/convert/xls/to/xlsx and Password first, then convert the XLSX.
  • Only Excel's binary format is read. A web page saved as .xls returns 422 "the input file could not be read: Cannot detect file format".
  • Requests up to 10 MB on the Free plan or 100 MB on paid plans; 120 seconds per conversion, then 504.

Where teams use it

Retiring a legacy export

When a supplier or an older system sends .xls attachments, convert each one to JSON as it arrives, and the rest of your code never has to read the binary format.

Loading historical data into a database

Archives of .xls workbooks from past years can be read sheet by sheet into rows for SQL or a data warehouse.

Questions

Why do some numbers have decimals and others don't?

An .xls file stores whole numbers in a compact integer form, and those come out as JSON integers (48210). Numbers with a fraction come out as decimals (14.2). Values are not rounded to the cell's display format.

What if the sheet starts with a title row?

The first row is used as the header, whatever it holds. The sample's Vans sheet starts with a merged title, so its keys became "Sunrise Rye Bakery: delivery vans" and column2 to column4. Use FirstRowIsHeader=false and choose the header row yourself, or move the title out of the sheet.

How do I convert every sheet?

Make one request per sheet with WorksheetIndex=1, 2 and so on. To see all sheets at once as text, /v2/convert/xls/to/md writes every sheet in one file.

Convert your first XLS file in a minute.