XLSX to WebP API
Call POST /v2/convert/xlsx/to/webp with a workbook and each printed page comes back as a lossless WebP. In the sample, ImageWidth=1000 makes both pages 1,000 pixels wide whatever their orientation.
- Endpoint
- POST /v2/
convert/ xlsx/ to/ webp - Accepts
- xlsx
- Sample timing
- 0.611 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/xlsx/to/webp \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@tool-library-loans.xlsx \
--form-string ImageWidth=1000 \
-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/xlsx/to/webp",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("tool-library-loans.xlsx", "rb"))],
data={
"ImageWidth": "1000",
},
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 = "tool-library-loans.xlsx";
form.append("File", new Blob([await readFile(file)]), file);
form.append("ImageWidth", "1000");
const url = "https://api.pdfconversionapi.com/v2/convert/xlsx/to/webp";
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.611,
"Files": [
{
"FileName": "tool-library-loans-1.webp",
"FileExt": "webp",
"FileSize": 58274,
"FileData": "UklGRprjAABXRUJQVlA4TI7j…"
},
{
"FileName": "tool-library-loans-2.webp",
"FileExt": "webp",
"FileSize": 39390,
"FileData": "UklGRtaZAABXRUJQVlA4TMqZ…"
}
]
}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
- tool-library-loans.xlsx (11 KB)
- Output
- tool-library-loans-1.webp (57 KB)tool-library-loans-2.webp (38 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.
| Parameter | What it does |
|---|---|
ImageWidthinteger | Target width in pixels; the height follows the page's proportions. The sample's landscape page becomes 1,000 × 773 and its portrait page 1,000 × 1,294. The page is drawn at the size needed, not drawn large and shrunk.Values: 1–20000 |
ImageHeightinteger | Target height. ImageHeight=800 gave 1,035 × 800 and 618 × 800. With both values the page fits inside the box with its proportions kept, unless ScaleProportions=false.Values: 1–20000 |
ImageResolutioninteger, default 150 | Pixels per inch when no size is given. At the default the sample's pages are 1,650 × 1,275 (108,760 bytes) and 1,275 × 1,650 (52,312 bytes). The WebP files carry no DPI value.Values: 36–600 |
ActiveWorksheetOnlyboolean, default false | Print only the tab that was open when the file was saved (Summary in the sample). |
WorksheetNamestring | Print one named sheet; letter case is ignored, and hidden sheets can be named. |
FitToPageboolean, default false | Make every printed sheet one page wide and as many pages tall as it needs, by changing its page setup before printing. |
Passwordstring | Open password for an encrypted workbook; without it the API answers 422. |
Not supported yet
Setting one of these to anything but its default returns 400.
| Option | What to do instead |
|---|---|
ImageQuality | Pages are always written as lossless WebP. Any value other than 75 returns 400 "ImageQuality is not supported yet for XLSX → WebP". |
What carries over, and what doesn't
Kept
- Every pixel of the drawn page: the encoder is lossless (VP8L), so small numbers and cell borders stay sharp
- Both printed sheets of the sample in tab order, each at its own orientation, with the hidden sheet left out
- Proportions of the page when only
ImageWidthorImageHeightis sent - The chart, cell fills, borders and number formats of each printed page, laid out by the sheet's own page setup
Lost or not yet supported
- Lossy WebP is not available: there is no way to trade quality for size, and
ImageQualityis refused. - No DPI or physical page size is stored in the file.
- Calibri text is drawn with the metric-compatible Carlito font.
Limits
ImageWidthandImageHeightgo up to 20,000; a drawn page may be at most 16,000 pixels per side and 100 million pixels.- 2,000 pages per request at most. Requests up to 10 MB on the Free plan or 100 MB on paid plans, and 120 seconds per conversion before a 504.
Where teams use it
Previews in a web app
Show users a picture of the workbook they uploaded. A fixed ImageWidth gives every preview the same width, so landscape and portrait pages line up in a list.
Smaller files than PNG for the same pixels
Lossless WebP keeps every pixel of the page. The sample's landscape page is 108,760 bytes as WebP and 286,206 bytes as PNG at the same 150 DPI.
Questions
Can I make the WebP files lossy to save space?
Not yet. The WebP pages are lossless, and ImageQuality returns 400 for this route. If you need lossy compression, use /v2/convert/xlsx/to/jpg, where ImageQuality sets the JPEG quality.
How do I make all previews the same width?
Send ImageWidth. Each page is drawn at exactly that width and its height follows the paper's proportions, as with the sample's 1,000 × 773 and 1,000 × 1,294 pages.
Which sheets end up in the images?
Every sheet that is not hidden, in tab order, split into pages by its print settings. Use WorksheetName, WorksheetIndex or ActiveWorksheetOnly=true to print just one.
Convert your first XLSX file in a minute.