最近在做一个小项目,项目中有一个功能要把pdf格式的图片转换为其它格式,接下来看看用pdfbox来如何实现吧。
首先导入pdfbox相关依赖:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>jempbox</artifactId>
<version>1.8.11</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>xmpbox</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>preflight</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>2.0.0</version>
</dependency>
接下来,控制层里面写一个方法接收三个参数(其中三个参数分别表示上传的文件,要转换的格式,输出路径):
@ApiOperation("将pdf格式的图片装换为其它格式")
@PostMapping("/pdfToimages")
public R pdfToimages(@RequestPart("file") MultipartFile file
, @RequestParam("type") String type,@RequestParam(value = "outpath",defaultValue = "C:\\PictureTool",required = false) String outpath){
return imagetoolService.convertToImages(file,type,outpath);
}
然后是serviceimpl实现层实现对应方法(service接口此处就不做展示了,直接将serviceimpl里面的对应的方法设置为接口就行了):
/**
* pdf转多张jpg(转换成多张图片)
*
* @param file
* @return
*/
@Override
public R convertToImages(MultipartFile file, String type, String outputPath) {
if (file == null || file.isEmpty() || outputPath == null || outputPath.trim().isEmpty()) {
// 对传入参数进行基本校验,确保它们不为空
return R.Failed("请确保文件不为空且输出路径不为空。");
}
// 获取文件名
String filename = file.getOriginalFilename();
int lastIndexOfDot = filename.lastIndexOf(".");
if (lastIndexOfDot != -1) {
filename = filename.substring(0, lastIndexOfDot);
}
System.out.println("文件名称为:" + filename);
// 确保路径以分隔符结尾
if (!outputPath.endsWith(File.separator)) {
outputPath += File.separator;
}
try {
// 加载PDF文件
PDDocument document = PDDocument.load(file.getBytes());
// 创建PDF渲染器
PDFRenderer pdfRenderer = new PDFRenderer(document);
// 使用ByteArrayOutputStream来构建ZIP文件的内容
ByteArrayOutputStream baosZip = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(baosZip);
// 遍历PDF中的每一页,并将其添加到ZIP流中
for (int page = 0; page < document.getNumberOfPages(); page++) {
// 使用300 DPI渲染图片
BufferedImage image = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
// 创建输出流缓存图像数据
ByteArrayOutputStream baosImage = new ByteArrayOutputStream();
// 保存图片到缓存流
ImageIO.write(image, type, baosImage);
// 将图像字节添加到ZIP文件中
zipOut.putNextEntry(new ZipEntry(file.getOriginalFilename() + "_page_" + (page + 1) + "." + type));
zipOut.write(baosImage.toByteArray());
zipOut.closeEntry();
}
// 完成ZIP输出流写入操作并关闭之
IOUtils.closeQuietly(zipOut);
// 关闭PDF文档
IOUtils.closeQuietly(document);
// 创建用户指定的文件,用于保存ZIP
String zipFilename = filename + "_converted_images_" + type + ".zip";
File outputFile = new File(outputPath + zipFilename);
FileUtils.writeByteArrayToFile(outputFile, baosZip.toByteArray());
// 返回成功的状态响应
return R.Success("转换成功,保存路径为:" + outputFile.getAbsolutePath(), 200);
} catch (IOException e) {
// 发生异常时打印堆栈跟踪并返回错误信息
e.printStackTrace();
return R.Failed(500, "转换失败:" + e.getMessage());
}
}
此处的R是我自己做的一个返回响应类,读者可以根据自己项目的实际情况设置自己的响应类,或者后台私信我获取,代码中均做有注释,若有疑问之处请留言~
项目成功运行之后会根据指定文件名的生成规则生成一个压缩包到指定的文件中,若没有指定文件则会用默认的文件生成路径。
接下来使用postman进行运行:
运行成功后,便可以在对应文件夹下面查看对应生成成功的文件:
后面直接将文件解压缩即可~