如何用PDFBox将现有PDF全部内容旋转90度?
嘿,我太懂你这种折腾PDF横竖页转换还得保住所有格式的崩溃感了!之前我帮朋友处理类似需求时,也踩过page.setRotation()的坑——这玩意儿根本不是真的修改页面布局,只是让阅读器“假装旋转显示”,内容的实际坐标和页面尺寸都没变化,自然达不到预期效果。
解决PDF页面横竖转换并保留格式的可行方案(基于Apache PDFBox)
要真正实现物理层面的横竖页转换(而非仅阅读器显示旋转),需要同时调整页面尺寸、旋转内容流,还要修正页面的媒体框、裁剪框等核心参数,下面是具体的落地方案:
核心思路
单纯修改旋转属性只是“表面功夫”,我们需要:
- 互换原页面的宽高尺寸,匹配目标方向的纸张大小
- 将页面内容整体旋转对应角度,同时调整偏移量确保内容在新页面内居中
- 更新页面的媒体框、裁剪框等属性,让PDF阅读器识别新的页面规格
完整代码示例
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject; import java.awt.geom.AffineTransform; import java.io.File; import java.io.IOException; public class PdfPageOrientationConverter { public static void main(String[] args) throws IOException { // 加载目标PDF try (PDDocument document = PDDocument.load(new File("input.pdf"))) { for (PDPage page : document.getPages()) { // 1. 获取原页面的基础参数 PDRectangle originalMediaBox = page.getMediaBox(); float origWidth = originalMediaBox.getWidth(); float origHeight = originalMediaBox.getHeight(); // 2. 设置新的页面尺寸(宽高互换,匹配目标方向) PDRectangle newMediaBox = new PDRectangle(origHeight, origWidth); page.setMediaBox(newMediaBox); page.setCropBox(newMediaBox); // 3. 将原页面内容转为Form XObject,方便整体旋转操作 PDFormXObject pageContentAsForm = PDFormXObject.createFormXObject(page, document); // 4. 重写页面内容:旋转+偏移,确保内容在新页面内正确显示 try (PDPageContentStream contentStream = new PDPageContentStream( document, page, PDPageContentStream.AppendMode.OVERWRITE, true, true)) { // 纵向转横向:先平移到新页面左上角,再旋转90度 contentStream.transform(AffineTransform.getTranslateInstance(origHeight, 0)); contentStream.transform(AffineTransform.getRotateInstance(Math.toRadians(90))); // 绘制旋转后的内容 contentStream.drawForm(pageContentAsForm); } // 5. 重置页面旋转属性(因为我们已经实际修改了内容布局) page.setRotation(0); } // 保存处理后的PDF document.save("output.pdf"); } } }
关键细节说明
- 为什么用Form XObject?:它能把整个页面的内容打包成一个可复用的对象,让我们可以一次性对所有内容执行旋转、平移操作,避免逐个处理文本、图片等元素的麻烦。
- 偏移量的作用:旋转后内容的坐标会偏移,
TranslateInstance(origHeight, 0)是把旋转后的内容移到新页面的左上角,防止内容跑出页面范围。如果是横向转纵向,只需要把旋转角度改成Math.toRadians(-90),平移参数改成(0, origWidth)即可。 - 复杂PDF适配:如果你的PDF包含表单、注释或交互式元素,需要额外遍历这些元素,同步调整它们的坐标和旋转属性,确保整体格式一致。
内容的提问来源于stack exchange,提问作者Paul Jay




