Android PDF Generation: A Step-by-Step Guide for Creating Dynamic PDF Documents

Android offers a robust framework for generating PDFs from native content. In this blog post, we will explore the process of creating a PDF document from scratch using the native Android framework.

The Android platform provides a dedicated class for PDF generation called . This class allows developers to create, modify, and output PDF files seamlessly. The process involves creating a new document, adding pages, writing content to each page, and finally saving and closing the document.

How it works?

Using the PdfDocument Class

The first step is to utilise the PdfDocument class, which is responsible for creating and rendering PDF documents. This class provides various methods and properties to manipulate PDF content.

Providing the Data

To render the PDF, you need to provide the data that will be displayed in the PDF document. This data can be retrieved from various sources, such as a database, API, or user input.

Defining Page Dimensions and Layout

Before rendering the content, you need to define the page dimensions and layout. Determine the height and width of each page based on your requirements. Additionally, calculate the number of pages needed based on the total items and the desired number of items per page.

Rendering Views from XML Files

To populate the PDF document with content, you can utilise XML layout files. Create XML files representing the desired views and content that you want to display in the PDF document. You can design these XML similar to how you design regular app layouts.

Use the PdfDocument class to render these views onto the PDF document. Iterate through the array of data and create the corresponding views dynamically. Then, for each page, create a canvas using the PdfDocument class and render the views onto the canvas.

Let's Get Started

We will see the simple app that tracks the daily expenses of the user and list them date-wise. We will see how we can generate or render the pdf for the same.

Here is the demo,

test

Creating a PdfDocument instance:

test

Next, we generate PageInfo for the page that will be added to the PdfDocument. The PageInfo object specifies the dimensions and other properties of the page.

test

Here’s what each parameter means:

  • PDF_PAGE_WIDTH: This constant represents the width of the page in points (1 inch = 72 points).

  • PDF_PAGE_HEIGHT: This constant represents the height of the page in points (1 inch = 72 points).

  • 1: This parameter represents the page number. In this case, we are creating the first page of the PDF document.

The PdfDocument.PageInfo.Builder class provides a convenient way to set the page dimensions and other properties. We pass the width, height, and page number to the Builder, and then call the create() method to generate the PageInfo object.

The PageInfo object will be used when adding content to the PDF document’s pages.

Creating the first page of the PDF:

testtest

Here we fetch the data from the database, calculate the total items and prepare the views. parentView() function to create a parent view that will hold the other views.

test

pdfHeaderView function to inflate a header view for the PDF document's first page. This view typically contains information such as the date range, total amount, and total number of items.

test

Important Note While Creating XML Layouts:

For better sizing, we use px font size and dimension. px renders better and looks real when PDF renders. We can also use dp it in the layout and later in the code, we can convert it px if we want.

We can later programmatically inflate the view while rendering the PDF just like we did with pdfHeaderView.

Rendering Layout XML:

The startPage method of the PdfDocument object (doc) is called with the pageInfo object as a parameter to initiate the creation of the first page of the PDF document. This method returns a PdfDocument.Page is an object representing the newly created page.

Now that we have created the page object we can draw the view on it. For that, we can use one function that returns the Bitmap from the view. So we can easily use that to draw.

testtest

The finishPage method is called to indicate that the rendering of the 

first page is complete. After finishing the page, the code removes all child views from the parentView to prepare for rendering subsequent pages.

Here is the result for the first header page,

test

Rendering Multiple Pages

As we have a list of items from the database to render, we have to determine how many pages are required to be rendered in our PDF. 

Steps

  1. Calculates the total number of pages required for the PDF based on the number of spending items in the list.

  2. Sets the page capacity (ITEM_CAPACITY_PER_PAGE = 25) for each page, ensuring it does not exceed the number of spending items.

  3. Iterates over the list of spending items paginate them, and adds them to a parent view.

  4. Renders each page as a bitmap image and adds it to the PDF document.

  5. Clears the parent view after each page is added to the PDF.

we can use this simple function to know the exact pages required from the count of the items.

testtest

Now we have the count of the required pages, we can paginate the list of items and create the views from it and add them to the page. 

testtest

The code enters a while loop that iterates over each page until pageNum reaches the totalPage count. Inside the loop, it creates a sublist of spending items for the current page based on the pageNum and finalPageCapacity values. It then adds each spending item to the parentView using the spendingItemView() function. 

After adding the spending items to the parentView, the code creates a new page (dynamicPage) in the PDF document using the provided pageInfo. It converts the parentView into a bitmap image using the loadBitmapFromView() function and draws the bitmap on the canvas of dynamicPage. Finally, it finishes the page and removes all views from the parentView.

Here is the result for the second page with multiple items rendered,

test

Writing the PDF in the storage

testtest

Writing the PDF to the storage is very easy. We created a folder called “report”. Created the file Object with an appropriate name. 

The code calls the writeTo() method on the doc object, which represents the generated PDF document. It writes the content of the document to the specified file using the file.outputStream() to obtain an output stream for the file.

Finally, the close() method is called on the doc object to release any resources associated with the PDF document, ensuring proper closure and cleanup.

Conclusion

In this blog, we explored the process of rendering PDF documents in Android using the PdfDocument class. We discussed how to generate a PDF document, define page dimensions, and render views onto the pages. 

Overall, rendering PDFs in Android using the PdfDocument class offers a powerful and flexible approach to generate PDF documents programmatically, opening up possibilities for creating customised and visually appealing content within Android applications.

Meet Prajapati

Software Engineer

Published: Jun 12, 2023

Updated: Jun 13, 20236 min read

AWS Certified Team

Tech Holding Team is a AWS Certified & validates cloud expertise to help professionals highlight in-demand skills and organizations build effective, innovative teams for cloud initiatives using AWS.

By using this site, you agree to thePrivacy Policy.