java进行PDF和图片之间的相互转换
简介
在项目中我们有时候会遇到操作PDF文件的需求,如将PDF的每一页转换成图片,今天我们就来实现一下相关功能。
实现
引入依赖
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.21</version>
</dependency>
pdfbox是一个开源的操作PDF的工具包,这里是 官方文档
将PDF转换成多张图片
程序中使用的源PDF下载 阿里巴巴Java开发...1528284352.pdf
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
public class Client {
public static void main(String[] args) throws Exception {
testPdf2images();
}
private static void testPdf2images() throws Exception {
List<byte[]> images = pdf2images(new File("D:/testpdf/阿里巴巴Java开发...1528284352.pdf"));
AtomicInteger fileNameIndex = new AtomicInteger(1);
for (byte[] image : images) {
new ByteArrayInputStream(image).transferTo(
new FileOutputStream("D:/testpdf/" + fileNameIndex.getAndIncrement() + ".png"));
}
}
/**
* 将PDF文件转换成多张图片
*
* @param pdfFile PDF源文件
* @return 图片字节数组列表
*/
private static List<byte[]> pdf2images(File pdfFile) throws Exception {
//加载PDF
PDDocument pdDocument = PDDocument.load(pdfFile);
//创建PDF渲染器
PDFRenderer renderer = new PDFRenderer(pdDocument);
int pages = pdDocument.getNumberOfPages();
List<byte[]> images = new ArrayList<>();
for (int i = 0; i < pages; i++) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
//将PDF的每一页渲染成一张图片
BufferedImage image = renderer.renderImage(i);
ImageIO.write(image, "png", output);
images.add(output.toByteArray());
}
pdDocument.close();
return images;
}
}
创建的图片列表如下
将图片列表转换成PDF
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Objects;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
public class Client2 {
public static void main(String[] args) throws Exception {
testImages2pdf();
}
private static void testImages2pdf() throws Exception {
File file = new File("D:/testpdf");
//过滤所有图片文件
File[] files = file.listFiles((f, s) -> s.endsWith(".png"));
if (Objects.nonNull(files)) {
//根据名称排序
Arrays.sort(files, Client2::compareImageFile);
byte[] pdf = images2pdf(files);
new ByteArrayInputStream(pdf).transferTo(
new FileOutputStream("D:/testpdf/阿里巴巴java文档.pdf"));
}
}
/**
* 根据图片名称排序
*/
private static int compareImageFile(File f1, File f2) {
String f1Name = f1.getName();
String f2Name = f2.getName();
return Integer.compare(Integer.parseInt(f1Name.substring(0, f1Name.lastIndexOf("."))),
Integer.parseInt(f2Name.substring(0, f2Name.lastIndexOf("."))));
}
/**
* 根据多张图片生成PDF文件
*
* @param images 图片列表
* @return PDF文件
*/
private static byte[] images2pdf(File... images) throws Exception {
//创建空PDF
PDDocument document = new PDDocument();
for (File image : images) {
InputStream input = new FileInputStream(image);
//读取图片
BufferedImage bufferedImage = ImageIO.read(input);
float width = bufferedImage.getWidth();
float height = bufferedImage.getHeight();
//创建PDF的一页
PDPage page = new PDPage(new PDRectangle(width, height));
document.addPage(page);
PDImageXObject pdImageXObject = PDImageXObject.createFromFileByContent(image, document);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
//写入图片
contentStream.drawImage(pdImageXObject, 0, 0);
contentStream.close();
input.close();
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
document.save(output);
document.close();
return output.toByteArray();
}
}
总结
遇到问题多google
参考
Java PDF转图片
Java: Create PDF pages from images using PDFBox library
在线处理PDF工具