使用PDFBox调整PDF每页格式

目录

一、内容没有图片

二、内容有图片


maven依赖,这里使用的是pdfbox的2.0.30版本

XML 复制代码
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.30</version>
        </dependency>

        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox-tools</artifactId>
            <version>2.0.30</version>
        </dependency>

一、内容没有图片

如果内容没有图片,可以直接将纸张改为A4大小

java 复制代码
import java.io.File;
import java.io.IOException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;

public class AdjustPdfPageWidthToA4 {
    public static void main(String[] args) {
        // 输入的PDF文件路径
        String inputFilePath = "input.pdf";
        // 输出的PDF文件路径
        String outputFilePath = "output.pdf";
        
        try {
            // 加载PDF文件
            PDDocument document = PDDocument.load(new File(inputFilePath));
            
            // 遍历每一页
            for (PDPage page : document.getPages()) {
                // 将页面宽度调整为A4尺寸
                page.setMediaBox(PDRectangle.A4);
            }
            
            // 保存修改后的PDF文件
            document.save(outputFilePath);
            document.close();
            
            System.out.println("PDF页面宽度已调整为A4尺寸,并保存为新的PDF文件。");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

但是如果有图片的话,会出现图片被截断,显示不全的情况出现,所以我们需要对图片元素按比例缩放

二、内容有图片

首先要对页面内容进行判断,如果页面是图片的话,对图片进行比例缩放,比如A4,就缩放到可以放进A4

java 复制代码
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.text.PDFTextStripper;

import javax.imageio.ImageIO;

/**
 * @author zjy
 * @describe 调整PDF每页为A4格式
 */
public class AdjustPdfPageWidthToA4Util {
    static String inputFilePath = "C:\\xxx\\xxx\\xx.pdf";
    // 输出的PDF文件路径
    static String outputFilePath = "D:\\result.pdf";

    public static void main(String[] args) {

        try {
            // 加载PDF文件
            PDDocument document = PDDocument.load(new File(inputFilePath));

            // 遍历每一页
            int totalPages = document.getNumberOfPages();

            for (int i = 0; i < totalPages; i++) {
                // 获取当前Page页面
                PDPage page = document.getPage(i);
                // 获取对应页面的资源对象
                PDResources resources = page.getResources();
                // 遍历当前页面所有内容,找出图片对象
                for (COSName cosName : resources.getXObjectNames()) {
                    PDXObject pdxObject = resources.getXObject(cosName);
                    // 判断是不是图片对象
                    if (pdxObject instanceof PDImageXObject) {
                        // 获取图片对象
                        PDImageXObject pdxObject1 = (PDImageXObject) pdxObject;
                        BufferedImage image = pdxObject1.getImage();
                        // 4、创建页面内容流,指定操作哪个文档中的哪个页面
                        PDPageContentStream stream = new PDPageContentStream(document, page);
                        float[] imageWH = getImageWH(image, PDRectangle.A4);
                        stream.drawImage(pdxObject1, imageWH[0], imageWH[1], imageWH[2], imageWH[3]); // 绘制图片到PDF页面里面
                        stream.close(); // 关闭页面内容流
                        page.setMediaBox(PDRectangle.A4);

                    } else {
                        page.setMediaBox(PDRectangle.A4);
                    }
                }

            }

            // 保存修改后的PDF文件
            document.save(outputFilePath);
            document.close();

            System.out.println("PDF页面宽度已调整为A4尺寸,并保存为新的PDF文件。");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取图片的宽度、高度,单位是【pt】
     *
     * @param box PDF文档页面矩形区域对象,可以获取到矩形区域的宽高
     * @return 返回缩放之后的图片宽高
     */
    public static float[] getImageWH(BufferedImage img, PDRectangle box) {
        try {
            // px 转换成 pt 单位
            float xAxis;
            float yAxis;
            int w = img.getWidth();
            int h = img.getHeight();
            float width = (float) (w * 3.0 / 4); // 这里是因为 1pt = 3/4 px,pt和px单位转换
            float height = (float) (h * 3.0 / 4);
            float pw = box.getWidth() - 60; // 设置图片与文档边缘的空白间距
            float ph = box.getHeight() - 60; // 设置图片与文档边缘的空白间距
            if (width > pw) {
                float scale = pw / width;  // 缩放比列
                width = pw; // 宽度等于页面宽度
                height = height * scale; // 高度自动缩放
            } else {
                float scale = ph / height;  // 缩放比列
                height = ph; // 高度等于页面高度
                width = width * scale;  // 宽度自动缩放
            }
            // 计算图片在X、Y轴上的显示位置
            xAxis = (box.getWidth() - width) / 2; // X轴居中对齐
//            yAxis = box.getHeight() - height - 10; // 距离页面顶部10个pt
            yAxis = (box.getHeight() - height) / 2; // Y轴垂直居中对齐
            return new float[]{xAxis, yAxis, width, height};
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new float[]{0, 0, 0, 0};
    }
}

运行完如下图所示,图片缩小至能放入A4,放在正中间

三、改进

上面的代码是将图片等比例缩小到A4能够放得下,也就是上下或者左右可能有很大的空白,图片比较小,难以看清,因此改进

java 复制代码
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.text.PDFTextStripper;

import javax.imageio.ImageIO;

/**
 * @author zjy
 * @describe 调整PDF每页为A4格式
 */
public class AdjustPdfPageWidthToA4Util {
    static String inputFilePath = "C:\\xxx\\xxx\\xx.pdf";
    // 输出的PDF文件路径
    static String outputFilePath = "D:\\result.pdf";

    public static void main(String[] args) {

        try {
            // 加载PDF文件
            PDDocument document = PDDocument.load(new File(inputFilePath));

            // 遍历每一页
            int totalPages = document.getNumberOfPages();

            for (int i = 0; i < totalPages; i++) {
                // 获取当前Page页面
                PDPage page = document.getPage(i);
                // 获取对应页面的资源对象
                PDResources resources = page.getResources();
                // 遍历当前页面所有内容,找出图片对象
                for (COSName cosName : resources.getXObjectNames()) {
                    PDXObject pdxObject = resources.getXObject(cosName);
                    // 判断是不是图片对象
                    if (pdxObject instanceof PDImageXObject) {
                        // 获取图片对象
                        PDImageXObject pdxObject1 = (PDImageXObject) pdxObject;
                        BufferedImage image = pdxObject1.getImage();
                        // 4、创建页面内容流,指定操作哪个文档中的哪个页面
                        PDPageContentStream stream = new PDPageContentStream(document, page);
                        float[] imageWH = getImageWH(image, PDRectangle.A4);
                        stream.drawImage(pdxObject1, 0, 0, imageWH[0], imageWH[1]); // 绘制图片到PDF页面里面
                        stream.close(); // 关闭页面内容流
//                        page.setMediaBox(PDRectangle.A4);
                        page.setMediaBox(new PDRectangle(imageWH[0], imageWH[1]));

                    } else {
                        page.setMediaBox(PDRectangle.A4);
                    }
                }

            }

            // 保存修改后的PDF文件
            document.save(outputFilePath);
            document.close();

            System.out.println("PDF页面宽度已调整为A4尺寸,并保存为新的PDF文件。");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取图片的宽度、高度,单位是【pt】
     *
     * @param box PDF文档页面矩形区域对象,可以获取到矩形区域的宽高
     * @return 返回缩放之后的图片宽高
     */
    public static float[] getImageWH(BufferedImage img, PDRectangle box) {
        try {
            // px 转换成 pt 单位
            float xAxis;
            float yAxis;
            int w = img.getWidth();
            int h = img.getHeight();
            float width = (float) (w * 3.0 / 4); // 这里是因为 1pt = 3/4 px,pt和px单位转换
            float height = (float) (h * 3.0 / 4);
            float pw = box.getWidth() ;
            float ph = box.getHeight() ;
            if (width > pw) {
                float scale = pw / width;  // 缩放比列
                width = pw; // 宽度等于页面宽度
                height = height * scale; // 高度自动缩放
            } else {
                float scale = ph / height;  // 缩放比列
                height = ph; // 高度等于页面高度
                width = width * scale;  // 宽度自动缩放
            }
            // 计算图片在X、Y轴上的显示位置
            return new float[]{width, height};
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new float[]{0, 0};
    }
}

这样子图片的宽度是A4的,长度就是原图片的长度了

以上内容参考以下博客【PDFBox】PDFBox操作PDF文档之添加本地图片、添加网络图片、图片宽高自适应、图片水平垂直居中对齐-支持Android_pdfbox缩放比例-CSDN博客文章浏览阅读322次,点赞2次,收藏3次。PDImageXObject类中提个了一些静态方法createFromFile(imagePath,doc)方法:采用File文件的方式读取本地磁盘中的图片。imagePath参数:图片的路径。doc参数:PDF文档对象。getImage()方法:返回BufferedImage图片对象。getSuffix()方法:返回图片的后缀类型,例如:jpg、png等。_pdfbox缩放比例https://blog.csdn.net/qq_27489007/article/details/134451128

相关推荐
π大星星️1 小时前
Jenkins 工作流程
运维·jenkins
Juicedata2 小时前
JuiceFS v1.3-Beta2:集成 Apache Ranger,实现更精细化的权限控制
运维·人工智能·ai
IT成长日记2 小时前
05【Linux经典命令】Linux 用户管理全面指南:从基础到高级操作
linux·运维·服务器·用户管理·命令
资讯第一线6 小时前
Windows系统工具:WinToolsPlus 之 SQL Server Suspect/质疑/置疑/可疑/单用户等 修复
运维
惊起白鸽4506 小时前
LVS负载均衡
运维·负载均衡·lvs
Sapphire~8 小时前
Linux-07 ubuntu 的 chrome 启动不了
linux·chrome·ubuntu
伤不起bb8 小时前
NoSQL 之 Redis 配置与优化
linux·运维·数据库·redis·nosql
广东数字化转型8 小时前
nginx怎么使用nginx-rtmp-module模块实现直播间功能
linux·运维·nginx
love530love8 小时前
【笔记】在 MSYS2(MINGW64)中正确安装 Rust
运维·开发语言·人工智能·windows·笔记·python·rust
啵啵学习8 小时前
Linux 里 su 和 sudo 命令这两个有什么不一样?
linux·运维·服务器·单片机·ubuntu·centos·嵌入式