zhouc PDF拆分图片以及单页

This commit is contained in:
zhouc 2025-03-01 20:29:39 +08:00
parent c9aaa1c696
commit b5075b9413
5 changed files with 126 additions and 29 deletions

View File

@ -162,6 +162,17 @@
<version>3.25.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.wmyun</groupId>
<artifactId>wmyun-module-infra-api</artifactId>
<version>2.3.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>6.2.2</version>
</dependency>
</dependencies>

View File

@ -2,9 +2,10 @@ package com.wmyun.module.system.controller.admin.pdf;
import com.wmyun.module.system.controller.admin.pdf.vo.PdfResultVO;
import com.wmyun.module.system.service.pdf.PdfSplitService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource;
import lombok.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -31,44 +32,64 @@ public class PDFController {
@Resource
private PdfSplitService pdfSplitService;
private String uploadDir; // 配置文件设置存储路径
@PostMapping("/split_result")
@Operation(summary = "PDF拆分")
@PreAuthorize("@ss.hasPermission('system:pdf:split_result')")
public ResponseEntity<?> splitPdfresult(@RequestParam("file") MultipartFile file) {
try {
if (!file.getContentType().equals("application/pdf")) {
throw new IllegalArgumentException("仅支持 PDF 文件");
}
// 保存临时文件
File tempFile = File.createTempFile("split-", ".pdf");
File tempFile = File.createTempFile("split-", ".pdf");
file.transferTo(tempFile);
// 执行拆分
List<PdfResultVO> resultList = pdfSplitService.splitPdf(
tempFile,
uploadDir
);
List<PdfResultVO> resultList = pdfSplitService.splitPdf(tempFile, uploadDir);
tempFile.delete();
// 返回结果
return ResponseEntity.ok(resultList);
} catch (IOException e) {
return ResponseEntity.status(500)
.body(Map.of("error", "处理失败: " + e.getMessage()));
.body(Map.of("error", "处理失败: " + e.getMessage()));
}
}
@PostMapping("/split")
public ResponseEntity<String> splitPdf(
@RequestParam("file") MultipartFile file,
@RequestParam(defaultValue = "1") int startPage,
@RequestParam(defaultValue = "1") int endPage) {
@PostMapping("/split_image")
@Operation(summary = "PDF拆分图片")
@PreAuthorize("@ss.hasPermission('system:pdf:split_image')")
public ResponseEntity<?> PdfToImageConverter(@RequestParam("file") MultipartFile file) {
try {
File tempFile = File.createTempFile("temp", ".pdf");
if (!file.getContentType().equals("application/pdf")) {
throw new IllegalArgumentException("仅支持 PDF 文件");
}
// 保存临时文件
File tempFile = File.createTempFile("split-", ".pdf");
file.transferTo(tempFile);
String outputPath = "/output/";
pdfSplitService.splitPdfByPages(tempFile, outputPath, startPage, endPage);
return ResponseEntity.ok(" 拆分成功");
// 执行拆分
List<PdfResultVO> resultList = pdfSplitService.PdfToImageConverter(tempFile, uploadDir);
tempFile.delete();
// 返回结果
return ResponseEntity.ok(resultList);
} catch (IOException e) {
return ResponseEntity.status(500).body(" 处理失败: " + e.getMessage());
return ResponseEntity.status(500).body(Map.of("error", "处理失败: " + e.getMessage()));
}
}
// @PostMapping("/split")
// public ResponseEntity<String> splitPdf(
// @RequestParam("file") MultipartFile file,
// @RequestParam(defaultValue = "1") int startPage,
// @RequestParam(defaultValue = "1") int endPage) {
// try {
// File tempFile = File.createTempFile("temp", ".pdf");
// file.transferTo(tempFile);
// String outputPath = "/output/";
// pdfSplitService.splitPdfByPages(tempFile, outputPath, startPage, endPage);
// return ResponseEntity.ok(" 拆分成功");
// } catch (IOException e) {
// return ResponseEntity.status(500).body(" 处理失败: " + e.getMessage());
// }
// }
}

View File

@ -1,5 +1,6 @@
package com.wmyun.module.system.controller.admin.pdf.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -12,7 +13,10 @@ import lombok.Data;
@Data
@AllArgsConstructor
public class PdfResultVO {
@Schema(description = "拆分后文件名称", example = "page_1.pdf")
private String fileName; // 拆分后的文件名
@Schema(description = "服务武器存储路径")
private String filePath; // 服务器存储路径
@Schema(description = "文件大小(字节))", example = "315063")
private Long fileSize; // 文件大小字节
}

View File

@ -1,17 +1,33 @@
package com.wmyun.module.system.service.pdf;
import com.wmyun.module.system.controller.admin.pdf.vo.PdfResultVO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public interface PdfSplitService {
/**
* 拆分一个PDF文件为多个pdf每页一个
* @param sourceFile
* @param outputDir
* @return
* @throws IOException
*/
List<PdfResultVO> splitPdf(File sourceFile, String outputDir) throws IOException;
/**
* 拆分一个PDF文件为多个图片每页一个
* @param pdfFile
* @param outputDir
* @return
* @throws IOException
*/
List<PdfResultVO> PdfToImageConverter(File pdfFile, String outputDir) throws IOException;
void splitPdfByPages(File sourceFile, String outputDir, int startPage, int endPage) throws IOException;
void splitAllPages(File sourceFile, String outputDir) throws IOException;
MultipartFile convertToMultipartFile(String filePath) throws IOException;
}

View File

@ -1,13 +1,22 @@
package com.wmyun.module.system.service.pdf;
import cn.hutool.core.io.IoUtil;
import com.wmyun.module.infra.api.file.FileApi;
import com.wmyun.module.system.controller.admin.pdf.vo.PdfResultVO;
import jakarta.annotation.Resource;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
@ -18,26 +27,28 @@ import java.util.List;
*/
@Service
public class PdfSplitServiceImpl implements PdfSplitService{
public class PdfSplitServiceImpl implements PdfSplitService {
@Resource
private FileApi fileService;
public List<PdfResultVO> splitPdf(File sourceFile, String outputDir) throws IOException {
List<PdfResultVO> results = new ArrayList<>();
try (PDDocument document = PDDocument.load(sourceFile)) {
int totalPages = document.getNumberOfPages();
for (int i = 0; i < totalPages; i++) {
// 创建单页文档
PDDocument singlePageDoc = new PDDocument();
singlePageDoc.addPage(document.getPage(i));
// 生成文件名和路径
String fileName = "page_" + (i + 1) + ".pdf";
File outputFile = new File(outputDir, fileName);
singlePageDoc.save(outputFile);
MultipartFile multipartFile = convertToMultipartFile(outputFile.getAbsolutePath());
String filePath = fileService.createFile(fileName, null, IoUtil.readBytes(multipartFile.getInputStream()));
// 构建返回VO
results.add(new PdfResultVO(
fileName,
outputFile.getAbsolutePath(),
filePath,
outputFile.length()
));
singlePageDoc.close();
@ -46,6 +57,17 @@ public class PdfSplitServiceImpl implements PdfSplitService{
return results;
}
public MultipartFile convertToMultipartFile(String filePath) throws IOException {
File file = new File(filePath);
FileInputStream input = new FileInputStream(file);
return new MockMultipartFile(
"file", // 表单字段名
file.getName(), // 原始文件名
Files.probeContentType(file.toPath()), // MIME类型需根据实际文件类型修改
input // 文件流
);
}
public void splitPdfByPages(File sourceFile, String outputDir, int startPage, int endPage) throws IOException {
try (PDDocument document = PDDocument.load(sourceFile)) {
int totalPages = document.getNumberOfPages();
@ -77,4 +99,27 @@ public class PdfSplitServiceImpl implements PdfSplitService{
}
}
}
// PDF转多张图片每页一张
public List<PdfResultVO> PdfToImageConverter(File pdfFile, String outputDir) throws IOException {
List<PdfResultVO> results = new ArrayList<>();
try (PDDocument document = PDDocument.load(pdfFile)) {
PDFRenderer renderer = new PDFRenderer(document);
for (int i = 0; i < document.getNumberOfPages(); i++) {
BufferedImage image = renderer.renderImageWithDPI(i, 300); // 300 DPI
String imageName = "page_" + (i + 1) + ".png";
File outputImage = new File(outputDir, imageName);
ImageIO.write(image, "PNG", outputImage);
// imagePaths.add(outputImage.getAbsolutePath());
MultipartFile multipartFile = convertToMultipartFile(outputImage.getAbsolutePath());
String filePath = fileService.createFile(imageName, null, IoUtil.readBytes(multipartFile.getInputStream()));
// 构建返回VO
results.add(new PdfResultVO(
imageName,
filePath,
outputImage.length()
));
}
}
return results;
}
}