Home » Programming » Archive by category "PHP"

Convert HTML to PDF with HTML2PDF Web Service

HTML2PDF Web ServiceRecently I launched my new product HTML2PDF Web Service — a web service for converting HTML to PDF.

In this post I’d like to talk about HTML2PDF Web Service. Why to choose it, how to use it and what technologies were used to create it.

Why Choose HTML2PDF Web Service?

Programmatically generating PDF documents is a painful and time consuming problem that neither makes your developers nor designers happy. With HTML2PDF Web Service you can design your invoices or reports in HTML, style them with CSS and convert the resulting page into a PDF document. Using HTML2PDF Web Service saves your developers and designers time which is better spent making your product better.

Say your web application or mobile app (or any application for that matter) needs to generate invoices or reports in PDF format. Unless you can install special HTML to PDF conversion software you’re probably stuck with some of the libraries available for your language that can programmatically generate PDF documents. To do this you would probably design your document in something like MS Word, LibreOffice Writer or perhaps HTML. After this design has been approved you can start programming your PDF module; setting up coordinates, font sizes etc. And then all of the sudden you notice your library has limited support for doing actual document layouts and presenting tabular data that can span multiple lines. Now you need to write your own routines for splitting text over multiple lines, keep track of coordinates and make sure nothing overlaps. If like me you’ve already been there, it’s quite the nightmare.

So being able to design in HTML, style with CSS (heck, even use a bit of JavaScript) and convert the resulting page to PDF would speed up this process a lot. Am I starting to tickle your interest?

How to use HTML2PDF Web Service

Simply create your soon to be PDF documents in HTML, style them with CSS and if wanted you can use JavaScript as well. The final document is best previewed in a WebKit based browser such as Google Chrome, since that’s the technology HTML2PDF Web Service uses in the background to render the HTML and convert it to PDF.

Here are some examples on how to call the web service. Converting HTML to PDF is easy with the HTML2PDF Web Service. You can pass an URL to the page you want to convert or either send the HTML code with the request.

cURL

$ curl -H "X-API-Key: F8802062-4D31-11E3-8F59-BFD4058B6BFF"
       -H "X-API-Username: MyUsername"
       -d '{"content":"<html><head><title>My page</title></head><body><h1>Hello World!</h1><p>I am an HTML page converted to PDF!</p></body></html>"}'
       https://html2pdfwebservice.com/api/convert > page.pdf

Perl

#!/usr/bin/env perl
use strict;
use warnings;
use Mojo::UserAgent;

my $ua = Mojo::UserAgent->new;
my $tx = $ua->post(
    'https://html2pdfwebservice.com/api/convert' => {
        'X-API-Username' => 'MyUsername',
        'X-API-Key'      => 'F8802062-4D31-11E3-8F59-BFD4058B6BFF'
    } => json => {url => 'http://domain.com/invoice.html'}
);
if (my $res = $tx->success) {
    my $pdf_data = $res->body;
}

Ruby

require 'net/https'
require 'uri'

uri           = URI.parse('https://html2pdfwebservice.com/api/convert')
https         = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
# In case the SSL certificate isn't accepted
https.verify_mode = OpenSSL::SSL::VERIFY_NONE

req = Net::HTTP::Post.new(uri.path)
req['X-API-Username'] = 'MyUsername'
req['X-API-Key']      = 'F8802062-4D31-11E3-8F59-BFD4058B6BFF'
req.body              = '{"url": "http://domain.com/invoice.html"}'

res = https.request(req)
if res.code == '200'
    pdf_data = res.body
    # - or write to file -
    # File.open('invoice.pdf', 'w') { |file| file.write(res.body) }
end

PHP

$settings = array(
    'url' => 'http://domain.com/invoice.html',
);

$curl = curl_init();
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($settings));
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
    'X-API-Username: MyUsername',
    'X-API-Key: F8802062-4D31-11E3-8F59-BFD4058B6BFF'
));

curl_setopt($curl, CURLOPT_URL, 'https://html2pdfwebservice.com/api/convert');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// Helps to debug in case of issues
// curl_setopt($curl, CURLOPT_VERBOSE, 1);

// In case the SSL certificate isn't accepted because of outdated certificates
// on your server
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

$res = curl_exec($curl);
// Save PDF to disk
file_put_contents('document.pdf', $res);
curl_close($curl);

Technologies used to develop HTML2PDF Web Service

The most interesting part in developing HTML2PDF Web Service was choosing which technology to use for converting HTML to PDF. After doing research on the subject and testing several solutions I eventually went with a WebKit based solution. By using WebKit it’s easier for the end user to preview their document using a WebKit based browser.

