使用PDFBox调整PDF每页格式

news2024/12/25 13:54:30

目录

一、内容没有图片

二、内容有图片


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

        <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大小

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

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能够放得下,也就是上下或者左右可能有很大的空白,图片比较小,难以看清,因此改进

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1538481.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于python+vue 的一加剧场管理系统的设计与实现flask-django-nodejs-php

二十一世纪我们的社会进入了信息时代&#xff0c;信息管理系统的建立&#xff0c;大大提高了人们信息化水平。传统的管理方式对时间、地点的限制太多&#xff0c;而在线管理系统刚好能满足这些需求&#xff0c;在线管理系统突破了传统管理方式的局限性。于是本文针对这一需求设…

vue 消息左右滚动(前后无缝衔接)

演示效果 封装的组件 <!--* Author:* Date: 2024-03-21 19:21:58* LastEditTime: 2024-03-21 20:31:50* LastEditors: Please set LastEditors* Description: 消息左右滚动 --> <template><divid"textScroll"class"text-scroll"mousemove&…

Alibaba spring cloud Dubbo使用(基于Zookeeper或者基于Nacos+泛化调用完整代码一键启动)

Quick Start Dubbo&#xff01;用更优雅的方式来实现RPC调用吧 - 掘金 dubbozookeeper demo 项目结构&#xff1a; RpcService 仅仅是提供服务的接口&#xff1a; public interface HelloService {String sayHello(String name); }DubboServer pom&#xff1a; <?xm…

分布式之网关介绍

一、网关简介 1、网关背景 由于微服务“各自为政的特性”使微服务的使用非常麻烦。通常公司会有一个“前台小姐姐”作为统一入口&#xff0c;这就是网关 2、网关作用 统一入口&#xff1a;为服务提供一个唯一的入口&#xff0c;网关起到外部和内部隔离的作用&#xff0c; 保…

软考中级 --网络工程师真题试卷 2023下半年

在EIGRP协议中&#xff0c;某个路由器收到了两条路径到达目标网络&#xff0c;路径1的带宽为100Mbps&#xff0c;延迟2ms&#xff0c;路径2的带宽为50Mbps&#xff0c;迟为4ms&#xff0c;如果EIGRP使用带宽和延迟的综合度量标准&#xff0c;那么该路由器选择的最佳路径是(D)。…

STM32 CubeMX使用介绍(含FreeRTOS生成)

文章目录 前言1. 简介1.1 什么是STM32CubeMX1.2 为什么会有STM32CubeMX的出现1.3 STM32CubeMX常用功能有哪些&#xff1f;1.4 官方资料下载地址 2. 下载和安装STM32CubeMX2.1 下载软件2.2 软件安装 3. 使用方式3.1 说明3.2 不同选择器介绍3.3 构建新的项目3.1 选择单片机的型号…

处理登录失效后提示多个错误

问题: 我的场景是后端规定&#xff0c;即使登录失效返回的code仍是200&#xff0c;然后data的code是999什么的&#xff1b; 原本代码&#xff1a; 修改版代码&#xff1a; 通过节 const NotLoginEvent () > {router.replace("/login");localStorage.clear();M…

对话悠易科技蔡芳:品牌逐渐回归核心能力建设,布局和构建自己的流量阵地

关于SaaS模式在中国的发展&#xff0c;网上出现多种声音。Marteker近期采访了一些行业专家&#xff0c;围绕SaaS模式以及Martech在中国的发展提出独特观点。悠易科技副总裁蔡芳认为&#xff0c;中国目前存在SaaS的应用场景与客户需求&#xff0c;用户的应用能力也在提升&#x…

element-ui radio-group 组件源码分享

接着上篇的 radio 组件源码分享&#xff0c;继续探索 radio-group 源码部分的实现过程&#xff0c;主要从以下四个方面来讲解&#xff1a; 1、el-radio-group 页面结构 2、el-radio-group 组件属性 3、el-radio-group 组件方法 4、核心代码部分 一、页面结构&#xff0c;如…

一文搞懂Log4j2的同步日志打印

前言 Log4j2诞生于2012年&#xff0c;是Apache推出用于对标Logback的日志框架&#xff0c;本篇文章将对Log4j2的同步日志打印的源码进行学习。 Log4j2版本&#xff1a;2.17.1 正文 一. Logger获取 通常&#xff0c;使用Slf4j的LoggerFactory获取Log4j2的Logger的代码如下所…

