目录
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的,长度就是原图片的长度了