Click here to Skip to main content
15,881,938 members
Articles / Mobile Apps / Android

Android iText Pdf Example

Rate me:
Please Sign up or sign in to vote.
4.86/5 (5 votes)
28 Apr 2015CPOL7 min read 94K   7   10
This blog post stems from my recent experience building my soon to be released Invoicing app. I waited until the last minute to integrate PDF hoping that there is a magical boolean I can set to true and voila, my deeply nested view will be converted to PDF.

This blog post stems from my recent experience building my soon to be released Invoicing app. I waited until the last minute to integrate PDF hoping that there is a magical boolean I can set to true and voila, my deeply nested view will be converted to PDF. I quickly realized that programmatic PDF involves dealing with a set of complex API. Anyone approaching programmatic PDF with the mindset of the ease of GUI PDF is in for a pleasant surprise. As I navigate my way through Pdfland I will be sharing my Android iText PDF example in this and subsequent posts.

In this post I will begin with the basics of how to use the iTextg library to create a PDF document in Android which will make this blog post a basic introduction to iText in Android. Itext is a popular library for creating and manipulating PDF documents. It was originally written for Java but has since been ported to .Net, Android and other platforms. Surprisingly iText for Android (called iTextG) tutorials are often hard to find or the blog or tutorial date seems dated, however I will admit that Stackoverflow has lots of helpful content and helpful pointers regarding iText in Android .

If you plan to do any meaningful work with programmatic PDF you will be well served to make an investment in this book iText in Action by Bruno Lowagie, I am very glad that I did. In this book, the author who is also the creator of the iText library outlined 5 steps to creating PDF with iText.

Steps in Creating a PDF Document with Itext (Excerpt from iText in Action)

      Step 1: Create a Document
      Step 2: Get a PDFWriter instance
      Step 3: Open the Document
      Step 4: Add Content
      Step 5: Close the Document

These steps applies whether you are creating PDF in server, web or mobile environment. Now, let us see how we can apply these steps in an Android app. To do this, lets create a simple application named SelfNote. This app lets you quickly take enter some notes for yourself and either email it to yourself as a PDF or view it. This is a glorified Hello World of PDF in Android with iText. Below is what the final app will look like once complete.

<iframe class='youtube-player' type='text/html' width='640' height='390' src='http://www.youtube.com/embed/7L97yRZ2lYE?version=3&rel=1&fs=1&showsearch=0&showinfo=1&iv_load_policy=1&wmode=transparent' frameborder='0' allowfullscreen='true'></iframe>

Step 1: Create a Document
Go ahead and create a standard Android Studio project and name it anything you like, I have named mine PdfDemo. In this project, add a Fragment with its own xml layout and name it SelfNoteFragment and the xml fragment_self_note_xml. If you created a new project, you can go ahead and delete the PlaceHolderFragment and any reference to it in the MainActivity. Below is the content of the fragment_self_note.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_margin="@dimen/activity_vertical_margin"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <EditText
        android:id="@+id/edit_text_subject"
        android:hint="@string/hint_subject"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

    <EditText
        android:id="@+id/edit_text_body"
        android:hint="@string/hint_body"
        android:layout_width="match_parent"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/button_save"
        android:layout_width="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_height="wrap_content"
        android:text="Save"/>
</LinearLayout>

And the Main Activity’s layout activity_main.xml just has a FrameLayout with the Id of container like so:

<FrameLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"/>

The Java code in the Main Activity just points to the SelfNoteFragment like below. All the code for creating the PDF will be contained inside the SelfNoteFragment so we can add more Fragments to the project for upcoming Android iText tutorials. Here is the Main Activity onCreate code.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SelfNoteFragment noteFragment = SelfNoteFragment.newInstance();

        android.support.v4.app.FragmentTransaction fragTransaction= this.getSupportFragmentManager().beginTransaction();
        fragTransaction.replace(R.id.container, noteFragment);
        fragTransaction.commit();
    }

Here is the starting Java code for the SelfNoteFragment.

public class SelfNoteFragment extends Fragment {
    private View mRootView;
    private EditText mSubjectEditText, mBodyEditText;
    private Button mSaveButton;

    public SelfNoteFragment() {
        // Required empty public constructor
    }

    public static SelfNoteFragment newInstance(){
        SelfNoteFragment fragment = new SelfNoteFragment();
        return fragment;
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        mRootView = inflater.inflate(R.layout.fragment_self_note, container, false);
        mSubjectEditText = (EditText) mRootView.findViewById(R.id.edit_text_subject);
        mBodyEditText = (EditText) mRootView.findViewById(R.id.edit_text_body);
        mSaveButton = (Button) mRootView.findViewById(R.id.button_save);
        return mRootView;
    }
}

Now unto the PDF world. Create a method called createPdf() in the SelfNoteFragment like this

private void createPdf(){

  }

