Java使用itext5實(shí)現(xiàn)生成多個(gè)PDF并合并
PDF批量生成并合并為1個(gè)PDF
單個(gè)生成
/** * 根據(jù)id查詢數(shù)據(jù) * @param id 數(shù)據(jù)id * @return */ private Map<String, String> queryEntityDataById(String id) { //根據(jù)id查詢 Box entity = BoxService.getById(id); Map<String, String> data = new HashMap<String, String>(); //顯示內(nèi)容 //id data.put("id", entity.getJdKh()); //動(dòng)態(tài)生成當(dāng)前時(shí)間的yymmddhh格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHH"); String currentDate = LocalDateTime.now().format(formatter); data.put("date", currentDate); //二維碼內(nèi)容 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; } //根據(jù)數(shù)據(jù)生成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); //標(biāo)簽內(nèi)容 //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
/** * 根據(jù)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生成與合并完成,總耗時(shí): " + (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包位置的同級(jí)files文件,可以直接通過http://IP:port/files下的文件名訪問 spring.web.resources.static-locations=file:./files/
合并PDF并保存
/** * 生成合并的pdf文件保存到服務(wù)器下面 * application.properties下面需要配置spring.web.resources.static-locations=file:./files/ * jar包運(yùn)行的文件夾目錄 * @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) { //根據(jù)id查詢pdf所需要數(shù)據(jù) Map<String, String> data = queryEntityDataById(id.trim()); // 根據(jù)id生成pdf數(shù)據(jù)流 ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream(); generatePdfForData(data, pdfOutputStream); // 將生成的pdf數(shù)據(jù)流 PdfReader reader = new PdfReader(new ByteArrayInputStream(pdfOutputStream.toByteArray())); copy.addDocument(reader); reader.close(); } mergedDocument.close(); //保存文件路徑 String currentDateDir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); // 獲取運(yùn)行目錄下的 files 目錄路徑 String filePath = System.getProperty("user.dir") + File.separator + "files" + File.separator + currentDateDir; File directory = new File(filePath); // 檢查目錄是否存在,不存在則創(chuàng)建 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(); } }
出現(xiàn)問題PDF文件過大
解決辦法:
提取字體子集
到此這篇關(guān)于Java使用itext5實(shí)現(xiàn)生成多個(gè)PDF并合并的文章就介紹到這了,更多相關(guān)Java itext5生成PDF內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java無鎖hashmap原理與實(shí)現(xiàn)詳解
本文主要介紹了java無鎖hashmap原理與實(shí)現(xiàn),大家參考使用吧2014-01-01java簡單實(shí)現(xiàn)數(shù)組的增刪改查方法
這篇文章主要介紹了Java數(shù)組的增刪改查的示例,幫助大家更好的利用Java處理數(shù)據(jù),感興趣的朋友可以了解下,希望能給你帶來幫助2021-07-07JavaWeb如何實(shí)現(xiàn)統(tǒng)一查詢接口(jfinal)
這篇文章主要介紹了JavaWeb如何實(shí)現(xiàn)統(tǒng)一查詢接口(jfinal),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06Lombok @Slf4j log對(duì)象沒有info等方法不可用問題及解決
本文主要介紹了如何解決Spring Boot項(xiàng)目中的日志依賴沖突問題,以及如何使用Lombok和SLF4J進(jìn)行日志記錄,Lombok通過生成Logger對(duì)象簡化了日志記錄,而SLF4J提供了一個(gè)統(tǒng)一的日志接口,允許開發(fā)者在運(yùn)行時(shí)選擇不同的日志實(shí)現(xiàn)2024-12-12在Java 8中將List轉(zhuǎn)換為Map對(duì)象方法
這篇文章主要介紹了在Java 8中將List轉(zhuǎn)換為Map對(duì)象方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11Spring Boot+Jpa多數(shù)據(jù)源配置的完整步驟
這篇文章主要給大家介紹了關(guān)于Spring Boot+Jpa多數(shù)據(jù)源配置的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01將Java程序打包成EXE文件的實(shí)現(xiàn)方式
這篇文章主要介紹了將Java程序打包成EXE文件的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04