如何用iText库合并PDF并保证页面方向正确?
解决iText合并PDF时横向页面方向错误的问题
嘿,这个问题我之前帮人踩过坑!用iText合并横向和纵向PDF时,最容易栽在页面方向和内容旋转不匹配的问题上,我来给你捋清楚怎么搞定~
问题根源
你之前遇到的情况本质是:直接设置document.setPageSize(PageSize.A4.rotate())只是强制把页面的物理尺寸改成了横向,但原横向PDF的内容大概率是先以纵向绘制,再通过页面自身的Rotate属性旋转显示的。只改页面尺寸的话,内容的旋转状态没被正确保留,就会出现页面是横向但文字还是纵向的尴尬情况。
解决方案分版本说明
iText 5和iText 7的API差异挺大的,我分别给你对应代码:
1. iText 5版本(旧版)
需要手动读取每个源页面的旋转属性,并在复制页面时保留这个属性,别用统一设置document页面尺寸的方式:
import com.itextpdf.text.Document; import com.itextpdf.text.pdf.PdfCopy; import com.itextpdf.text.pdf.PdfImportedPage; import com.itextpdf.text.pdf.PdfReader; import java.io.FileOutputStream; import java.util.Arrays; import java.util.List; public class PdfMerger { public static void main(String[] args) throws Exception { // 初始化目标文档和PdfCopy实例 Document document = new Document(); PdfCopy pdfCopy = new PdfCopy(document, new FileOutputStream("merged_result.pdf")); document.open(); // 处理横向PDF文件 PdfReader horizontalReader = new PdfReader("your_horizontal_file.pdf"); int horizontalPageCount = horizontalReader.getNumberOfPages(); for (int i = 1; i <= horizontalPageCount; i++) { PdfImportedPage importedPage = pdfCopy.getImportedPage(horizontalReader, i); // 获取原页面的旋转角度 int pageRotation = horizontalReader.getPageRotation(i); // 添加页面并同步设置旋转属性 pdfCopy.addPage(importedPage); pdfCopy.setPageRotation(i, pageRotation); } horizontalReader.close(); // 处理多个纵向PDF文件 List<String> verticalFiles = Arrays.asList("vertical1.pdf", "vertical2.pdf", "vertical3.pdf"); int currentPage = horizontalPageCount + 1; // 记录目标文档当前页码 for (String verticalFile : verticalFiles) { PdfReader verticalReader = new PdfReader(verticalFile); int verticalPageCount = verticalReader.getNumberOfPages(); for (int i = 1; i <= verticalPageCount; i++) { PdfImportedPage importedPage = pdfCopy.getImportedPage(verticalReader, i); int pageRotation = verticalReader.getPageRotation(i); pdfCopy.addPage(importedPage); pdfCopy.setPageRotation(currentPage, pageRotation); currentPage++; } verticalReader.close(); } document.close(); pdfCopy.close(); } }
2. iText 7版本(推荐新版)
iText 7的PdfMergerAPI做了优化,会自动保留每个源页面的尺寸、旋转属性和内容方向,代码简洁到离谱:
import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.pdfmerger.PdfMerger; import java.util.Arrays; import java.util.List; public class PdfMerger7 { public static void main(String[] args) throws Exception { // 初始化目标文档 PdfDocument mergedPdf = new PdfDocument(new PdfWriter("merged_result.pdf")); PdfMerger merger = new PdfMerger(mergedPdf); // 合并横向PDF PdfDocument horizontalPdf = new PdfDocument(new PdfReader("your_horizontal_file.pdf")); merger.merge(horizontalPdf, 1, horizontalPdf.getNumberOfPages()); horizontalPdf.close(); // 合并多个纵向PDF List<String> verticalFiles = Arrays.asList("vertical1.pdf", "vertical2.pdf", "vertical3.pdf"); for (String verticalFile : verticalFiles) { PdfDocument verticalPdf = new PdfDocument(new PdfReader(verticalFile)); merger.merge(verticalPdf, 1, verticalPdf.getNumberOfPages()); verticalPdf.close(); } mergedPdf.close(); } }
关键提醒
- 别用统一设置
document.setPageSize()的方式强制改页面方向,这会覆盖原页面的个性化属性,反而弄巧成拙。 - 优先升级到iText 7,API更直观,坑更少,处理页面属性的逻辑也更完善。
内容的提问来源于stack exchange,提问作者Virkom




