25

I'm attempting to open an existing pdf file and then add another page to the pdf document from within an Android application. On the added page, I need to add some text and an image.

I am wanting to give PDFBox a try. Other solutions such as iTextPDF aren't suitable for our company because of the licencing terms/price.

I have a library project with the main code base, and also full and lite projects that reference the library project.

I have downloaded the jar from http://pdfbox.apache.org/download.html and copied it into the library projects lib folder and added the pdfbox-app-1.6.0.jar file to the java build path libraries.

I am able to import the librarys successfully eg import org.apache.pdfbox.pdmodel.PDDocument; and compile all the projects. However when I run the application it crashes on PDDocument document = new PDDocument(); with the following error.

E/AndroidRuntime(24451): java.lang.NoClassDefFoundError: org.apache.pdfbox.pdmodel.PDDocument

I read somewhere that version 1.5 of PDFBox onwards didn't work with Android so I tried downloading the pdfbox-app-1.4.0.jar file but got the same issue. I also added the library to the build path in my full and lite projects but I got the same error or eclipse kept crashing with an out of memory error.

Can anyone tell me what I am doing wrong? Have I downloaded the wrong file? Have I imported it correctly?

Thanks,

Dittimon
  • 986
  • 2
  • 14
  • 28

4 Answers4

19

PDFBox uses java awt and swing, even for non UI tasks, I've tried to remove references but there are a lot of files, and I was removing too much stuff

I've just tested PDFjet http://pdfjet.com/os/edition.html it's bsd licensed (plus commercial version with more features), with this sample code (ripped from Example_03.java) I was able to convert a jpeg to a pdf

    FileOutputStream fos = null;
    try
    {
        fos = new FileOutputStream("/sdcard/sample.pdf");
        PDF pdf = new PDF(fos);
        InputStream f = getApplicationContext().getAssets().open("img0.jpg"); 
        Image image = new Image(pdf, f, ImageType.JPEG);
        Page page = new Page(pdf, A4.PORTRAIT);
        image.setPosition(0, 0);
        image.drawOn(page);
        pdf.flush();
        fos.close();
    } catch (Exception e)
    {
        e.printStackTrace();
    }

I found the link here http://java-source.net/open-source/pdf-libraries

sherpya
  • 4,890
  • 2
  • 34
  • 50
  • 2
    Please let me know if you are aware of any examples which achieve the reverse i.e. PDF->Image using PDFJet. I've gone through most of the examples.All of them seem to be passing an instance of new FileOutputStream to the PDF() constructor method, which I believe is suggestive of the fact that we are trying to create a new PDF. Instead what I seek is the ability to read/parse an existing pdf. Thanks. – Sdr Apr 10 '13 at 18:47
  • 1
    @sherpya how to integrate PDFjet into android project? – Chirag Shah May 07 '13 at 08:00
  • 1
    I did it some time ago, but I think you can just put the .jar in the lib subdirectory of the project – sherpya May 07 '13 at 13:17
16

Android Port of PDFBox

There's a free Android Port of PDFBox available here:

https://github.com/TomRoush/PdfBox-Android

Tilman Hausherr
  • 17,731
  • 7
  • 58
  • 97
Jason
  • 13,563
  • 15
  • 74
  • 125
0

I got the same error. I've solved this way, the documentation says:

Before calls to PDFBox are made it is required to initialize the library's resource loader. Add the following line before calling PDFBox methods:

PDFBoxResourceLoader.init(getApplicationContext());

An example app is located in the sample directory and includes examples of common tasks.

To read a PDF from Uri with PDFBox i just do:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    if (requestCode == ESCOGER_DOCUMENTO_REQUEST_CODE) {
        if (resultCode == RESULT_OK && data != null) {
            Uri archivo = data.getData();
            switch (extensionArchivo(this, archivo)) {
                case "jpg":
                case "png":
                    //Procesar imagen
                    break;
                case "pdf":
                    PDFBoxResourceLoader.init(getApplicationContext());
                    ContentResolver contentResolver = getContentResolver();      // Get a content resolver to access the Uri
                    InputStream inputStream = null;                              // Open an input stream to the Uri
                    try {
                        inputStream = contentResolver.openInputStream(archivo);
                    } catch (IOException e) {
                        //Log.e("PdfBox-Android-Sample", "Exception thrown while loading document to strip", e);
                    }
                    String parsedText = null;                                    // Load the PDF document from the input stream
                    PDDocument document = null;
                    try {
                        document = PDDocument.load(inputStream);
                    } catch (IOException e) {
                        //Log.e("PdfBox-Android-Sample", "Exception thrown while loading document to strip", e);
                    }

                    try {
                        PDFTextStripper pdfStripper = new PDFTextStripper();
                        pdfStripper.setStartPage(0);
                        pdfStripper.setEndPage(1);
                        parsedText = "Parsed text: " + pdfStripper.getText(document);
                    } catch (IOException e) {
                        //Log.e("PdfBox-Android-Sample", "Exception thrown while stripping text", e);
                    } finally {
                        try {
                            if (document != null) document.close();
                        } catch (IOException e) {
                            //Log.e("PdfBox-Android-Sample", "Exception thrown while closing document", e);
                        }
                    }
                    Toast.makeText(this, parsedText, Toast.LENGTH_SHORT).show();
                    break;
                default:
                    // Salir y mostrar mensaje "Archivo no permitido"
            }

        } else {
            Toast.makeText(this, "Error al subir documento", Toast.LENGTH_LONG).show();
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}
Angel
  • 190
  • 2
  • 10
0

i think the library class files are not included in the apk file. The library classes need to be converted into dex files then only it will be detected.please refer http://developer.android.com/guide/developing/building/index.html

sateesh
  • 121
  • 1
  • 3