XLSB to TIFF API
Post an .xlsb file to POST /v2/convert/xlsb/to/tiff and get a separate TIFF for each printed page. The sample keeps page 2 only, in grayscale at 72 DPI, and receives one 595 × 841 image of 500,593 bytes.
- Endpoint
- POST /v2/
convert/ xlsb/ to/ tiff - Accepts
- xlsb
- Sample timing
- 0.567 s 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/xlsb/to/tiff \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@meter-readings.xlsb \
--form-string PageRange=2 \
--form-string ColorSpace=gray \
--form-string ImageResolution=72 \
-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
fiimport base64
import os
import requests
key = os.environ["PDFCONVERSIONAPI_KEY"]
response = requests.post(
"https://api.pdfconversionapi.com/v2/convert/xlsb/to/tiff",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("meter-readings.xlsb", "rb"))],
data={
"PageRange": "2",
"ColorSpace": "gray",
"ImageResolution": "72",
},
timeout=180,
)
result = response.json()
if not response.ok:
raise SystemExit(f"{result['Code']}: {result['Message']}")
os.makedirs("converted", exist_ok=True)
for file in result["Files"]:
path = os.path.join("converted", file["FileName"])
with open(path, "wb") as out:
out.write(base64.b64decode(file["FileData"]))
print(path, file["FileSize"], "bytes")
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
const form = new FormData();
const file = "meter-readings.xlsb";
form.append("File", new Blob([await readFile(file)]), file);
form.append("PageRange", "2");
form.append("ColorSpace", "gray");
form.append("ImageResolution", "72");
const url = "https://api.pdfconversionapi.com/v2/convert/xlsb/to/tiff";
const key = process.env.PDFCONVERSIONAPI_KEY;
const response = await fetch(url, {
method: "POST",
headers: { Authorization: `Bearer ${key}` },
body: form,
});
const result = await response.json();
if (!response.ok) {
throw new Error(`${result.Code}: ${result.Message}`);
}
await mkdir("converted", { recursive: true });
for (const file of result.Files) {
const path = join("converted", file.FileName);
await writeFile(path, Buffer.from(file.FileData, "base64"));
console.log(path, file.FileSize, "bytes");
}
{
"ConversionCost": 1,
"ConversionTime": 0.567,
"Files": [
{
"FileName": "meter-readings-2.tiff",
"FileExt": "tiff",
"FileSize": 500593,
"FileData": "SUkqAMOiBwBIAAAAAQAAAEgA…"
}
]
}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.

- Input
- meter-readings.xlsb (3.3 KB)
- Output
- meter-readings-2.tiff (489 KB)
- Source
- A fictional cold-storage unit's meter readings in Excel binary format (two sheets with dates, times and formulas) that we wrote record by record 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.
| Parameter | What it does |
|---|---|
ColorSpaceenum, default default | gray stores one 8-bit channel instead of three, a third of the size: the sample's page is 500,593 bytes in gray and 1,501,411 in color at 72 DPI. monochrome stores black and white in the same 8 bits.Values: default, rgb, gray, monochrome |
ImageResolutioninteger, default 150 | Pixels per inch, written into the TIFF when you send it. File size grows with its square: an A4 page in color is 6,521,426 bytes at 150 and 1,501,411 at 72. ConvertAPI's image default is 200.Values: 36–600 |
PageRangestring | Printed pages to return. 2 is the Daily sheet; each file keeps its page number (meter-readings-2.tiff).Values: e.g. 1, 2, 1-2 |
MultiPageboolean, default false | Send true to get all printed pages in one LZW-compressed TIFF: the sample's two A4 pages in color at 150 DPI came back as one 165,903-byte file instead of two files of 6,521,426 bytes. Left out, every page is its own uncompressed TIFF. |
WorksheetNamestring | Print one sheet by name, in any letter case. |
PageSizeenum, default default | Paper size; without page setup in the file, pages are A4.Values: default, letter, legal, a3, a4, a5 and others |
Passwordstring | Open password for an encrypted .xlsb. |
What carries over, and what doesn't
Kept
- The printed page exactly as drawn, with no compression loss: the Daily table with its dates, kWh values and the Average row
- One 8-bit gray channel with
ColorSpace=gray, marked as black-is-zero grayscale - The DPI you send, recorded in the file (72 for the sample)
- The page number in each file name
Lost or not yet supported
- Pages are not combined unless you send
MultiPage=true: by default every page is its own TIFF, where the XLSX and XLS routes return one multi-page file. - Pages returned as separate files are not compressed, so they are large: 6,521,426 bytes for one A4 page in color at the default 150 DPI.
- Gridlines aren't printed, and the paper is A4 when the file stores no page setup.
Limits
- 2,000 pages per request; each page at most 16,000 pixels per side and 100 million pixels.
- All files of one answer travel in the same response, so many uncompressed pages make it large; ask for fewer pages or a lower resolution.
- 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
Archiving printed pages of data workbooks
Imaging and records systems that store TIFF can keep a page-by-page copy of an XLSB report next to scanned paper documents.
Grayscale pages for services that take TIFF
For services that take TIFF pages, ColorSpace=gray gives single-channel pages a third the size of color ones.
Questions
Can I get a single multi-page TIFF from an XLSB?
Yes, send MultiPage=true. Every printed page then goes into one LZW-compressed file: 165,903 bytes for the sample's two pages in color, or 39,333 bytes with ColorSpace=gray at 72 DPI, where both frames stay 8-bit gray. Without it, each page arrives as a separate uncompressed TIFF.
Why is each TIFF so large?
The pages are stored without compression, three bytes per pixel in color. An A4 page is 1,240 × 1,753 pixels at 150 DPI, about 6.5 MB. Grayscale cuts that to a third and a lower resolution cuts it further: the sample's gray page at 72 DPI is about 0.5 MB. Combining the pages with MultiPage=true adds LZW compression.
Which page is which?
Pages are numbered across the printed sheets in tab order. In the sample, page 1 is the Readings sheet and page 2 is Daily, so PageRange=2 returned meter-readings-2.tiff.
Convert your first XLSB file in a minute.