McAPI - HTML to PDF Converter API with PHP

PHP sample code to convert websites and plain HTML to a PDF document with the McAPI HTML to PDF Converter REST API service. The sample uses PHP 7 but the code will also work with older versions. The code below uses the modules curl and json which should both be available with a standard PHP installation. All samples will also work in Laravel.

Requirements: A free RapidAPI account. Replace YOUR_API_KEY in the code below with your RapidAPI key.

All samples below work with the free tier of the API, see the McAPI HTML to PDF API Listing for available plans.

See the overview page for a reference that lists all available parameters and error codes.

Convert business documents (invoices, package lists, timesheets) from HTML to PDF with PHP

In the first code snippet we'll convert this invoice from HTML to PDF, a standard use case of HTML to PDF conversion. We set the paper to "A4" with the storeExternal parameter to "true"; with this options the PDF will be returned from the API as a downloadable URL.

The PHP source code:

// PHP
  
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://mcapi-html-2-pdf.p.rapidapi.com/",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{
    \"url\": \"https://mcapi.io/html2pdf/templates/invoice.html\",
    \"format\": \"A4\",
    \"storeExternal\": \"true\"
  }",
  CURLOPT_HTTPHEADER => [
    "content-type: application/json",
    "x-rapidapi-host: mcapi-html-2-pdf.p.rapidapi.com",
    "x-rapidapi-key: YOUR_API_KEY"
  ],
]);

$response = curl_exec($curl);
curl_close($curl);
  

The PDF's URL will be delivered as a JSON object in the $response variable, example:

{
  "service": "McAPI HTML 2 PDF, https://mcapi.io",
  "version": "V1",
  "pdf": "https://...pdf"
}

McAPI HTML to PDF API - Converted HTML Invoice as PDF with PHP

The returned PDF from the PHP code above, viewed in the Preview app of macOS. The PDF is fully indexable and searchable (note the selected and highlighted text):

Image of Converted HTML Invoice to PDF in PHP

Specifying page formats

The HTML to PDF Converter API comes with a built-in list of standard paper formats, e.g. "A4" or "letter". To get a list of all formats use the listFormats option, like so:

// PHP
  
...

  CURLOPT_POSTFIELDS => "{
    \"listFormats\": \"true\"
  }"

...

The API will now return an array of all predefined page sizes, shown here as JSON source:

{
  formats: ["Letter", "Legal", "Tabloid", "Ledger", "A0", "A2", "A3", "A4", "A5", "A6"]
}

Selecting one of the predefined formats is simple, just use its name in the call (paper names, like all parameters and options, are case sensitive with this API):

// PHP
  
...

  CURLOPT_POSTFIELDS => "{
    \"url\": \"https://mcapi.io/html2pdf/templates/invoice.html\",
    \"format\": \"Letter\",
    \"storeExternal\": \"true\"
  }"

...

Posting HTML code for conversion to PDF with PHP

All previous examples sent URLs for conversion to the API. You can also add HTML code directly to your call to the API with the html parameter. We first load the HTML code from a file, then escape with json_encode so that it can be used within a JSON block:

// PHP

...

  $data = file_get_contents("invoice.html");
  $html = json_encode();

... 

Then we set the parameters like so:

// PHP

...

  CURLOPT_POSTFIELDS => "{
    \"html\": $html,
    \"format\": \"Letter\",
    \"storeExternal\": \"true\"
  }"

...

The rest of the call to the API remains unchanged. The API will now render the supplied HTML into a PDF and return it to the caller.

Note that relative references or links in the HTML string will not resolve. Example for an image tag that won't work:

<img src="../templates/logo.png"/>

All references and links in your HTML code must be absolute and point to valid web locations, here's an example:

<img src="https://mcapi.io/html2pdf/templates/logo.png"/>

Make sure to see the discussion in the API overview on this.

With your call you can also add HTML to define headers and footers for each page of the converted PDF. The API overview has more on this and provides some example code.

Cookie consent banners and ad blocking

If so desired, the API can also automatically click the "Accept" button on GDPR / DSGVO cookie consent banners (Note that this feature is currently experimental, discussion.)

Consider the CNBC website which we convert to a PDF with this PHP snippet:

// PHP
  
...

  CURLOPT_POSTFIELDS => "{
    \"url\": \"https://cnbc.com\",
    \"format\": \"A4\",
    \"background\": \"true\",
    \"orientation\": 1,
    \"storeExternal\": \"true\"
  }"

...

Screenshot from the captured PDF (link to PDF), note the large cookie consent banner:

PHP  Website HTML to PDF Conversion with Cookie Banner

Set the cookie option in the POSTFIELDS to "true" to get a PDF without the banner:

// PHP
  
