arlomedia
arlomedia

Reputation: 9061

Draw contents of a PDF file to a Canvas

My Android app is generating multi-page PDF files programmatically using PdfDocument:

public byte[] buildPDF() {
    int pageWidth = Math.round(8.5f * 72f);
    int pageHeight = Math.round(11.0f * 72f);
    int margin = Math.round(.5f * 72f);
    int fontSize = 12;

    TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
    textPaint.setColor(Color.BLACK);
    textPaint.setTextSize(fontSize);
    textPaint.setTypeface(Typeface.DEFAULT_BOLD);

    PdfDocument document = new PdfDocument();
    PdfDocument.Page page = null;
    Canvas canvas = null;

    for (int i=0; i<10; i++) {
        PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(pageWidth, pageHeight, document.getPages().size()).create();
        page = document.startPage(pageInfo);
        canvas = page.getCanvas();

        String content = "Content for page " + (i + 1);
        canvas.drawText(content, margin, margin + fontSize, textPaint);
        document.finishPage(page);
    }

    byte[] output = new byte[0];
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    try {
        document.writeTo(outputStream);
    } catch (Exception e) {
        Log.d("buildPDF", "error writing PDF output");
        return output;
    }
    output = outputStream.toByteArray();
    document.close();

    return output;
}

In some cases, I want to place an existing PDF file from the local device into this series of pages. The easiest workflow would be to somehow open the PDF file as data, then write it to the canvas. Is there any way to do this with the Android SDK?

This is easy in iOS using CGPDFDocumentRef and CGContextDrawPDFPage, but I haven't found an equivalent for Android.

If there's no built-in way, then it seems like the multipdf package in Apache PDFBox might to the job. However, I need the data in memory as shown above, so I think that would require writing the generated data to a temp file, performing operations on the temp file and then reading the data back into memory.

Upvotes: 0

Views: 3680

Answers (2)

arlomedia
arlomedia

Reputation: 9061

CommonsWare answered my specific question (the SDK can't do this), but here's some more info about third-party tools that can:

  1. I tried Apache PDFBox, then realized it's not compatible with Android. Then I found PdfBox-Android and tried installing that, but ran into a series of build problems starting with "The number of Dex files cannot exceed 64,000...." I spent a few hours trying to get that to build before it felt like I was on a wild goose chase and I moved on.

  2. iTextG comes up a lot in situations like this, but I've always followed the rule that if a software company doesn't list its prices on its website, I can't afford it. I did go ahead and send a price request, but they forwarded my request to a reseller, and then the reseller's response went into my spam folder and I didn't see it until it was too late. Their cost was not as high as I feared, but still not very feasible given the relatively small role PDFs play in my app.

  3. I'm already using Radaee PDF as a PDF viewer in my app, and I realized that it includes some document editing and merging functions. I couldn't get this to work with the older library version I was using, but with some help from their tech support I was able to update my project for the current version, and that worked. This requires a Premium license, but they offer a flat fee pricing structure that wasn't out of reach for my project.

So, I spent most of a week dealing with third-party libraries and working out compatibility issues, but once this was running it only took 14 lines of code to get the functionality I wanted. That's a great example of why software development times are so hard to estimate ... LOL.

Upvotes: 2

CommonsWare
CommonsWare

Reputation: 1006724

My Android app is generating multi-page PDF files programmatically using PdfDocument:

Note that PdfDocument is designed for use with printing, not for creating arbitrary PDF files.

The easiest workflow would be to somehow open the PDF file as data, then write it to the canvas. Is there any way to do this with the Android SDK?

No, sorry.

Upvotes: 1

Related Questions