背景:跟着我的步驟一步一步,最後一定會成功!!
首先生成pdf有很多種方式:
- iText,生成PDF文檔,還支持將XML、Html文件轉化爲PDF文件;
- Apache PDFBox,生成、合併PDF文檔;
- docx4j,生成docx、pptx、xlsx文檔,支持轉換爲PDF格式。
比較:
- iText開源協議爲AGPL,而其他兩個框架協議均爲Apache License v2.0。需要用畫筆去花模板,很繁瑣!
- Apache PDFBox,生成、合併PDF文檔;
- docx4j,生成docx、pptx、xlsx文檔,支持轉換爲PDF格式。
本文使用最後一種,思路如下圖:
步驟
1.首先將你要生成的pdf,用worl畫出來,比如你需要特定結構的pdf,你沒辦法做到,但是一個wold你可以通過編輯,得到你想要的模板 。如下:(你想要替換的內容換成${arg0!""},就是用將來你需要替換的數據暫時用變量表示出來,後續只要替換變量的值即可!而模板本身不變)
2.其次將word的字體換成宋體(通用),文件另存爲xml格式文件如下:
3.將文件改名,以.ftl形式結尾(利用freemarker,所以改成freemarker文件形式)
4.讀取ftl文件,將其轉化成xml字符串。讀取xml字符串,將其轉換成word,讀取word,利用dom4j將其轉換成你想要的模式的pdf
@SuppressWarnings({ "unchecked", "rawtypes" })
private Map createPdf(List<Loan> loanList) {
Map fileMap = new HashMap();
for (Loan loan : loanList) {
// 創建數據
String bankParentName = "";
// List<SysOrg> orgByOrgId = service.getOrgByOrgId(loan.getBankId());
// if (orgByOrgId!=null && orgByOrgId.size()>0) {
// String orgPathname = orgByOrgId.get(0).getOrgPathname();
// if (orgPathname.indexOf("/", 1)==-1) {
// bankParentName = orgPathname.substring(1);
// }else {
// bankParentName = orgPathname.substring(1,orgPathname.indexOf("/", 1));
// }
// }
// 銀行名稱
String bankName = loan.getBankName();
// 企業名稱
String enterpriseName = loan.getEnterpriseName();
// 貸款編號
// String loanNumber = loan.getLoanNumber();
String loanNumber = loan.getUpdator();
// 會議方案期數
Long meetingPlanNper = loan.getMeetingPlanNper();
// 會議方案金額
BigDecimal meetingPlanAmount = loan.getMeetingPlanAmount().multiply(new BigDecimal(10000));
//融資平臺企業類別
String businessCategory = loan.getBusinessCategory();
//信用貸款
BigDecimal credit;
//索賠金額
BigDecimal claimAmount;
if ("第一類".equals(businessCategory)) {
credit = new BigDecimal(0);
claimAmount =new BigDecimal(0);
}else if ("第二類".equals(businessCategory)) {
credit = meetingPlanAmount.multiply(new BigDecimal(0.6667));
claimAmount = meetingPlanAmount.multiply(new BigDecimal(0.3333));
}else if ("第三類".equals(businessCategory)) {
credit = meetingPlanAmount.multiply(new BigDecimal(0.95));
claimAmount = meetingPlanAmount.multiply(new BigDecimal(0.005));
}else {
credit = new BigDecimal(0);
claimAmount =new BigDecimal(0);
}
Map dataMap = new HashMap();
dataMap.put("arg0", bankParentName);
dataMap.put("arg1", bankName);
dataMap.put("arg2", enterpriseName);
dataMap.put("arg3", loanNumber);
dataMap.put("arg4", ConvertNumberToUpper.toChinese(meetingPlanNper+""));
dataMap.put("arg5", ConvertNumberToUpper.digitUppercase(meetingPlanAmount.doubleValue()));
if (credit.intValue()==0) {
dataMap.put("arg6", "___________");
}else {
dataMap.put("arg6", ConvertNumberToUpper.digitUppercase(credit.doubleValue()));
}
if (claimAmount.intValue()==0) {
dataMap.put("arg7", "___________");
}else {
dataMap.put("arg7", ConvertNumberToUpper.digitUppercase(claimAmount.doubleValue()));
}
// Map dataMap = new HashMap();
// dataMap.put("bankName", loan.getBankName());
// dataMap.put("loanNumber", loan.getLoanNumber());
// dataMap.put("enterpriseName", loan.getEnterpriseName());
// dataMap.put("applicationSituationAmount", ConvertNumberToUpper.digitUppercase(loan.getApplicationSituationAmount()*10000));
// dataMap.put("meetingPlanAmount", ConvertNumberToUpper.digitUppercase(loan.getMeetingPlanAmount()*10000));
// dataMap.put("meetingPlanNper", ConvertNumberToUpper.toChinese(loan.getMeetingPlanNper()+""));
// 獲取模板
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
configuration.setClassForTemplateLoading(this.getClass(), "/template/chj");
String name = "temp" + UUID.randomUUID() + ".doc";
File file = new File(name);
try {
Template template = configuration.getTemplate("testwold.ftl");
template.setEncoding("UTF-8");
/*Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(name), "UTF-8"));
template.process(dataMap, out);
out.close();*/
/**
* 這段是我爲了測試pdf功能而增加上的-start
*/
//將數據和ftl文件組裝爲xml文本
StringWriter stringWriter = new StringWriter();
BufferedWriter writer = new BufferedWriter(stringWriter);
template.process(dataMap, writer);
String xmlStr = stringWriter.toString();
System.out.println("xmlStr:"+xmlStr);
writer.close();
//使用docx4j將xml文本加載爲word文檔對象
ByteArrayInputStream in = new ByteArrayInputStream(xmlStr.getBytes("utf-8"));
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(in);
Mapper nzt = wordMLPackage.getFontMapper();
Map<String, PhysicalFont> fontMappingssss = nzt.getFontMappings();
//使用docx4j將word文檔轉存爲pdf文檔
String outputfilepath = "D:\\late\\qyh\\caohejing\\finally\\test.pdf";
FileOutputStream os = new FileOutputStream(new File(outputfilepath));
FOSettings foSettings = Docx4J.createFOSettings();
Mapper fontMapper = new IdentityPlusMapper();
Map<String, PhysicalFont> physicalFonts = PhysicalFonts.getPhysicalFonts();
Set<String> keySet = physicalFonts.keySet();
//中文字體轉換
fontMapper.getFontMappings().put("Calibri", physicalFonts.get("Calibri"));
fontMapper.getFontMappings().put("華文行楷", physicalFonts.get("STXingkai"));
fontMapper.getFontMappings().put("隸書", physicalFonts.get("LiSu"));
fontMapper.getFontMappings().put("宋體",physicalFonts.get("SimSun"));
fontMapper.getFontMappings().put("微軟雅黑",physicalFonts.get("Microsoft Yahei"));
fontMapper.getFontMappings().put("黑體",physicalFonts.get("SimHei"));
fontMapper.getFontMappings().put("楷體",physicalFonts.get("KaiTi"));
fontMapper.getFontMappings().put("新宋體",physicalFonts.get("NSimSun"));
fontMapper.getFontMappings().put("華文行楷", physicalFonts.get("STXingkai"));
fontMapper.getFontMappings().put("華文仿宋", physicalFonts.get("STFangsong"));
fontMapper.getFontMappings().put("宋體擴展",physicalFonts.get("simsun-extB"));
fontMapper.getFontMappings().put("仿宋",physicalFonts.get("FangSong"));
fontMapper.getFontMappings().put("仿宋_GB2312",physicalFonts.get("FangSong_GB2312"));
fontMapper.getFontMappings().put("幼圓",physicalFonts.get("YouYuan"));
fontMapper.getFontMappings().put("華文宋體",physicalFonts.get("STSong"));
fontMapper.getFontMappings().put("華文中宋",physicalFonts.get("STZhongsong"));
try {
wordMLPackage.setFontMapper(fontMapper);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
foSettings.setWmlPackage(wordMLPackage);
Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
// Docx4J.toPDF(wordMLPackage, new FileOutputStream(new File(outputfilepath)));
//Word轉PDF
/*WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(new File("abc.docx"));
Mapper fontMapper = new IdentityPlusMapper();
// fontMapper.put("華文行楷", PhysicalFonts.get("STXingkai"));
mlPackage.setFontMapper(fontMapper);
OutputStream os = new java.io.FileOutputStream("abc.pdf");
FOSettings foSettings = Docx4J.createFOSettings();
foSettings.setWmlPackage(mlPackage);
Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL); */
/**
* 這段是我爲了測試pdf功能而增加上的-end
*/
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} catch (Docx4JException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//fileMap.put(loan.getEnterpriseName()+"_投放通知書_告知書.doc", file);
}
return fileMap;
}
5.項目所用jar包:
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-export-fo</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.18</version>
</dependency>
6.結果展示:
總結:生成pdf有很多種方式,但是本文所選可以實現複雜的數據替換,複雜的模板使用!思路清晰,容易上手!是不是很簡單!嘻嘻!