...

  CURLOPT_POSTFIELDS => "{
    \"url\": \"https://cnbc.com\",
    \"format\": \"A4\",
    \"background\": \"true\",
    \"cookie\": \"true\",
    \"orientation\": 1,
    \"storeExternal\": \"true\"
  }"

...

The CNBC site without the cookie message but now with ads (link to PDF):

Python Website HTML to PDF Conversion with Ad.png

Blocking ads on a website before conversion to a PDF

While there are some use cases to include ads when converting a website (for example to document ad placement or to check ad rotation), in many cases you'll prefer the PDFs without any ads. The API comes with a built-in ad blocker, activate it with the adblock option:

// PHP
  
...

  CURLOPT_POSTFIELDS => "{
    \"url\": \"https://cnbc.com\",
    \"format\": \"A4\",
    \"background\": \"true\",
    \"cookie\": \"true\",
    \"adblock\": \"true\",
    \"orientation\": 1,
    \"storeExternal\": \"true\"
  }"

...

The Site without cookie banner and without ads (link to PDF):

PHP Website HTML to PDF Conversion no Cookies no Ads

For the PDF of the CNBC site we had set the orientation to "1" for landscape ("0" is portrait) and the background parameter to "true". This is a sensible option for converting websites to PDF because they often have inverted text and similar styling.

Here's the CNBC site without background elements (the default). The site's design features lots of white text against blue or black background which is now no longer visible:

PHP Website HTML to PDF Conversion Transparent Background

As a rule of thumb, set the background option to "false" for conversion of documents like invoices, package lists, time sheets, set it to "true" when converting web pages or sites to a PDF.

The header-parameter - writing PDFs to a file (PHP)

With the storeExternal option set to "false", the PDF is returned immediately as a base64 encoded string. Per default, this string has a MIME header that describes the media type of the encoded content.

Sample POSTFIELDS block:

// PHP

...

  CURLOPT_POSTFIELDS => "{
    \"url\": \"https://mcapi.io/html2pdf/templates/invoice.html\",
    \"format\": \"A4\",
    \"storeExternal\": \"false\"
  }"

...

The returned response will look like this:

{
  "service": "McAPI HTML 2 PDF, https://mcapi.io",
  "version": "V1",
  "pdf": "data:application/pdf;base64,JVBERi0 ... JUVPRg=="
}

You can now directly set the "pdf"-string as the data property of an HTML object element like in this example:

// PHP

...

if(curl_getinfo($curl, CURLINFO_HTTP_CODE) == 200){
    // In production code you would test the result of json_decode against null
    $pdf = json_decode($response, true)["pdf"];
    echo "<object data=\"" . $pdf . "\"/>"; 
  }
  else{
    echo "Error";
  }

...

The MIME header will make sure that the PDF data is interpreted correctly by the browser (Note that not all browsers support the embedding of PDF files with the object tag, see this thread on Stackoverflow.)

However, when writing the PDF data to a file, including the header would result in an invalid PDF document as the MIME header is not part of the PDF file format. To convert your content to a PDF without the header, set the header-parameter to "false", like so:

// PHP

...

  CURLOPT_POSTFIELDS => "{
    \"url\": \"https://mcapi.io/html2pdf/templates/invoice.html\",
    \"format\": \"A4\",
    \"storeExternal\": \"false\",
    \"header\": \"false\"
  }"

...

The returned PDF data, now without the MIME header:

{
  "service": "McAPI HTML 2 PDF, https://mcapi.io",
  "version": "V1",
  "pdf": "JVBERi0 ... JUVPRg=="
}

All that is left now is decoding the base64 string to get the binary PDF data and then write this data to a file. Shown here as a complete PHP program:

// PHP

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://mcapi-html-2-pdf.p.rapidapi.com/",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{
    \"url\": \"https://mcapi.io/html2pdf/templates/invoice.html\",
    \"format\": \"A4\",
    \"storeExternal\": \"false\",
    \"header\": \"false\"
}",
  CURLOPT_HTTPHEADER => [
    "content-type: application/json",
    "x-rapidapi-host: mcapi-html-2-pdf.p.rapidapi.com",
    "x-rapidapi-key: YOUR_API_KEY"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

if ($err) {
  echo "Error: " . $err;
} else {
  if(curl_getinfo($curl, CURLINFO_HTTP_CODE) == 200){
    // In production code you would test the result of json_decode against null
    $pdf = json_decode($response, true)["pdf"];
    $pdfData = base64_decode($pdf);
    $f = fopen("invoice.pdf", "wb");
    fwrite($f, $pdfData);
    fclose($f);
  }
  else{
    echo "Error";
  }
}
curl_close($curl);

Back to McAPI HTML to PDF API main page.