Use Nutrient DWS Processor API to convert HTML pages into Office document output including DOCX, XLSX, and PPTX. Start a free trial, test with Postman, and move to production with credit-based pricing.
This example will convert your uploaded HTML file to a DOCX document.
Try it out in three steps
index.html to your project folder.result.docx to see the output.curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o result.docx \ --fail \ -F document=@index.html \ -F instructions='{ "parts": [ { "html": "document" } ], "output": { "type": "docx" } }'curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.docx ^ --fail ^ -F document=@index.html ^ -F instructions="{\"parts\": [{\"html\": \"document\"}], \"output\": {\"type\": \"docx\"}}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "document", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "instructions", new JSONObject() .put("parts", new JSONArray() .put(new JSONObject() .put("html", "document") ) ) .put("output", new JSONObject() .put("type", "docx") ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.docx"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/build");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("document", "index.html") .AddParameter("instructions", new JsonObject { ["parts"] = new JsonArray { new JsonObject { ["html"] = "document" } }, ["output"] = new JsonObject { ["type"] = "docx" } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.docx"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('instructions', JSON.stringify({ parts: [ { html: "document" } ], output: { type: "docx" }}))formData.append('document', fs.createReadStream('index.html'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/build', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.docx")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/build', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'document': open('index.html', 'rb') }, data = { 'instructions': json.dumps({ 'parts': [ { 'html': 'document' } ], 'output': { 'type': 'docx' } }) }, stream = True)
if response.ok: with open('result.docx', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.docx', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/build', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'instructions' => '{ "parts": [ { "html": "document" } ], "output": { "type": "docx" } }', 'document' => new CURLFILE('index.html') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/build HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="instructions"Content-Type: application/json
{ "parts": [ { "html": "document" } ], "output": { "type": "docx" }}--customboundaryContent-Disposition: form-data; name="document"; filename="index.html"Content-Type: text/html
(document data)--customboundary--This example will convert your uploaded HTML file to a PPTX document.
Try it out in three steps
index.html to your project folder.result.pptx in your project folder to view the results.curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o result.pptx \ --fail \ -F document=@index.html \ -F instructions='{ "parts": [ { "html": "document" } ], "output": { "type": "pptx" } }'curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pptx ^ --fail ^ -F document=@index.html ^ -F instructions="{\"parts\": [{\"html\": \"document\"}], \"output\": {\"type\": \"pptx\"}}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "document", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "instructions", new JSONObject() .put("parts", new JSONArray() .put(new JSONObject() .put("html", "document") ) ) .put("output", new JSONObject() .put("type", "pptx") ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pptx"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/build");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("document", "index.html") .AddParameter("instructions", new JsonObject { ["parts"] = new JsonArray { new JsonObject { ["html"] = "document" } }, ["output"] = new JsonObject { ["type"] = "pptx" } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pptx"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('instructions', JSON.stringify({ parts: [ { html: "document" } ], output: { type: "pptx" }}))formData.append('document', fs.createReadStream('index.html'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/build', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pptx")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/build', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'document': open('index.html', 'rb') }, data = { 'instructions': json.dumps({ 'parts': [ { 'html': 'document' } ], 'output': { 'type': 'pptx' } }) }, stream = True)
if response.ok: with open('result.pptx', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pptx', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/build', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'instructions' => '{ "parts": [ { "html": "document" } ], "output": { "type": "pptx" } }', 'document' => new CURLFILE('index.html') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/build HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="instructions"Content-Type: application/json
{ "parts": [ { "html": "document" } ], "output": { "type": "pptx" }}--customboundaryContent-Disposition: form-data; name="document"; filename="index.html"Content-Type: text/html
(document data)--customboundary--This example will convert your uploaded HTML file to an XLSX document.
Try it out in three steps
index.html to your project folder.result.xlsx in your project folder to view the results.curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o result.xlsx \ --fail \ -F document=@index.html \ -F instructions='{ "parts": [ { "html": "document" } ], "output": { "type": "xlsx" } }'curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.xlsx ^ --fail ^ -F document=@index.html ^ -F instructions="{\"parts\": [{\"html\": \"document\"}], \"output\": {\"type\": \"xlsx\"}}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "document", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "instructions", new JSONObject() .put("parts", new JSONArray() .put(new JSONObject() .put("html", "document") ) ) .put("output", new JSONObject() .put("type", "xlsx") ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.xlsx"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/build");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("document", "index.html") .AddParameter("instructions", new JsonObject { ["parts"] = new JsonArray { new JsonObject { ["html"] = "document" } }, ["output"] = new JsonObject { ["type"] = "xlsx" } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.xlsx"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('instructions', JSON.stringify({ parts: [ { html: "document" } ], output: { type: "xlsx" }}))formData.append('document', fs.createReadStream('index.html'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/build', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.xlsx")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/build', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'document': open('index.html', 'rb') }, data = { 'instructions': json.dumps({ 'parts': [ { 'html': 'document' } ], 'output': { 'type': 'xlsx' } }) }, stream = True)
if response.ok: with open('result.xlsx', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.xlsx', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/build', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'instructions' => '{ "parts": [ { "html": "document" } ], "output": { "type": "xlsx" } }', 'document' => new CURLFILE('index.html') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/build HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="instructions"Content-Type: application/json
{ "parts": [ { "html": "document" } ], "output": { "type": "xlsx" }}--customboundaryContent-Disposition: form-data; name="document"; filename="index.html"Content-Type: text/html
(document data)--customboundary--Convert HTML into Word, Excel, and PowerPoint output for editing, collaboration, and distribution workflows.
Use REST, Postman, curl, JavaScript, Python, Java, C#, PHP, or HTTP to automate conversion inside larger document processing pipelines.
This conversion is one action in the DWS Processor API. Combine it with other conversions, OCR, extraction, and editing in a single request.
Most common next steps
Use the following:
The API accepts standard HTML markup with inline and embedded CSS for layout, typography, tables, and styling. You upload an HTML file along with any CSS or asset files, and the API renders it before converting to the selected Office format.
Send a request to the DWS Processor API with your HTML input and DOCX as the target format. You can call it over REST, curl, Postman, or an SDK in JavaScript, Python, Java, C#, or PHP. See the getting started guide for API key setup, or the dedicated HTML-to-DOCX API for that specific conversion.
Yes. The API renders your HTML and CSS and maps the result into the target Office format, preserving layout, fonts, tables, and styling as closely as the format allows. Some advanced CSS may render differently across DOCX, XLSX, and PPTX because each format has its own structural constraints.
Use HTML to Office when recipients need to edit or repurpose the output in Word, Excel, or PowerPoint — for example, DOCX, XLSX, or PPTX. Use the HTML-to-PDF API when you need a fixed, non-editable document for sharing, printing, or archiving.
Yes. Start a free trial to get an API key and test conversions before moving to production. Production usage runs on credit-based pricing; see Processor API pricing for details.