menu

Thursday, May 1, 2014

Creating PDF file from dynamic HTML in Android

Hellow world,

So i was missing from action for few weeks now. I blame it on my work because I'm always dead tired (only can watch some films for another 4 hours) after i come back from work each day :D. Anyway once again I was given some task that seem's hard at first.

We have a mobile app in android which is not surprisingly a hybrid app. Hence, all the UI elements are HTML/javascript. One day the project managers in a weird way wanted to make a PDF out of some HTML content in display. Now the HTML content here are a dynamic table that's created based on data from a webservice + user interaction. So no way of hard-coding anything.

Todo

Retrieve dynamic HTML from a webview in Android and make a PDF from the content in it

Things you need

  1. iTextPDF : an open source PDF creation library for java, works well in android too
  2. XMLWorker : a plugin for iTextPDF to support XML/HTML


Download these and you need only to reference 2 libraries, those are

  1. itextpdf-5.x.x.jar
  2. xmlworker-5.x.x.jar


CODE

Let's take a look a the sample HTML i would be converting to PDF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<table width="100%">
    <thead>
        <tr>
            <th style="font-weight:bold;text-align:left">Item Name</th>
            <th style="font-weight:bold;text-align:center">Base Currency</th>
            <th style="font-weight:bold;text-align:right">Base Amount</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Basic</td>
            <td>LKR</td>
            <td>75000</td>
        </tr>
        <tr>
            <td>Another</td>
            <td>LKR</td>
            <td>25000</td>
        </tr>
    </tbody>
</table>


NOTE:

  1. We are using a XML parser here, so your HTML structure should be perfect. No loose ends, incomplete tags, open quotes bla bla like that
  2. While this supports retrieving style from external CSS files, the best thing is to embed it into the HTML code itself. Either in <style></style> tags or as inline-style.


So let's check the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
try{
    //your_html_here is a variable with all the dynamic HTML stuff
    String html = "<html><head></head><body>" + your_html_here + "</body></html>";
     
    //Open a new document instance
    Document doc = new Document();
     
    //We convert the string to a byte array, so we can input it to the XMLWorker instance                  
    InputStream in = new ByteArrayInputStream(html.getBytes());
     
    //We write the file to a app accesbile location
    PdfWriter pdf = PdfWriter.getInstance(doc, new FileOutputStream(p.getApplication().getExternalFilesDir("MyFileStorage") + "/out.pdf"));
     
    //open the document to write
    doc.open();
     
    //parser and write the file
    XMLWorkerHelper.getInstance().parseXHtml(pdf, doc,in);
     
    //close things before it gets messey           
    doc.close();
    in.close();
}catch(Exception e){
    System.out.println(e.getMessage());
}

Few things to note:
1) You need to add the following for the manifest to give write access to the app


<
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

2) Since our sample HTML code didnt have the opening tags like <html>, we have to put them on hand.
3) Change out.pdf to the filename you want, but to a .pdf of course :3
4) Your file can be found at /external/storage/mnt/bla/Android/data/<you app related name>/MyStorageFiles/ firectory

That's brief i know, but this would get you PDF-ing fast :D

Cya ppl


8 comments:

  1. How can i show image in a pd file as well . Please help

    ReplyDelete
  2. not working when opening pdf doesnot show any result !!

    ReplyDelete
  3. Unfortunately, this can´t convert html with forms or images...

    ReplyDelete
    Replies
    1. Didnt check with images but please let me know if you find a workaround

      Delete
  4. what is p in here?? PdfWriter pdf = PdfWriter.getInstance(doc, new FileOutputStream(p.getApplication().getExternalFilesDir("MyFileStorage") + "/out.pdf"));

    ReplyDelete
    Replies
    1. Anything that can gt the application instance, if you are inside an Activity, remove "p" and just call getApplication()

      Delete