How to create PDF file using iText or some other library on android?

39,706

Solution 1

You can use iText to create PDFs. Use the latest version (5.1.3) and include only the itextpdf-5.1.3.jar in the build path. You can use something like this to accomplish the pdf creation.

Document document = new Document();
file = Environment.getExternalStorageDirectory().getPath() + "/Hello.pdf"
PdfWriter.getInstance(document,new FileOutputStream(file));
document.open();
Paragraph p = new Paragraph("Hello PDF");
document.add(p);
document.close();

Also, don't forget to use the permission to write to external storage in the manifest.xml.

Solution 2

It's Easy,For example

Here the Code in my repository (updated link)

gradle.build

compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.madgag:scpkix-jdk15on:1.47.0.1'
compile 'com.itextpdf:itextpdf:5.0.6'

activity_main.xml

 <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.hackro.itext.MainActivity">
    
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnwrite"
        android:text="PDF"
        android:onClick="GeneratePDF"
        />
    </RelativeLayout>

MainActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.itextpdf.text.pdf.BaseFont;
import java.io.File;

public class MainActivity extends Activity {

    private static final String LOG_TAG = "GeneratePDF";


    private BaseFont bfBold;

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



    }


    public void GeneratePDF(View view)
    {
        // TODO Auto-generated method stub
        String filename = "david";
        String filecontent = "Contenido";
        Metodos fop = new Metodos();
        if (fop.write(filename, filecontent)) {
            Toast.makeText(getApplicationContext(),
                    filename + ".pdf created", Toast.LENGTH_SHORT)
                    .show();
        } else {
            Toast.makeText(getApplicationContext(), "I/O error",
                    Toast.LENGTH_SHORT).show();
        }
    }

  }

Metodos.java

 import android.util.Log;
    
    import com.itextpdf.text.BaseColor;
    import com.itextpdf.text.Document;
    import com.itextpdf.text.DocumentException;
    import com.itextpdf.text.Element;
    import com.itextpdf.text.Font;
    import com.itextpdf.text.Paragraph;
    import com.itextpdf.text.Phrase;
    import com.itextpdf.text.pdf.PdfPCell;
    import com.itextpdf.text.pdf.PdfPTable;
    import com.itextpdf.text.pdf.PdfWriter;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /**
     * Created by hackro on 24/11/15.
     */
    public class Metodos {
    
    
        public Boolean write(String fname, String fcontent) {
            try {
                String fpath = "/sdcard/" + fname + ".pdf";
                File file = new File(fpath);
    
                if (!file.exists()) {
                    file.createNewFile();
                }
    
                Font bfBold12 = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.BOLD, new BaseColor(0, 0, 0));
                Font bf12 = new Font(Font.FontFamily.TIMES_ROMAN, 12);
    
    
                Document document = new Document();
    
                PdfWriter.getInstance(document,
                        new FileOutputStream(file.getAbsoluteFile()));
                document.open();
    
                document.add(new Paragraph("Sigueme en Twitter!"));
    
                document.add(new Paragraph("@DavidHackro"));
                document.close();
    
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            } catch (DocumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
        }}
    

Result

Good Luck

Solution 3

This is my sample coding for creating pdf file with text and image content using Itext library and to store the pdf file in the external Storage location. The only thing is you need to download the itext library and add it into your project.

private void createPdf() {
                // TODO Auto-generated method stub
                com.itextpdf.text.Document document = new com.itextpdf.text.Document();

                 try {
                        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/vindroid";

                        File dir = new File(path);
                            if(!dir.exists())
                                dir.mkdirs();

                        Log.d("PDFCreator", "PDF Path: " + path);


                        File file = new File(dir, "sample.pdf");
                        FileOutputStream fOut = new FileOutputStream(file);

                        PdfWriter.getInstance(document, fOut);

                        //open the document
                        document.open();


                        Paragraph p1 = new Paragraph("Sample PDF CREATION USING IText");
                        Font paraFont= new Font(Font.FontFamily.COURIER);
                        p1.setAlignment(Paragraph.ALIGN_CENTER);
                        p1.setFont(paraFont);

                         //add paragraph to document    
                         document.add(p1);

                         Paragraph p2 = new Paragraph("This is an example of a simple paragraph");
                         Font paraFont2= new Font(Font.FontFamily.COURIER,14.0f,0, CMYKColor.GREEN);
                         p2.setAlignment(Paragraph.ALIGN_CENTER);
                         p2.setFont(paraFont2);

                         document.add(p2);

                         ByteArrayOutputStream stream = new ByteArrayOutputStream();
                         Bitmap bitmap = BitmapFactory.decodeResource(getBaseContext().getResources(), R.drawable.ic_launcher);
                         bitmap.compress(Bitmap.CompressFormat.JPEG, 100 , stream);
                         Image myImg = Image.getInstance(stream.toByteArray());
                         myImg.setAlignment(Image.MIDDLE);

                         //add image to document
                         document.add(myImg);




                 } catch (DocumentException de) {
                         Log.e("PDFCreator", "DocumentException:" + de);
                 } catch (IOException e) {
                         Log.e("PDFCreator", "ioException:" + e);
                 } 
                 finally
                 {
                         document.close();
                 }

            }      

