在使用itextpdf 工具进行文件合并的时候,发现就是简单的把两个或者多个PDF拼接成一个文档,这样的方式会合并的文件会存在很多的空白区域,有没有什么办法把这个空白区域去除,让下一个文件内容继续当前的页面往下开始填充数据;
你这种想法在逻辑上就存在漏洞,下一页的如果是整页图,要截一半放上去,整个文档不乱套了吗,
https://www.jianshu.com/p/f48db63dcfea
pdf本来就是当做图片处理的,你这个要求已经设计图片内容了不行的
1、引入POM
<dependencies>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
</dependencies>
2、编写工具类
public class PdfUtils {
/**
* 创建pdf文档
*
* @param response
* @param fileName
* @return
*/
public static Document createDocument(HttpServletResponse response, String fileName) {
try {
response.reset();
response.setHeader("Content-Type", "application/pdf-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
} catch (Exception e) {
e.printStackTrace();
}
// 设置大小
return new Document(PageSize.A4, 50, 50, 80, 50);
}
/**
* 合并pdf
*
* @param response
* @param document
* @param byteList
*/
public static void mergePdf(HttpServletResponse response, Document document, List<byte[]> byteList) {
try {
OutputStream os = response.getOutputStream();
// 以任意一个页面创建pdf模板
document = new Document(new PdfReader(byteList.get(0)).getPageSize(1));
PdfCopy copy = new PdfCopy(document, os);
// 打开文档
document.open();
// 遍历pdf文件
for (byte[] bytes : byteList) {
// 读取pdf
PdfReader reader = new PdfReader(bytes);
// 获取页数
int numberOfPages = reader.getNumberOfPages();
// 从第一页开始
for (int i = 1; i <= numberOfPages; i++) {
// 新建文档页
document.newPage();
// 复制操作
PdfImportedPage page = copy.getImportedPage(reader, i);
copy.addPage(page);
}
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("PDF合并失败!");
} finally {
if (document != null) {
document.close();
}
}
}
}
3、代码实现
支持上传MultipartFile文件或者通过本地文件的Path的进行合并PDF
@RestController
@RequestMapping("/test")
public class PdfController {
/**
* 上传文件进行合并
*
* @param files
* @param response
*/
@PostMapping("pdfStream")
public void pdf(@RequestParam("files") MultipartFile[] files, HttpServletResponse response) {
try {
// 判断文件是否合规、以及转化为输入流
List<byte[]> byteList = new ArrayList<>();
for (MultipartFile file : files) {
// 限制格式只能为pdf
if (file == null) {
throw new RuntimeException("文件不能为空!");
}
String originalFilename = file.getOriginalFilename();
String substring = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
if (!substring.equals("pdf")) {
throw new RuntimeException("只能上传pdf格式文件!");
}
// 获取输入流
// 获取输入流
InputStream inputStream = file.getInputStream();
byte[] bytes = inputStreamToByte(inputStream);
byteList.add(bytes);
}
// 1.设置输出流名称
String fileName = "合并文件.pdf";
Document document = PdfUtils.createDocument(response, fileName);
// 2.开启合并
PdfUtils.mergePdf(response, document, byteList);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
/**
* 本地文件转换合并
*
* @param response
*/
@GetMapping("pdfPath")
public void pdfPath(HttpServletResponse response) {
try {
// 加载本地文件
List<String> paths = new ArrayList<>();
paths.add("C:\\Users\\LiGezZ\\Desktop\\1.pdf");
paths.add("C:\\Users\\LiGezZ\\Desktop\\2.pdf");
// 判断文件是否合规、以及转化为输入流
List<byte[]> byteList = new ArrayList<>();
for (String path : paths) {
File file = new File(path);
// 限制格式只能为pdf
if (!file.exists()) {
throw new RuntimeException("文件不存在!");
}
if (file.length() <= 0) {
throw new RuntimeException("文件不能为空!");
}
String name = file.getName();
String substring = name.substring(name.lastIndexOf(".") + 1);
if (!substring.equals("pdf")) {
throw new RuntimeException("只能上传pdf格式文件!");
}
// 获取输入流
FileInputStream inputStream = new FileInputStream(file);
byte[] bytes = inputStreamToByte(inputStream);
byteList.add(bytes);
}
// 1.设置输出流名称
String fileName = "合并文件.pdf";
Document document = PdfUtils.createDocument(response, fileName);
// 2.开启合并
PdfUtils.mergePdf(response, document, byteList);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
private byte[] inputStreamToByte(InputStream inputStream) {
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) {
os.write(bytes, 0, len);
}
os.flush();
return os.toByteArray();
} catch (Exception e) {
throw new RuntimeException("InputStream转换失败!");
}
}
}