The HTML to PDF conversion server was developed using Go. Go is a fun language to program with, does concurrency in a really nice way and can produce a native executable for Linux, OS X, Windows and some other platforms. Thanks to Go the conversion server is fast, snappy and low on memory and CPU usage. Being able to create a binary executable allows me to sell the conversion server as a standalone product as well.

To get access to the web service there’s also a web application which is written in Perl. My favorite web framework of choice has become Mojolicious for quite some time now and thus HTML2PDF Web Service has been written with it. DBIx::Class has been used for database interaction and Validation::Class is used to validate all user inputted data.

Used databases are PostgreSQL and Redis. The former is used to store user accounts, subscriptions and more. The latter is used to keep track of token usage per user.

Sign up now for a free trial

If after reading all this and you’re still reading, please do sign up for a free trial. The trial gives full access to all the features of the web service so if you like it, please consider buying a subscription.

In case of any questions, please do contact me either through the comments on this page or send an e-mail to support at support@html2pdfwebservice.com.

Symfony 2 cheatsheet

A cool Symfony 2 website I ran in today is the Symfony 2 Cheatsheet by David Pérez. It sure would’ve been nice if I had this one around when I just started out with the Symfony 2 project I’m working on (which will be launching soon).

Check it out at http://www.symfony2cheatsheet.com.

Propel ORM for PHP

For the last couple of weeks I’ve have been working with Propel ORM for PHP and have really enjoyed using it. Coming from Perl I’m spoiled because it has DBIx::Class which is my ORM by choice and makes fetching data from your SQL database including relational data a breeze. Propel does a really nice job with this as well and though the API differs greatly from that of DBIx::Class I found it easy enough to pick up.

Propel nicely integrates with Symfony 2 and I’m happy with my decision to go with Propel. The alternative would’ve been Doctrine but decided against using it, mainly because of having to learn DQL (Doctrine Query Language). DQL is similar to SQL, but I liked the named methods of Propel better (e.g. filterByCampaign($object) or filterByCampaignId($id)) and in the end with Doctrine you’re still busy writing a dialect of SQL. With Propel and DBIx::Class you can still use SQL when needed (and to be honest I still find it to be a bit awkward at times in DBIx::Class but I understand why it is the way it is). I could also have looked at Zend_Db_Table from Zend Framework which I’ve used in the past but found too limiting.

All in all Propel a nice ORM library for PHP. Be sure to check it out if you haven’t already.

 

I’m now a freelance developer

To my surprise I hadn’t even announced here that I have recently started freelancing! As of August the 1st I now operate under the name Kras IT and am available as a freelance developer. Since it’s now the 1st of September this means I’m already in business for a month now which has been exciting. I’ve been with my previous employer for almost 7 years and after a lot of thinking and planning I decided to take the leap!

As a freelance developer you can hire me for all your PHP and Perl work. I mainly do webdevelopment but I do a lot of backend as well. Aside from that I also enjoy configuring Linux servers. I personally think being able to configure and optimize both your app and the server(s) the app is running on can be a great asset, as it gives a lot more insight in the overall workings of your software.

Aside from doing freelance work I also plan on doing product development. I’ve got a few ideas in the pipeline of which one I expect to launch within 5 months. I’m likely to blog about this in the near future as well as about freelancing and running your own business.

For a full list of skills you can take a look at my website at Kras IT. Currently the website is still Dutch only but my LinkedIn and résumé are in English. Do you’ve got any questions or are in need of a freelance developer? Feel free to contact me!

PHP’s switch-statement bit me in the ass

Since a few days a certain operation in the webshop software we’ve written at work was extremely slow. Adding a product to the basket took forever, like 2 minutes. When adding a product to the basket it checks if there are any related products that should be added to the shopping basket as well. This is a feature we’ve called bundles. You can bundle products together and specify some rules such as optional or obligatory to purchase with the selected product.

In our current database some products can have up to 100 optional articles. Such as extended warranties, memory expansion and so forth (in case of e.g. a desktop PC). After finding the source of my problems I was dazzled. I iterated over the products in my shopping basket with a foreach-loop. Inside I used a switch-statement to see if the related article was optional or not. If not, I would simply do a continue to go to the next item in my list. Or so I thought.

This however didn’t seem to work and after looking up PHP’s online manual I found this:

Note: Note that unlike some other languages, the continue statement applies to switch and acts similar to break. If you have a switch inside a loop and wish to continue to the next iteration of the outer loop, use continue 2.

I was very surprised to read this, totally unexpected to learn about this behavior. I really can’t think of any reason why they did this.

PS: I know adding 100 optional products shouldn’t take that long, but since all our prices are pre-calculated (we have a very extended pricing table with lots of features and conditions) we want to be sure the price is right when they add it to the basket so we recalculate it and update the product database.