- 优化方法一:使用PdfSmartCopy类代替PdfCopy类。这个类可以在合并PDF文件时,检测并消除重复的对象,从而减少内存的占用。您可以参考以下代码示例:
java
//创建一个Document对象
Document document = new Document();
//创建一个PdfSmartCopy对象
PdfSmartCopy copy = new PdfSmartCopy(document, new FileOutputStream("output.pdf"));
//打开Document对象
document.open();
//创建一个PdfReader对象
PdfReader reader = null;
//遍历要合并的PDF文件
for (String file : files) {
//加载PDF文件
reader = new PdfReader(file);
//获取PDF文件的总页数
int n = reader.getNumberOfPages();
//遍历每一页,添加到PdfSmartCopy对象中
for (int page = 0; page < n;) {
copy.addPage(copy.getImportedPage(reader, ++page));
}
}
//关闭PdfReader对象
reader.close();
//关闭Document对象
document.close();
//创建一个PdfStamper对象
PdfStamper stamper = new PdfStamper(new PdfReader("output.pdf"), new FileOutputStream("output.pdf"));
//获取总页数
int pageCount = stamper.getReader().getNumberOfPages();
//遍历每一页,添加页码
for (int i = 1; i <= pageCount; i++) {
//获取当前页
PdfContentByte content = stamper.getOverContent(i);
//设置字体和颜色
content.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 12);
content.setRGBColorFill(0, 0, 0);
//获取当前页的宽度和高度
Rectangle pageSize = stamper.getReader().getPageSize(i);
float width = pageSize.getWidth();
float height = pageSize.getHeight();
//计算页码的位置
float x = width / 2;
float y = 10;
//添加页码
content.beginText();
content.showTextAligned(PdfContentByte.ALIGN_CENTER, "第" + i + "页,共" + pageCount + "页", x, y, 0);
content.endText();
}
//关闭PdfStamper对象
stamper.close();
- 优化方法二:使用PdfWriter类代替PdfCopy类。这个类可以在合并PDF文件时,直接将每一页写入到输出流中,而不需要将整个文档加载到内存中。可以参考以下代码示例:
java
//创建一个Document对象
Document document = new Document();
//创建一个PdfWriter对象
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));
//打开Document对象
document.open();
//创建一个PdfImportedPage对象
PdfImportedPage page = null;
//创建一个PdfReader对象
PdfReader reader = null;
//遍历要合并的PDF文件
for (String file : files) {
//加载PDF文件
reader = new PdfReader(file);
//获取PDF文件的总页数
int n = reader.getNumberOfPages();
//遍历每一页,添加到PdfWriter对象中
for (int i = 1; i <= n; i++) {
//获取当前页的宽度和高度
Rectangle pageSize = reader.getPageSizeWithRotation(i);
float width = pageSize.getWidth();
float height = pageSize.getHeight();
//设置Document对象的页面大小
document.setPageSize(pageSize);
//创建一个新的页面
document.newPage();
//导入当前页
page = writer.getImportedPage(reader, i);
//将当前页添加到PdfWriter对象中
writer.addPageDictEntry(PdfName.ROTATE, pageSize.getRotationAsPageDictEntry());
writer.addDirectImageSimple(page);
writer.getCurrentPage().add(page);
//创建一个PdfContentByte对象
PdfContentByte content = writer.getDirectContent();
//设置字体和颜色
content.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 12);
content.setRGBColorFill(0, 0, 0);
//计算页码的位置
float x = width / 2;
float y = 10;
//添加页码
content.beginText();
content.showTextAligned(PdfContentByte.ALIGN_CENTER, "第" + i + "页,共" + pageCount + "页", x, y, 0);
content.endText();
}
}
//关闭PdfReader对象
reader.close();
//关闭Document对象
document.close();
- 优化方法三:使用PdfReader类的partial和selectPages方法。这些方法可以在加载PDF文件时,只读取需要的页面,而不需要将整个文档加载到内存中。可以参考以下代码示例:
java
//创建一个Document对象
Document document = new Document();
//创建一个PdfCopy对象
PdfCopy copy = new PdfCopy(document, new FileOutputStream("output.pdf"));
//打开Document对象
document.open();
//创建一个PdfReader对象
PdfReader reader = null;
//遍历要合并的PDF文件
for (String file : files) {
//设置partial为true,只读取需要的页面
reader = new PdfReader(new RandomAccessFileOrArray(file), null);
reader.consolidateNamedDestinations();
reader.partial = true;
//获取PDF文件的总页数
int n = reader.getNumberOfPages();
//创建一个List对象,存储需要的页面
List<Integer> pages = new ArrayList<Integer>();
//遍历每一页,添加到List对象中
for (int i = 1; i <= n; i++) {
pages.add(i);
}
//使用selectPages方法,只选择需要的页面
reader.selectPages(pages);
//将选择的页面添加到PdfCopy对象中
for (int i = 0; i < pages.size(); ) {
copy.addPage(copy.getImportedPage(reader, ++i));
}
}
//关闭PdfReader对象
reader.close();
//关闭Document对象
document.close();
//创建一个PdfStamper对象
PdfStamper stamper = new PdfStamper(new PdfReader("output.pdf"), new FileOutputStream("output.pdf"));
//获取总页数
int pageCount = stamper.getReader().getNumberOfPages();
//遍历每一页,添加页码
for (int i = 1; i <= pageCount; i++) {
//获取当前页
PdfContentByte content = stamper.getOverContent(i);
//设置字体和颜色
content.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 12);
content.setRGBColorFill(0, 0, 0);
//获取当前页的宽度和高度
Rectangle pageSize = stamper.getReader().getPageSize(i);
float width = pageSize.getWidth();
float height = pageSize.getHeight();
//计算页码的位置
float x = width / 2;
float y = 10;
//添加页码
content.beginText();
content.showTextAligned(PdfContentByte.ALIGN_CENTER, "第" + i + "页,共" + pageCount + "页", x, y, 0);
content.endText();
}
//关闭PdfStamper对象
stamper.close();
[java - How to avoid OutOfMemoryError when merging PDFs using iText? - Stack Overflow]
[java - How to merge pdf files without loading all the documents in memory? - Stack Overflow]
[java - How to merge pdf files without loading all the documents in memory? - Stack Overflow]