Android如何实现往PDF文件中插入新页面

Android平台使用iTextG在已有PDF文件中插入带有图片的新页面

本文将介绍如何在安卓平台对一个PDF文件进行插入页面操作,用到的第三方库主要为iTextG

背景

由于工作上需要实现电子发票打印机正面打印电子发票,背面打印电子账单的功能,而打印机支持双面打印,但是必须得提供一个双页的PDF文件。不巧的是后台提供的PDF源文件为单页的电子发票,故需要寻找到一个能够对已有PDF文件插入新页面方法。在经过一番搜索后,找到了iTextG这个库。

引入依赖

1
2
3
4
5
6
7
# iTextG本体
implementation 'com.itextpdf:itextg:5.5.10'
# 相关加密算法需要用到的库
implementation 'com.madgag.spongycastle:core:1.54.0.0'
implementation 'com.madgag.spongycastle:prov:1.54.0.0'
implementation 'com.madgag.spongycastle:pkix:1.54.0.0'
implementation 'com.madgag.spongycastle:pg:1.54.0.0'

使用方式

在任意的静态类中如Application中添加

1
Security.insertProviderAt(org.spongycastle.jce.provider.BouncyCastleProvider(), 1)

PDF编辑相关代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* 在发票PDF第二页插入电子账单图片
* @param dst PDF源文件路径
*/
fun insertBillPage(dst: String?) {
try { // 读取PDF文件
val pdfReader = PdfReader(dst)
// PDF修改器,我传入了项目里面的一个常量,请按需修改
val pdfStamper = PdfStamper(
pdfReader,
FileOutputStream(Constants.SD_FILE_INVOICE_DOUBLE_PAGE_PDF_CACHE)
)
pdfStamper.insertPage(
pdfReader.getNumberOfPages() + 1,
pdfReader.getPageSizeWithRotation(1)
)
// 待插入的图片,我传入了项目里面的一个常量,请按需修改
val image: Image = Image.getInstance(Constants.SD_FILE_INVOICE_BMP_CACHE)
// 由于PDF文件中电子发票页面尺寸为A5,而插入的图片过大,所以需要进行缩放操作
image.scalePercent(30.0f)
// 调整图片在页面中的位置
image.setAbsolutePosition(32, 120)
val content: PdfContentByte = pdfStamper.getUnderContent(pdfReader.getNumberOfPages())
content.addImage(image)
pdfStamper.close()
} catch (e: DocumentException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
}
}

效果预览

bill
invoice

设备: 映美IM-100T

环境

1
2
3
4
5
6
Gradle                                  5.6.4
Android Gradle Plugin Version 3.6.1
Android Studio Version Android Studio 3.6.1
Android buildToolsVersion 28.0.3
Android compileSdkVersion 28
Android Version 4.4.2

参考资料: