Java使用itext5實(shí)現(xiàn)生成多個PDF并合并
PDF批量生成并合并為1個PDF
單個生成
/** * 根據(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()); //動態(tài)生成當(dāng)前時間的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生成與合并完成,總耗時: " + (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文件保存到服務(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)生成多個PDF并合并的文章就介紹到這了,更多相關(guān)Java itext5生成PDF內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring工廠方法創(chuàng)建(實(shí)例化)bean實(shí)例代碼
這篇文章主要介紹了Spring工廠方法創(chuàng)建bean實(shí)例代碼,具有一定借鑒價值,需要的朋友可以參考下2018-01-01JVM內(nèi)存模型/內(nèi)存空間:運(yùn)行時數(shù)據(jù)區(qū)
這篇文章主要介紹了JVM內(nèi)存模型/內(nèi)存空間的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java虛擬機(jī),感興趣的朋友可以了解詳細(xì),希望能夠給你帶來幫助2021-08-08java實(shí)現(xiàn)哈弗曼編碼與反編碼實(shí)例分享(哈弗曼算法)
本文介紹java實(shí)現(xiàn)哈弗曼編碼與反編碼實(shí)例,大家參考使用吧2014-01-01Java實(shí)現(xiàn)兩個日期相減等于天數(shù)
這篇文章主要介紹了Java兩個日期相減等于天數(shù)的實(shí)現(xiàn)方式,本文通過兩種方式結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09SpringBoot+mybatis+thymeleaf實(shí)現(xiàn)登錄功能示例
這篇文章主要介紹了SpringBoot+mybatis+thymeleaf實(shí)現(xiàn)登錄功能示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07Java中數(shù)據(jù)轉(zhuǎn)換及字符串的“+”操作方法
本文主要介紹了Java中的數(shù)據(jù)類型轉(zhuǎn)換,包括隱式轉(zhuǎn)換和強(qiáng)制轉(zhuǎn)換,隱式轉(zhuǎn)換通常用于將范圍較小的數(shù)據(jù)類型轉(zhuǎn)換為范圍較大的數(shù)據(jù)類型,而強(qiáng)制轉(zhuǎn)換則是將范圍較大的數(shù)據(jù)類型轉(zhuǎn)換為范圍較小的數(shù)據(jù)類型,本文介紹Java中數(shù)據(jù)轉(zhuǎn)換以及字符串的“+”操作,感興趣的朋友一起看看吧2024-10-10