POI + freemaker 制作复杂word

Apache POI

The Apache POI Project's mission is to create and maintain Java APIs for manipulating various file formats based upon the Office Open XML standards (OOXML) and Microsoft's OLE 2 Compound Document format (OLE2).

POI是一个基于xml标准的JAVA 框架,相信很多人会用来处理office。这篇文章的主旨不是介绍POI,而是讲一下复杂的word。

首先,poi的介绍网上很多,包括demo代码。大部分都是采用渲染range的方式,填充word body。这种方式很直观,也只要做简单的replace就能做出demo,但是真实业务中基本不会那么简单。

			FileInputStream fis = new FileInputStream(new File(templateFile));
			HWPFDocument doc = new HWPFDocument(fis);
			Range bodyRange = doc.getRange();
			Field[] fields = obj.getClass().getDeclaredFields();
			for (Field field : fields) {
				PropertyDescriptor proDescriptor = new PropertyDescriptor(field.getName(), obj.getClass());

				if (proDescriptor != null) {
					Method readMethod = proDescriptor.getReadMethod();
					bodyRange.replaceText("${" + field.getName() + "}", readMethod.invoke(obj) == null ? "" : readMethod.invoke(obj).toString());
					}
			}
			
			return doc;

上面是最简单的replaceText方式。查看 Range API可以发现有各种replace的方式。

Merge Word 这里有简单的text合并,stack overflow上也有些提问,都是实现了简单的字体,text合并。如果你的需求只是这么简单,那么够了。

下面来介绍一种 poi + freemarker 方式来制作复杂的word。

	public static void converWord(String templateFile, String targetFile, List<?> objs){
		Configuration configuration = new Configuration();
		configuration.setDefaultEncoding("utf-8");
		Map<String, List<?>> dataMap = new HashMap<String, List<?>>();
		dataMap.put("data", objs);
		Template tmpl = null;
		try {
			configuration.setDirectoryForTemplateLoading(new File(templateFile));
			tmpl = configuration.getTemplate("template.ftl");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		File outFile = new File(targetFile);
		Writer out = null;
		try {
			out = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(outFile), "UTF-8"));
			tmpl.process(dataMap, out);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				out.flush();
				out.close();
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}

看上面代码可以发现,首先需要一个 template.ftl 的xml文件,然后采用el表达式来替换xml中的 ${xxx} 参数。xml文件可以采用word自带的导出word xml方式获得。

相比于range方式,这里提供了xml,但是xml的维护时同同时带出的一个问题。

word的xml都是 <w:**> 的标签,比如<w:sectPr>等等。

这时再联系poi本身,不难发现,如果我们撇开range这种烂播的方式(各种无脑复制、粘贴占据搜索榜),我们也采用word本身的标签来处理,其实跟第二种的本质是一样的,但是我们需要些很多java代码。freemarker只是提供了一种xml的配置而已。

POI API


/*20140930*/

添加转义:转义 转义2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值