无插件网页视频播放器,支持图像绘制(包含方格子、方框等),支持音视频播放、支持录像截图,提供源码下载

前言 本播放器内部采用jessibuca插件接口&#xff0c;支持录像、截图、音视频播放等功能。播放器播放基于ws流&#xff0c;图像绘制操作&#xff1a;1&#xff09;支持绘制方格子&#xff0c;用于监控移动检测画框&#xff1b;2&#xff09;支持绘制不透明方框&#xff0c;用于…

ExoPlayer架构详解与源码分析(11)——DataSource

系列文章目录 ExoPlayer架构详解与源码分析&#xff08;1&#xff09;——前言 ExoPlayer架构详解与源码分析&#xff08;2&#xff09;——Player ExoPlayer架构详解与源码分析&#xff08;3&#xff09;——Timeline ExoPlayer架构详解与源码分析&#xff08;4&#xff09;—…

探索SDK技术架构:构建高效稳定的开发工具

随着移动应用和软件开发的不断发展&#xff0c;SDK&#xff08;Software Development Kit&#xff09;已经成为开发者们日常工作中不可或缺的利器。SDK作为一种开发工具包&#xff0c;能够提供丰富的功能和接口&#xff0c;帮助开发者加快应用开发的速度&#xff0c;提升软件质…

【Web应用技术基础】HTML(6)——案例2:填写简历信息

样式&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>填写简历信息&…

探索uni-app项目的架构与开发实践:快速开发的项目模板参考

摘要&#xff1a;本文将深入探讨uni-app项目架构的模板设计&#xff0c;以及如何通过使用该模板实现快速开发。我们将重点介绍模板中的组件示例、SDK示例和模板页面&#xff0c;并阐述它们在提高开发效率和优化用户体验方面的作用。 一、引言 随着移动互联网的迅猛发展&#…

环信新版单群聊UIKit集成指南——Android篇

前言 环信新版UIKit已重磅发布&#xff01;目前包含单群聊UIKit、聊天室ChatroomUIKit&#xff0c;本文详细讲解Android端单群聊UIKit的集成教程。 环信单群聊 UIKit 是基于环信即时通讯云 IM SDK 开发的一款即时通讯 UI 组件库&#xff0c;提供各种组件实现会话列表、聊天界…

Jetson AGX ORIN 配置 FGVC-PIM 神经网络

Jetson AGX ORIN 配置 FGVC-PIM 神经网络 文章目录 Jetson AGX ORIN 配置 FGVC-PIM 神经网络配置 ORIN 环境创建 FGVC-PIM 虚拟环境安装 PyTorch安装 torchvision安装其他依赖包 配置 ORIN 环境 首先先配置 ORIN 的环境&#xff0c;可以参考这个链接&#xff1a; Jetson AGX …

UE5制作推箱子动作时获取物体与角色朝向的角度及跨蓝图修改变量

就是脑残死磕&#xff0c;你们如果有更好的方法一定要留言啊~~独乐乐不如众乐乐。 做推箱子的时候需要考虑脸是不是面对着箱子&#xff0c;不是必须90度&#xff0c;可以有一个-45~45度的范围。 摸索了一下&#xff0c;有几种做法和几个小白坑&#xff0c;这里列出来。 一、准…

Etcd Raft 协议(进阶篇)

前言 在正式开始介绍 Raft 协议之间&#xff0c;我们有必要简单介绍一下其相关概念。在分布式系统中&#xff0c;一致性是比较常见的概念&#xff0c;所谓一致性指的是集群中的多个节点在状态上达成一致。在程序和操作系统不会崩溃、硬件不会损坏、服务器不会掉电、网络绝对可靠…

电商系统秒杀二 秒杀场景下如何进行限流

本章学习内容 1、在秒杀页面&#xff0c;客户点击秒杀后&#xff0c;在前台弹出一个验证码&#xff0c;需要用户输入验证码才能往后端发送请求&#xff0c;这样能够错开秒杀下单的时间。 2、通过验证码&#xff0c;对后台下单请求进行保护&#xff0c;防止刷单&#xff0c;即防…