itext5生成多个PDF并合并
PDF批量生成并合并为1个PDF
单个生成
/**
* 根据id查询数据
* @param id 数据id
* @return
*/
private Map<String, String> queryEntityDataById(String id) {
//根据id查询
Box entity = BoxService.getById(id);
Map<String, String> data = new HashMap<String, String>();
//显示内容
//id
data.put("id", entity.getJdKh());
//动态生成当前时间的yymmddhh格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHH");
String currentDate = LocalDateTime.now().format(formatter);
data.put("date", currentDate);
//二维码内容
data.put("imsi", entity.getImsi());
data.put("imei", entity.getImei());
String type = entity.getType();
if (type == null || type.isEmpty()) {
type = "A";
}
data.put("type", type);
return data;
}
//根据数据生成PDF
private void generatePdfForData(Map<String, String> data, ByteArrayOutputStream outputStream) throws Exception {
// Load the PDF template
InputStream templateStream = getClass().getResourceAsStream("/template/ddentitytemplate.pdf");
PdfReader reader = new PdfReader(templateStream);
PdfStamper stamper = new PdfStamper(reader, outputStream);
AcroFields form = stamper.getAcroFields();
String fontPath = File.separator + "font" + File.separator + "micosoftyh.ttf";
BaseFont bfChinese = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Map<String, AcroFields.Item> fields = form.getFields();
for (String k : fields.keySet()) {
form.setFieldProperty(k, "textfont", bfChinese, null);
form.setFieldProperty(k, "textsize", Float.valueOf("55"), null);
form.setFieldProperty(k, "textstyle", com.itextpdf.text.Font.BOLD, null);
form.setFieldProperty(k, "textalign", Element.ALIGN_MIDDLE, null);
}
//特殊文本框字体大小重置
form.setFieldProperty("$serialnumber$", "textsize", Float.valueOf("40"), null);
//标签内容
//ID
form.setField("$id$", data.get("id"));
//日期
form.setField("$date$", data.get("date"));
//二维码
String qrContent = String.format(
"ID:%s\n" +
"IMSI:%s\n" +
"IMEI:%s\n" +
"type:%s",
data.get("id"), data.get("imsi"), data.get("imei"),data.get("type"));
PdfContentByte cb = stamper.getOverContent(1);
generateQRcode(qrContent, cb);
stamper.setFormFlattening(true);
stamper.close();
reader.close();
}
返回PDF
/**
* 根据ID批量生成pdf并合并
* @param ids ids集合
* @return 可直接访问的pdf流文件
*/
@GetMapping("/generateMergePdfStream")
public ResponseEntity<ByteArrayResource> generateMergePdfStream(@RequestParam String ids) {
long startTime = System.currentTimeMillis();
System.out.println("开始生成PDF: " + startTime);
try {
String[] idArray = ids.split(",");
ByteArrayOutputStream mergedOutputStream = new ByteArrayOutputStream();
Document mergedDocument = new Document();
PdfSmartCopy copy = new PdfSmartCopy(mergedDocument, mergedOutputStream);
mergedDocument.open();
for (String id : idArray) {
Map<String, String> data = queryEntityDataById(id.trim());
ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
generatePdfForData(data, pdfOutputStream);
System.out.println("生成的PDF文件大小: " + pdfOutputStream.size());
PdfReader reader = new PdfReader(new ByteArrayInputStream(pdfOutputStream.toByteArray()));
copy.addDocument(reader);
reader.close();
pdfOutputStream.close();
}
mergedDocument.close();
ByteArrayResource resource = new ByteArrayResource(mergedOutputStream.toByteArray());
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "inline; filename=merged.pdf");
long generationEnd = System.currentTimeMillis();
System.out.println("PDF生成与合并完成,总耗时: " + (generationEnd - startTime) + " 毫秒");
return ResponseEntity.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_PDF)
.body(resource);
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(500).build();
}
}
文件保存在本地通过http接口访问pdf文件
application.properties
#访问jar包位置的同级files文件,可以直接通过http://IP:port/files下的文件名访问
spring.web.resources.static-locations=file:./files/
合并PDF并保存
/**
* 生成合并的pdf文件保存到服务器下面
* application.properties下面需要配置spring.web.resources.static-locations=file:./files/
* jar包运行的文件夹目录
* @param ids ids集合
* @return 可直接访问的http://IP:Port/*.pdf
*/
@GetMapping("/generateentityLogPdf")
public ResponseEntity generateMergeSavePdf(@RequestParam String ids, HttpServletRequest request) {
try {
// 分割ids
String[] idArray = ids.split(",");
// 输出流
ByteArrayOutputStream mergedOutputStream = new ByteArrayOutputStream();
Document mergedDocument = new Document();
PdfCopy copy = new PdfCopy(mergedDocument, mergedOutputStream);
mergedDocument.open();
for (String id : idArray) {
//根据id查询pdf所需要数据
Map<String, String> data = queryEntityDataById(id.trim());
// 根据id生成pdf数据流
ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
generatePdfForData(data, pdfOutputStream);
// 将生成的pdf数据流
PdfReader reader = new PdfReader(new ByteArrayInputStream(pdfOutputStream.toByteArray()));
copy.addDocument(reader);
reader.close();
}
mergedDocument.close();
//保存文件路径
String currentDateDir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
// 获取运行目录下的 files 目录路径
String filePath = System.getProperty("user.dir") + File.separator + "files" + File.separator + currentDateDir;
File directory = new File(filePath);
// 检查目录是否存在,不存在则创建
if (!directory.exists()) {
directory.mkdirs();
}
// 保存文件名
Random random = new Random();
int randomNumber = random.nextInt(1000);
String fileName = System.currentTimeMillis() + "_" + randomNumber + ".pdf";
File file = new File(directory, fileName);
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(mergedOutputStream.toByteArray());
fos.flush();
System.out.println("文件保存成功:" + file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
//返回直接访问pdf的url
String ip = request.getServerName();
int port = request.getServerPort();
String fileUrl = "http://" + ip + ":" + port + "/" + currentDateDir + "/" + fileName;
return ResponseEntity.ok(fileUrl);
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(500).build();
}
}
出现问题PDF文件过大
解决办法:
提取字体子集
如果这篇文章对你有用,可以关注本人微信公众号获取更多ヽ(^ω^)ノ ~
