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)文章
Spring工廠方法創(chuàng)建(實(shí)例化)bean實(shí)例代碼
這篇文章主要介紹了Spring工廠方法創(chuàng)建bean實(shí)例代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01
JVM內(nèi)存模型/內(nèi)存空間:運(yùn)行時(shí)數(shù)據(jù)區(qū)
這篇文章主要介紹了JVM內(nèi)存模型/內(nèi)存空間的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java虛擬機(jī),感興趣的朋友可以了解詳細(xì),希望能夠給你帶來(lái)幫助2021-08-08
java實(shí)現(xiàn)哈弗曼編碼與反編碼實(shí)例分享(哈弗曼算法)
本文介紹java實(shí)現(xiàn)哈弗曼編碼與反編碼實(shí)例,大家參考使用吧2014-01-01
Java實(shí)現(xiàn)兩個(gè)日期相減等于天數(shù)
這篇文章主要介紹了Java兩個(gè)日期相減等于天數(shù)的實(shí)現(xiàn)方式,本文通過兩種方式結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09
Java 基于AQS實(shí)現(xiàn)一個(gè)同步器
這篇文章主要介紹了如何基于AQS實(shí)現(xiàn)一個(gè)同步器,幫助大家更好的理解和學(xué)習(xí)Java并發(fā),感興趣的朋友可以了解下2020-09-09
SpringBoot+mybatis+thymeleaf實(shí)現(xiàn)登錄功能示例
這篇文章主要介紹了SpringBoot+mybatis+thymeleaf實(shí)現(xiàn)登錄功能示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
Java中數(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

