You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用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

火山引擎 最新活动