Add the iText Library to Android Studio

    • Click on Project
    • Project Structure
    • On the left hand side, under Modules, highlight app
    • Click on Dependencies tab
    • Click on the green plus sigh to the far right
    • Click on Library dependencies
    • Type itext in the search bar and hit enter
    • Select the latest version of the iText library for Android as show below
    • Click Ok and OK, and give Gradle a minute to rebuild

    add_itext_library_to_android_studio

    Under your createPdf() method, the first thing we need to do is to create a folder where we will save the PDF files we will be creating and we do this with the code below:

    File pdfFolder = new File(Environment.getExternalStoragePublicDirectory(
                   Environment.DIRECTORY_DOCUMENTS), "pdfdemo");
           if (!pdfFolder.exists()) {
               pdfFolder.mkdir();
               Log.i(LOG_TAG, "Pdf Directory created");
           }
    

    Next we need to create the name(s) of the Pdf file we are going to create. We do this my appending the current date and time to the string “SelfNote” and then append “.pdf” like this:

    Date date = new Date() ;
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date);
    
            File myFile = new File(pdfFolder + timeStamp + ".pdf");

    Next create an output stream where the iText library will write the PDF to, and point the output stream to the myfile we created. File operations can through an exception that means that it has some probability of failing therefore, the IDE will prompt you to add an exception to the signature of the method or surround the call to FileOutputStream with a Try/Catch clause. Because of this reason, go ahead and add a FileNotFoundException to the signature of the createPdf() method and with that the method will now look like this:

    private void createPdf() throws FileNotFoundException {
    
            File pdfFolder = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_DOCUMENTS), "pdfdemo");
            if (!pdfFolder.exists()) {
                pdfFolder.mkdir();
                Log.i(LOG_TAG, "Pdf Directory created");
            }
    
            //Create time stamp
            Date date = new Date() ;
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date);
    
            File myFile = new File(pdfFolder + timeStamp + ".pdf");
    
            OutputStream output = new FileOutputStream(myFile);
    
        }  

    Good progress, we now have a place to write our yet to be created PDF file. Remember I told you, programmatic PDF is not for the faint of heart.

    Now the fun begins! Create the PDF with this one line of Code

    Document document = new Document();

    That easy! – yes. In reality though the iText library did quite a few things for you under the hood. For one it supplied or implied your measurement. This is because PDF does not have an infinite dimension like an Android ScrollView. It has a defined measurements that has to be specified at the time of creation and since we did not specify one the iText library filled in the gaps for us like so:

    Rectangle pagesize = new Rectangle(216f, 720f);
    Document document = new Document(pagesize, 36f, 72f, 108f, 180f);

    The library also provides lots of helper methods and constants that will help you gain granular control of what is created. For example the above document created a standard European sized document, to create an American standard sized document you can create the document instead like this:

    Document document = new Document(PageSize.LETTER);

    Step 2: Get an Instance of PdfWriter
    The PdfWriter class is responsible for writing the PDF file. And in this step, you associate the blank document we created above with the PdfWriter class and point it to the output stream where the PDF will be written to like so:

    //Step 2
    PdfWriter.getInstance(document, output);

    And again we need to add DocumentException to the signature of this method so it looks like this with the content removed for brevity.

    private void createPdf() throws FileNotFoundException, DocumentException {} 

    Step 3: Open the PDF Document
    This step could as well has been named Initialization. A PDF is not a PDF until it is opened or initialized. When you call open the document the library performs some low level initialization of the PDF such as adding the file headers, the PDF version, making any bookmarks available, etc

    //Step 3
            document.open();

    Step 4: Add Content
    In this step we add two content (paragraph) corresponding to the two EditTexts in our layout like this:

    //Step 4 Add content
            document.add(new Paragraph(mSubjectEditText.getText().toString()));
            document.add(new Paragraph(mBodyEditText.getText().toString()));

    And we are done, of course you can guess that more than paragraphs can be added, you can get this book below to get deeper information about all the possibilities with PDF

    <iframe style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//ws-na.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&OneJS=1&Operation=GetAdHtml&MarketPlace=US&source=ss&ref=ss_til&ad_type=product_link&tracking_id=wwwafrodiscsc-20&marketplace=amazon&region=US&placement=1935182617&asins=1935182617&linkId=FNLDV3ZPEMR6BGTL&show_border=true&link_opens_in_new_window=true">
    </iframe>

    Step 5: Close the Document
    //Step 5: Close the document
    document.close();
    Let iText know that you are done so it can flush the content to the stream and close the output stream that we opened. The whole method should look like this when you are done.

    private void createPdf() throws FileNotFoundException, DocumentException {
    
            File pdfFolder = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_DOCUMENTS), "pdfdemo");
            if (!pdfFolder.exists()) {
                pdfFolder.mkdir();
                Log.i(LOG_TAG, "Pdf Directory created");
            }
    
            //Create time stamp
            Date date = new Date() ;
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date);
    
            File myFile = new File(pdfFolder + timeStamp + ".pdf");
    
            OutputStream output = new FileOutputStream(myFile);
    
            //Step 1
            Document document = new Document();
    
            //Step 2
            PdfWriter.getInstance(document, output);
    
            //Step 3
            document.open();
    
            //Step 4 Add content
            document.add(new Paragraph(mSubjectEditText.getText().toString()));
            document.add(new Paragraph(mBodyEditText.getText().toString()));
    
            //Step 5: Close the document
            document.close();
    
        }

    Viewing PDF in Android
    And that is it we are done with creating a PDF document with Android with iTextG. How about reading it. That is very simple, we will not recreate the wheel, just throw up an Intent and let Adobe Viewer of any other installed PDF viewer view the document like this:

    private void viewPdf(){
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(myFile), "application/pdf");
            intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
            startActivity(intent);
        }

    Email PDF Attachment in Android
    Sending an email with a PDF attachment is equally easy, just like with viewing it on the screen, we show an Intent that uses an email client such as Gmail to send the email like this:

    private void emailNote()
        {
            Intent email = new Intent(Intent.ACTION_SEND);
            email.putExtra(Intent.EXTRA_SUBJECT,mSubjectEditText.getText().toString());
            email.putExtra(Intent.EXTRA_TEXT, mBodyEditText.getText().toString());
            Uri uri = Uri.parse(myFile.getAbsolutePath());
            email.putExtra(Intent.EXTRA_STREAM, uri);
            email.setType("message/rfc822");
            startActivity(email);
        }

    To give an option of either sending the the PDF as email or just vieweing on the screen, we add a dialog prompt which is called at the end of the PDF document creation. Here is the method that shows the dialog with an option to either view the PDF document or send an email attachment with the PDF document:

    private void promptForNextAction()
        {
            final String[] options = { getString(R.string.label_email), getString(R.string.label_preview),
                    getString(R.string.label_cancel) };
    
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle("Note Saved, What Next?");
            builder.setItems(options, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if (options[which].equals(getString(R.string.label_email))){
                        emailNote();
                    }else if (options[which].equals(getString(R.string.label_preview))){
                        viewPdf();
                    }else if (options[which].equals(getString(R.string.label_cancel))){
                        dialog.dismiss();
                    }
                }
            });
    
            builder.show();
    
        }

    Update the createPdf() method to call the promptForNextAction() method right after document.close(). Finally add an onlick listener to the Save button that calls the createPdf() and check for null in the EditTexts so we do not create blank documents. Also add try/catch blocks to catch the Exceptions that we added to the createPdf() signature like this:

    mSaveButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mSubjectEditText.getText().toString().isEmpty()){
                        mSubjectEditText.setError("Subject is empty");
                        mSubjectEditText.requestFocus();
                        return;
                    }
    
                    if (mBodyEditText.getText().toString().isEmpty()){
                        mBodyEditText.setError("Body is empty");
                        mBodyEditText.requestFocus();
                        return;
                    }
    
                    try {
                        createPdf();
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (DocumentException e) {
                        e.printStackTrace();
                    }
                }
            });

    Thanks for reading and goodluck with your Pdf adventures.

    The post Android iText Pdf Example appeared first on Val Okafor.