Solution 4

I have created a sample project for creating the pdf file from data using itextpdf/itext7 library

Example project link: https://github.com/rheyansh/RPdfGenerator

Add below dependancy in your application gradle:

implementation 'com.itextpdf:itext7-core:7.1.12'

Important Notes

Add WRITE_EXTERNAL_STORAGE permission in AndroidManifest.xml

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

Add File Provider in AndroidManifest.xml

<provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="com.rheyansh.rpdfgenerator.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>

Add XML resource folder (see provider_paths.xml in example folder)

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
</paths>

Create RPdfGenerator class

import android.content.Context
import android.os.Environment
import com.rheyansh.model.RTransaction
import android.widget.Toast
import com.itextpdf.io.font.constants.StandardFonts
import com.itextpdf.kernel.colors.ColorConstants
import com.itextpdf.kernel.font.PdfFontFactory
import com.itextpdf.kernel.pdf.PdfDocument
import com.itextpdf.kernel.pdf.PdfWriter
import com.itextpdf.kernel.pdf.action.PdfAction
import com.itextpdf.layout.Document
import com.itextpdf.layout.element.Paragraph
import com.itextpdf.layout.element.Table
import com.itextpdf.layout.element.Text
import com.itextpdf.layout.property.TextAlignment
import com.itextpdf.layout.property.UnitValue
import com.rheyansh.lenden.model.RPdfGeneratorModel
import java.io.File
import java.io.FileOutputStream

object RPdfGenerator {

    private val linkSample = "https://github.com/rheyansh/RPdfGenerator"

    fun generatePdf(context: Context, info: RPdfGeneratorModel) {

        val FILENAME = info.header + ".pdf"
        val filePath = getAppPath(context) + FILENAME

        if (File(filePath).exists()) {
            File(filePath).delete()
        }

        val fOut = FileOutputStream(filePath)
        val pdfWriter = PdfWriter(fOut)

        // Creating a PdfDocument
        val pdfDocument =
            PdfDocument(pdfWriter)
        val layoutDocument = Document(pdfDocument)

        // title
        addTitle(layoutDocument, info.header)

        //add empty line
        addEmptyLine(layoutDocument,1)

        //Add sub heading
        val appName = "RPdfGenerator"
        addSubHeading(layoutDocument, "Generated via: ${appName}")
        addLink(layoutDocument, linkSample)

        //add empty line
        addEmptyLine(layoutDocument,1)

        // customer reference information
        addDebitCredit(layoutDocument, info)

        //add empty line
        addEmptyLine(layoutDocument,1)

        //Add sub heading
        addSubHeading(layoutDocument, "Transactions")

        //Add list
        addTable(layoutDocument, info.list)

        layoutDocument.close()
        Toast.makeText(context, "Pdf saved successfully to location $filePath", Toast.LENGTH_LONG).show()

        //FileUtils.openFile(context, File(filePath))
    }

    private fun getAppPath(context: Context): String {
        val dir = File(
            Environment.getExternalStorageDirectory()
                .toString() + File.separator
                    + context.resources.getString(R.string.app_name)
                    + File.separator
        )
        if (!dir.exists()) {
            dir.mkdir()
        }
        return dir.path + File.separator
    }

