Java中如何用PDFBox或iText将A4纵向PDF内容缩放至5%?
当然没问题!不管是Apache PDFBox还是iText 7,都能直接通过PDF原生操作实现你的需求——完全不需要转图片,全程保持矢量内容的清晰度。下面给你分别演示两种库的实现方案:
使用Apache PDFBox实现
PDFBox通过将原页面转换为Form XObject,再通过图形变换矩阵实现缩放和定位,操作起来非常直观:
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject; import java.io.File; import java.io.IOException; public class PdfScaleWithPDFBox { public static void main(String[] args) { float scaleFactor = 0.05f; // 5%的缩放比例 String inputPdfPath = "your-input.pdf"; String outputPdfPath = "scaled-output.pdf"; try (PDDocument inputDoc = PDDocument.load(new File(inputPdfPath)); PDDocument outputDoc = new PDDocument()) { // 遍历原文档的每一页(这里示例处理单页,多页只需循环即可) for (PDPage sourcePage : inputDoc.getPages()) { // 创建新的A4纵向页面 PDPage newPage = new PDPage(PDRectangle.A4); outputDoc.addPage(newPage); // 将原页面转为Form XObject,方便复用和缩放 PDFormXObject pageForm = sourcePage.convertToFormXObject(outputDoc); try (PDPageContentStream contentStream = new PDPageContentStream(outputDoc, newPage)) { // 计算缩放后的尺寸 float scaledWidth = sourcePage.getMediaBox().getWidth() * scaleFactor; float scaledHeight = sourcePage.getMediaBox().getHeight() * scaleFactor; // 计算居中位置(让缩放后的内容在新A4页面居中显示) float centerX = (PDRectangle.A4.getWidth() - scaledWidth) / 2; float centerY = (PDRectangle.A4.getHeight() - scaledHeight) / 2; // 应用缩放和位移变换,绘制内容 contentStream.saveGraphicsState(); contentStream.transform(new float[]{scaleFactor, 0, 0, scaleFactor, centerX, centerY}); contentStream.drawForm(pageForm); contentStream.restoreGraphicsState(); } } outputDoc.save(outputPdfPath); System.out.println("缩放完成,输出文件已保存至:" + outputPdfPath); } catch (IOException e) { e.printStackTrace(); } } }
关键说明:
- 用
convertToFormXObject把原页面内容封装成可复用的对象,这是PDFBox处理页面内容缩放的标准方式 - 通过
transform方法传入变换矩阵,前四个参数是缩放比例(x和y方向都是5%),后两个是位移坐标(实现居中) - 如果原PDF有多页,直接遍历
inputDoc.getPages()即可批量处理
使用iText 7实现
iText 7的思路类似,通过复制原页面为Form XObject,再通过矩阵变换实现缩放:
import com.itextpdf.kernel.geom.PageSize; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.kernel.pdf.canvas.PdfCanvas; import com.itextpdf.kernel.pdf.xobject.PdfFormXObject; import java.io.File; import java.io.IOException; public class PdfScaleWithiText { public static void main(String[] args) { float scaleFactor = 0.05f; String inputPdfPath = "your-input.pdf"; String outputPdfPath = "scaled-output-itext.pdf"; try (PdfReader reader = new PdfReader(inputPdfPath); PdfWriter writer = new PdfWriter(outputPdfPath); PdfDocument inputDoc = new PdfDocument(reader); PdfDocument outputDoc = new PdfDocument(writer)) { // 遍历原文档的每一页(iText页码从1开始) for (int i = 1; i <= inputDoc.getNumberOfPages(); i++) { com.itextpdf.kernel.pdf.PdfPage sourcePage = inputDoc.getPage(i); // 创建新的A4纵向页面 PageSize a4 = PageSize.A4; com.itextpdf.kernel.pdf.PdfPage newPage = outputDoc.addNewPage(a4); PdfCanvas canvas = new PdfCanvas(newPage); // 将原页面复制为Form XObject PdfFormXObject pageForm = sourcePage.copyAsFormXObject(outputDoc); // 计算缩放后的尺寸和居中位置 float scaledWidth = sourcePage.getPageSize().getWidth() * scaleFactor; float scaledHeight = sourcePage.getPageSize().getHeight() * scaleFactor; float centerX = (a4.getWidth() - scaledWidth) / 2; float centerY = (a4.getHeight() - scaledHeight) / 2; // 应用变换并绘制内容 canvas.saveState(); canvas.concatMatrix(scaleFactor, 0, 0, scaleFactor, centerX, centerY); canvas.addXObject(pageForm); canvas.restoreState(); } System.out.println("缩放完成,输出文件已保存至:" + outputPdfPath); } catch (IOException e) { e.printStackTrace(); } } }
关键说明:
copyAsFormXObject是iText中复制页面内容的核心方法,保留了原内容的矢量属性concatMatrix方法和PDFBox的transform作用一致,用来设置缩放和位移- iText的页码从1开始,遍历的时候注意起始索引
两种方案都完全符合你的要求:全程基于PDF原生对象操作,没有任何转图片的步骤,缩放后的内容依然保持矢量清晰度,而且最终输出的是标准A4纵向PDF。
内容的提问来源于stack exchange,提问作者Al Phaba
相关产品推荐
相关产品推荐

