Java使用itext5实现生成多个PDF并合并
目录
- PDF批量生成并合并为1个PDF
- 单个生成
- 返回PDF
- 文件保存在本地通过http接口访问pdf文件
- application.properties
- 合并PDF并保存
- 出现问题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 android 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 Stringjs[] 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数据流 dnWXCszY 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文件过大
解决办法:
提取字体子集
到此这篇关于Java使用itext5实现生成多个PDF并合并的文章就介绍到这了,更多相关Java itext5生成PDF内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论