    private fun addTable(layoutDocument: Document, items: List<RTransaction>) {

        val table = Table(
            UnitValue.createPointArray(
                floatArrayOf(
                    100f,
                    180f,
                    80f,
                    80f,
                    80f,
                    100f
                )
            )
        )

        // headers
        //table.addCell(Paragraph("S.N.O.").setBold())
        table.addCell(Paragraph("Item").setBold())
        table.addCell(Paragraph("Customer").setBold())
        table.addCell(Paragraph("Qty").setBold())
        table.addCell(Paragraph("Price/Q").setBold())
        table.addCell(Paragraph("Total").setBold())
        table.addCell(Paragraph("Date").setBold())

        // items
        for (a in items) {
//            table.addCell(Paragraph(a.SNO.toString() + ""))
            table.addCell(Paragraph(a.itemName + ""))
            table.addCell(Paragraph(a.custName + ""))
            table.addCell(Paragraph(a.quantity.toString() + ""))
            table.addCell(Paragraph(a.pricePerUnit.toString() + ""))
            table.addCell(Paragraph((a.quantity * a.pricePerUnit).toString() + ""))
            table.addCell(Paragraph(a.transactionDateStr + ""))
        }
        layoutDocument.add(table)
    }

    private fun addEmptyLine(layoutDocument: Document, number: Int) {
        for (i in 0 until number) {
            layoutDocument.add(Paragraph(" "))
        }
    }

    private fun addDebitCredit(layoutDocument: Document, info: RPdfGeneratorModel) {

        val table = Table(
            UnitValue.createPointArray(
                floatArrayOf(
                    100f,
                    160f
                )
            )
        )

        table.addCell(Paragraph("Total Credit").setBold())
        table.addCell(Paragraph(info.totalCredit + ""))
        table.addCell(Paragraph("Total Debit").setBold())
        table.addCell(Paragraph(info.totalDebit + ""))
        table.addCell(Paragraph("Total Profit").setBold())
        table.addCell(Paragraph(info.totalProfit + ""))

        layoutDocument.add(table)
    }

    private fun addSubHeading(layoutDocument: Document, text: String) {
        layoutDocument.add(
            Paragraph(text).setBold()
                .setTextAlignment(TextAlignment.CENTER)
        )
    }

    private fun addLink(layoutDocument: Document, text: String) {

        val blueText: Text = Text(text)
            .setFontColor(ColorConstants.BLUE)
            .setFont(PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD))

        layoutDocument.add(
            Paragraph(blueText)
                .setAction(PdfAction.createURI(text))
                .setTextAlignment(TextAlignment.CENTER)
                .setUnderline()
                .setItalic()
        )
    }

    private fun addTitle(layoutDocument: Document, text: String) {
        layoutDocument.add(
            Paragraph(text).setBold().setUnderline()
                .setTextAlignment(TextAlignment.CENTER)
        )
    }
}

RPdfGeneratorModel

class RPdfGeneratorModel(list: List<RTransaction>, header: String) {

    var list = emptyList<RTransaction>()
    var header = ""
    var totalCredit = ""
    var totalDebit = ""
    var totalProfit = ""

    init {
        this.list = list
        this.header = header
        calculateTotal(list)
    }

    private fun calculateTotal(items: List<RTransaction>) {
        val totalPlus = items.map {
            if (it.transType == RTransactionType.plus) {
                it.totalPrice
            } else { 0.0 }
        }.sum()

        val totalMinus = items.map {
            if (it.transType == RTransactionType.minus) {
                it.totalPrice
            } else { 0.0 }
        }.sum()

        val final = totalPlus - totalMinus
        totalDebit = "-" + totalMinus.toString()
        totalCredit = totalPlus.toString()
        totalProfit = final.toString()
    }
}

RTransaction model

enum class RTransactionType { plus, minus }

class RTransaction {

    var itemName: String = ""
    var custName: String = ""
    var transType: RTransactionType = RTransactionType.plus
    var pricePerUnit: Double = 0.0
    var quantity: Int = 0
    var totalPrice: Double = 0.0
    var transactionDateStr: String = ""

    constructor() {
    }
}

write below functions in your activity class for creating dummy data

