java生成pdf(利用dom4j、freemarker)

背景:跟着我的步骤一步一步,最后一定会成功!!

首先生成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有很多种方式,但是本文所选可以实现复杂的数据替换,复杂的模板使用!思路清晰,容易上手!是不是很简单!嘻嘻!

参考:https://www.jb51.net/article/160109.htm

发布了17 篇原创文章 · 获赞 2 · 访问量 2012

猜你喜欢

转载自blog.csdn.net/wumingdu1234/article/details/104418074