This article was originally posted at http://valokafor.com/android-itext-pdf-example

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) ValOkafor.com
United States United States
My name is Val Okafor, I am a Senior Software Engineer with specialization in Android Development. Learning and problem solving is my passion and I share my Android development knowledge through my blog ValOkafor.com.

My Android courses are the courses I wish I had when I started. I teach Android development in the context of a fully developed Android app. I believe that new Android concepts are better understood if they are presented in the context of creating an app from scratch to finish.

I focus on creating Productivity Android apps and besides Android development I have 7 years’ experience as System Administrator supporting Enterprise applications and 2 years’ experience as a Web Developer building websites using PHP and ASP.Net.

I have worked for corporations such as The Home Depot, American Council on Exercise, Legend3D and HD Supply, Inc. I have a bachelor's degree in Information Technology from National University San Diego, California and a master's degree in Software Engineering from Regis University Denver, Colorado.

I enjoy sharing my extensive work experience through my blog, social media.

Comments and Discussions

 
Questionmissing picture Pin
Member 1383877022-May-18 1:02
Member 1383877022-May-18 1:02 
QuestionThanks + Note Pin
zezo alharazi4-Mar-18 20:48
zezo alharazi4-Mar-18 20:48 
QuestionLooking for a sample of create PDF file Pin
Member 130810347-Apr-17 0:15
Member 130810347-Apr-17 0:15 
QuestionI have a error,,,,Sir please resolve it...and post immediatlly Pin
Member 1204582210-Apr-16 9:58
Member 1204582210-Apr-16 9:58 
QuestionNote Pin
Member 16051391-Mar-16 1:12
Member 16051391-Mar-16 1:12 
QuestioniTextG Pin
Member 1229292428-Jan-16 1:21
Member 1229292428-Jan-16 1:21 
AnswerRe: iTextG Pin
Val Okafor28-Jan-16 10:40
professionalVal Okafor28-Jan-16 10:40 
QuestionThanks Pin
Santhakumar Munuswamy @ Chennai6-May-15 15:37
professionalSanthakumar Munuswamy @ Chennai6-May-15 15:37 
QuestionNice, but... Pin
David Crow1-May-15 2:55
David Crow1-May-15 2:55 
QuestionThanks Pin
eslipak30-Apr-15 12:37
professionaleslipak30-Apr-15 12:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.