private fun dummyModel(): RPdfGeneratorModel {
        val list = dummyTransactions()
        val header = "Statement"
        val dummy = RPdfGeneratorModel(list, header)
        return dummy
    }

    private fun dummyTransactions(): List<RTransaction> {

        val list = arrayListOf<RTransaction>()

        val i1 = RTransaction()
        i1.custName = "Johan Store"
        i1.itemName = "Snacks"
        i1.quantity = 4
        i1.pricePerUnit = 40.0
        i1.totalPrice = i1.quantity * i1.pricePerUnit
        i1.transactionDateStr = "10 Sep, 20"
        i1.transType = RTransactionType.plus
        list.add(i1)


        val i2 = RTransaction()
        i2.custName = "Alice Store"
        i2.itemName = "Chocolate"
        i2.quantity = 3
        i2.pricePerUnit = 79.0
        i2.totalPrice = i2.quantity * i2.pricePerUnit
        i2.transactionDateStr = "9 Sep, 20"
        i2.transType = RTransactionType.plus
        list.add(i2)

        val i3 = RTransaction()
        i3.custName = "Alexa Mall"
        i3.itemName = "Shoes"
        i3.quantity = 2
        i3.pricePerUnit = 177.0
        i3.totalPrice = i3.quantity * i3.pricePerUnit
        i3.transactionDateStr = "9 Sep, 20"
        i3.transType = RTransactionType.minus
        list.add(i3)

        val i4 = RTransaction()
        i4.custName = "Zainab Baba"
        i4.itemName = "Chips"
        i4.quantity = 5
        i4.pricePerUnit = 140.0
        i4.totalPrice = i4.quantity * i4.pricePerUnit
        i4.transactionDateStr = "8 Sep, 20"
        i4.transType = RTransactionType.plus
        list.add(i4)

        list.add(i1)
        list.add(i2)
        list.add(i3)
        list.add(i4)

        list.add(i1)
        list.add(i2)
        list.add(i3)
        list.add(i4)


        return list
    }

Now call RPdfGenerator function. Make sure to ask WRITE_EXTERNAL_STORAGE permission before calling. For more details checkout example project

val dummyInfo = dummyModel()
                RPdfGenerator.generatePdf(this, dummyInfo)
Share:
39,706
Khushwant
Author by

Khushwant

Updated on July 09, 2022

Comments

  • Khushwant
    Khushwant almost 2 years

    How to create PDF file using iText or some other library on android?

    Is there any tutorial on iText for android?

    Thanks

  • Khushwant
    Khushwant over 12 years
    Hi Tarrant, I want to create an PDF file in android application not in java swing.
  • Khushwant
    Khushwant over 12 years
    I am using simple code to create a pdf file in my sd card using iText pdf library, but it is giving following errors. 1. Could not find class 'com.itextpdf.text.pdf.PdfGraphics2D', referenced from method com.itextpdf.text.pdf.PdfContentByte.createGraphics 2. Could not find class 'com.itextpdf.text.pdf.PdfPrinterGraphics2D', referenced from method com.itextpdf.text.pdf.PdfContentByte.createPrinterGraphics 3. ERROR/dalvikvm(309): Could not find class 'org.bouncycastle.cms.CMSEnvelopedData', referenced from method com.itextpdf.text.pdf.PdfReader.readDecryptedDocObj
  • tarrant
    tarrant over 12 years
    I'm assuming you've added the library to your project. I think you may need to run dx (in android sdk) on the jar file since unless you are using Eclipse? Dx is used to turn class files in a non-android jar into dex files so that they can be found/used on the device.
  • Khushwant
    Khushwant over 12 years
    Yes i have added library to my project & i am using eclipse as IDE.Could you please share version of iText you have used? as iText 5.0.7 is for developing apps on android but its not free.They are charging around $1500 for license. Do you have any other open source pdf library for android.Please share if you know any.
  • tarrant
    tarrant over 12 years
    I used iText 2.0.6. I believe it was open source back then.
  • GvSharma
    GvSharma almost 10 years
    getting error here.....PdfWriter.getInstance(document,new FileOutputStream(file)); tell me the possible solution
  • arTsmarT
    arTsmarT almost 10 years
    People here can help you better if you post the error. And downvoting just because a solution didn't work for you is not the way to go. Please spend some time learning the code of conduct before you post something. Also nobody is going to walk you through a solution without you having tried to debug it at least a little bit on your own.
  • Michaël Demey
    Michaël Demey over 8 years
    iTextpdf v5.0.6 is listed as the dependency. I have two issues with that. 1. 5.0.6 is insanely old. Stick to newer versions for new applications. 2. You're using iText Java and not iTextG (Android port). The Android port has a few minor modifications. To name a few: exclude the usage of API that isn't in the Android API (java.awt) and prevention of namespace clashing (BouncyCastle).
  • David Hackro
    David Hackro over 8 years
    yea, I 'm building second example using iTextG ;)
  • Samir
    Samir about 6 years
    Well. first of all thank you wish I saw your solution few hours before. Second I need to ask itext is not free isnt it ?
  • Zulqarnain
    Zulqarnain over 4 years
    I used itextg here is the gist I used to create pdf . I added the watermark, image and use table gist.github.com/mhd-zulqarnain/ee99c42c4d35dcdcaffd610507f75‌​402
  • AMIT
    AMIT over 4 years
    same code i am using, in console it is showing proper format, but after creating PDF alignment is not proper