Android環境下生成PDF檔案

weixin_34054866發表於2017-10-20

一、應用場景

從本地選擇圖片生成pdf檔案,由於Android本身並沒有對pdf的支援,這裡選擇使用一個第三方的庫來達成需求。


1908171-f08cb2bb2a9ef62f.jpg
image

1908171-b17cf32cd7c2a2ec.jpg
image

1908171-1af9dd447ace6f80.jpg
image

1908171-eb313f69a77847db.jpg
image

二、庫的選擇

2.1 當前主流的庫

在眾多Java語言編寫的PDf庫中,對Android有支援且有一定使用者量的的有:iText、Qoppa qPDF工具包、PDFJet。

2.2 三個庫的對比如下:

~ iText Qoppa PDFJet
應用檔案大小 1.52MB 0.93MB 0.67MB
時間消耗 3.7ms 39ms 51.3ms
平均CPU利用率 29% 77.9% 86.8%
修改PDF 沒有
加密 沒有
形式欄位函式 沒有
文字提取 沒有
將PDF轉換為影像 沒有 沒有
開源 沒有
書可用 沒有 沒有
論壇,郵件列表 沒有 沒有

2.3 選型

鑑於效能和開源,決定選擇iText作為此次接入的PDF庫。

三、iText庫接入

3.1 資源說明

3.1.1 下載連結

https://github.com/itext/itextpdf/tree/itextg

3.1.2 下載說明

If you want to use iText on Android or the Google App Engine, you need to use iTextG. iTextG is almost identical to iText, except that it only uses classes that are white-listed by Google. All references to java.awt, javax.nio and other "forbidden" packages have been removed.(在Android上使用iText,需要使用iTextG。iTextG與iText基本相同,只是替換掉了java.awt,javax.nio等Android上不支援的包。)

3.1.3 混淆說明

# itext
-dontwarn com.itextpdf.**
-keep class com.itextpdf.** {*;}

3.2 圖片生成pdf方法

3.2.1 設定pdf每頁的背景

public class PdfBackground extends PdfPageEventHelper {
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        //設定pdf背景色為白色
        PdfContentByte canvas = writer.getDirectContentUnder();
        Rectangle rect = document.getPageSize();
        canvas.setColorFill(BaseColor.WHITE);
        canvas.rectangle(rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight());
        canvas.fill();
 
        //設定pdf頁面內間距
        PdfContentByte canvasBorder = writer.getDirectContent();
        Rectangle rectBorder = document.getPageSize();
        rectBorder.setBorder(Rectangle.BOX);
        rectBorder.setBorderWidth(BORDER_WIDTH);
        rectBorder.setBorderColor(BaseColor.WHITE);
        rectBorder.setUseVariableBorders(true);
        canvasBorder.rectangle(rectBorder);
    }
}

3.2.2 根據圖片Uri生成pdf

/**
 * 根據圖片生成PDF
 *
 * @param pdfPath 生成的PDF檔案的路徑
 * @param imagePathList 待生成PDF檔案的圖片集合
 * @throws IOException 可能出現的IO操作異常
 * @throws DocumentException PDF生成異常
 */
private void createPdf(String pdfPath, List<String> imagePathList) throws IOException, DocumentException {
    Document document = new Document();
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdfPath));
     
    //設定pdf背景
    PdfBackground event = new PdfBackground();
    writer.setPageEvent(event);
     
    document.open();
    for (int i = 0; i < imagePathList.size(); i++) {
        document.newPage();
        Image img = Image.getInstance(imagePathList.get(i));
        //設定圖片縮放到A4紙的大小
        img.scaleToFit(PageSize.A4.getWidth() - BORDER_WIDTH * 2, PageSize.A4.getHeight() - BORDER_WIDTH * 2);
        //設定圖片的顯示位置(居中)
        img.setAbsolutePosition((PageSize.A4.getWidth() - img.getScaledWidth()) / 2, (PageSize.A4.getHeight() - img.getScaledHeight()) / 2);
        document.add(img);
    }
    document.close();
}

四、參考文獻

4.1 iText官方網站:

http://itextpdf.com/

4.2 iText5圖片處理相關examples:

http://developers.itextpdf.com/examples/image-examples-itext5

4.3 Stefan Fenz的部落格地址:

http://stefan.fenz.at/creating-pdfs-on-android-an-evaluation/

五、DEMO下載

https://github.com/zhufeng1222/PdfBuilder

相關文章