158

Is there any way to create PDF Files from an Android application?

hichris123
  • 10,145
  • 15
  • 56
  • 70
  • 6
    Wouldn't it be nice if Android's imaging model took some inspiration from Qt's? Qt established that generating PDF or SVG can be as simple as redirecting the same code one uses to draw on the screen. Look at the derivation of QPrinter, QSvgGenerator, and QWidget from QPaintDevice for the pattern. – Calaf Apr 20 '13 at 10:54
  • 1
    Same in iOS. PDF generation is built-in. – Fabian Zeindl May 29 '13 at 10:20
  • 2
    I believe Kit Kat has a feature for generating PDF, but I don't know if this is backwards compatible. I have posted an option below and the following site lists several options ranging from commercial to free: http://stefan.fenz.at/creating-pdfs-on-android-an-evaluation/ – IcedDante Feb 17 '14 at 04:42
  • 1
    Used [PdfBox-Android](https://github.com/TomRoush/PdfBox-Android) based on [PDFBox](https://pdfbox.apache.org) library open source. – alditis Oct 25 '17 at 23:08
  • 8
    Ridiculous that this was closed as "off-topic". – Joe Coder Apr 23 '18 at 17:09
  • 1
    We published an article about it: https://pspdfkit.com/blog/2018/ways-to-create-a-pdf-on-android/ – steipete Oct 20 '18 at 06:53
  • 3
    Why was this post closed? Stackoverflow is way too picky about its scope; this question has 175,000 views, as a coding resource this site should allow hyper-common things like this, the rules need amending, we read way too far into the literal text of what's "off-topic" rather than the heart of the rule. I flagged it for re-opening, hope others will vote as well. – Albert Renshaw Mar 11 '19 at 20:58
  • Because its asking for the Stack Overflow community to do the asker's entire job for them, without them having shown any indication of trying anything themselves. The correct close reason is "needs more focus" not "off-topic", but this is academic at this point because the question has already been closed and it's not worth reopening and reclosing just to change the close reason. – pppery Jun 12 '20 at 21:57

8 Answers8

157

If anyone wants to generate PDFs on Android device, here is how to do it:

Rubens Mariuzzo
  • 28,358
  • 27
  • 121
  • 148
nikib3ro
  • 20,366
  • 24
  • 120
  • 181
110

If you are developing for devices with API level 19 or higher you can use the built in PrintedPdfDocument: http://developer.android.com/reference/android/print/pdf/PrintedPdfDocument.html

// open a new document
PrintedPdfDocument document = new PrintedPdfDocument(context,
     printAttributes);

// start a page
Page page = document.startPage(0);

// draw something on the page
View content = getContentView();
content.draw(page.getCanvas());

// finish the page
document.finishPage(page);
. . .
// add more pages
. . .
// write the document content
document.writeTo(getOutputStream());

//close the document
document.close();
teh.fonsi
  • 3,040
  • 2
  • 27
  • 22
  • this uses API 19 (Kitikat) - so in future devices you can easyly create pdf documents by painting on canvas. Thank you for this helpful post – Chris623 Nov 24 '13 at 10:41
  • 2
    Finally its part of Android as its part of iOS. – lalitm Mar 27 '14 at 06:41
  • 6
    @Chris623 I think you meant "KitKat" ... :) – android developer Jul 17 '14 at 14:46
  • 7
    @lalitm It is not as it is in ios. Pdf generated in iOS has selectable text written in doc. But in android its a image. – Kantesh Nov 27 '14 at 11:28
  • 1
    I got this [GitHub](http://developer.android.com/reference/android/support/v4/content/FileProvider.html) source from AndroidCookBook to do the job, just don't forget to add the file provider in your manifest, and make sure the provider points to the correct file_path xml resource. Examples on doing this are included in the android API FileProvider docs [HERE](http://developer.android.com/reference/android/support/v4/content/FileProvider.html) – Will Thomson Feb 26 '16 at 00:39
  • 2
    @WillThomson Was your GitHub link supposed to be [this one](https://github.com/IanDarwin/Android-Cookbook-Examples) or something else? – jk7 Nov 01 '17 at 21:41
  • 3
    Thanks so much - the useful link is here https://github.com/IanDarwin/Android-Cookbook-Examples/blob/master/PdfShare/src/main/java/com/example/pdfshare/MainActivity.java – Kibi Nov 20 '17 at 13:41
  • Thanks. What is the difference with PdfDocument class ? https://developer.android.com/reference/android/graphics/pdf/PdfDocument – toto_tata Dec 03 '20 at 14:51
31

A trick to make a PDF with complex features is to make a dummy activity with the desired xml layout. You can then open this dummy activity, take a screenshot programmatically and convert that image to pdf using this library. Of course there are limitations such as not being able to scroll, not more than one page,but for a limited application this is quick and easy. Hope this helps someone!

Community
  • 1
  • 1
hrishitiwari
  • 634
  • 7
  • 15
  • 2
    It deserved atleast 1up. – Rahul Rastogi Jun 29 '15 at 11:06
  • worked for me. was a simple implementation. – TharakaNirmana Apr 25 '16 at 06:36
  • thats a cool workaround – Kumar Saurabh Apr 03 '17 at 09:31
  • This comment point me in the right direction. However: 1. you don't need to start an activity to take a screen shot! you can just inflate an xml layout on runtime and convert it to a bitmap [like suggested here](http://stackoverflow.com/questions/12402392/android-converting-xml-view-to-bitmap-without-showing-it); That being said, you can generate multiple pages with different layouts. Scroll is not supported as being said but you can implement a list using, for example, a linear layout. – r.pedrosa Apr 26 '17 at 00:01
11

It's not easy to find a full solution of the problem of a convertion of an arbitrary HTML to PDF with non-english letters in Android. I test it for russian unicode letters.

We use three libraries:

(1) Jsoup (jsoup-1.7.3.jar) for a convertion from HTML to XHTML,

(2) iTextPDF (itextpdf-5.5.0.jar),

(3) XMLWorker (xmlworker-5.5.1.jar).

public boolean createPDF(String rawHTML, String fileName, ContextWrapper context){
    final String APPLICATION_PACKAGE_NAME = context.getBaseContext().getPackageName();
    File path = new File( Environment.getExternalStorageDirectory(), APPLICATION_PACKAGE_NAME );
    if ( !path.exists() ){ path.mkdir(); }
    File file = new File(path, fileName);

    try{

    Document document = new Document();
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
    document.open();

    // Подготавливаем HTML
    String htmlText = Jsoup.clean( rawHTML, Whitelist.relaxed() );
    InputStream inputStream = new ByteArrayInputStream( htmlText.getBytes() );

    // Печатаем документ PDF
    XMLWorkerHelper.getInstance().parseXHtml(writer, document,
        inputStream, null, Charset.defaultCharset(), new MyFont());

    document.close();
    return true;

    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return false;
    } catch (DocumentException e) {
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    } 

The difficult problem is to display russian letters in PDF by using iTextPDF XMLWorker library. For this we should create our own implementation of FontProvider interface:

public class MyFont implements FontProvider{
    private static final String FONT_PATH = "/system/fonts/DroidSans.ttf";
    private static final String FONT_ALIAS = "my_font";

    public MyFont(){ FontFactory.register(FONT_PATH, FONT_ALIAS); }

    @Override
    public Font getFont(String fontname, String encoding, boolean embedded,
        float size, int style, BaseColor color){

        return FontFactory.getFont(FONT_ALIAS, BaseFont.IDENTITY_H, 
            BaseFont.EMBEDDED, size, style, color);
    }

    @Override
    public boolean isRegistered(String name) { return name.equals( FONT_ALIAS ); }
}

Here we use the standard Android font Droid Sans, which is located in the system folder:

private static final String FONT_PATH = "/system/fonts/DroidSans.ttf";
DenisMath
  • 547
  • 4
  • 8
6

A bit late and I have not yet tested it yet myself but another library that is under the BSD license is Android PDF Writer.

Update I have tried the library myself. Works ok with simple pdf generations (it provide methods for adding text, lines, rectangles, bitmaps, fonts). The only problem is that the generated PDF is stored in a String in memory, this may cause memory issues in large documents.

AggelosK
  • 4,313
  • 2
  • 32
  • 37
2

PDFJet offers an open-source version of their library that should be able to handle any basic PDF generation task. It's a purely Java-based solution and it is stated to be compatible with Android. There is a commercial version with some additional features that does not appear to be too expensive.

Mahdi Alkhatib
  • 1,954
  • 1
  • 29
  • 43
IcedDante
  • 6,145
  • 12
  • 57
  • 100
0

U can also use PoDoFo library. The main goal is that it published under LGPL. Since it is written in C++ you should cross-compile it using NDK and write C-side and Java wrapper. Some of third-party libraries can be used from OpenCV project. Also in OpenCV project U can find android.toolchain.cmake file, which will help you with generating Makefile.

Johnny Doe
  • 3,280
  • 4
  • 29
  • 45
0

Late, but relevant to request and hopefully helpful. If using an external service (as suggested in the reply by CommonsWare) then Docmosis has a cloud service that might help - offloading processing to a cloud service that does the heavy processing. That approach is ideal in some circumstances but of course relies on being net-connected.

Paul Jowett
  • 6,513
  • 2
  • 24
  • 19