java通过freemarket生成word文档

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java通过freemarket生成word文档相关的知识,希望对你有一定的参考价值。

1、使用freemarker的原因是:由于POI和ITEXT在处理复杂word文档格式时欠缺,尤其在生成WORD文档时,(其他处理word的工具需要动态加载windows动态链接库,有些还要收费),并且需求要在WORD指定位置插入图片,所以在参考了POI和ITEXT官网处理WORD和网络上其他处理WORD的工具后,发现freemarker可以通过设定WORD模板,经过处理生成ftl文件后,可直接通过freemarker的工具jar包可以生成指定位置的WORD文件。(不过用模板生成有个别缺点,一是:插入WORD中的图片大小会按照模板中的图片大小自动进行放大或缩小,所以建议最好按照事先规定的格式来上传固定图片尺寸;二是:最终生成的WORD文档有时会出现提示文档错误,用wps制定的docx模板生成没问题,但是office的doc文档有问题,这个问题暂时还未解决,直接点是即可。提示:模板后缀名最好跟生成的文档后缀名保持一致!)


#注意事项:JDK为64位的jdk1.7.0_45,windows系统为64位win10


2、生成最终WORD文档的基本流程为

执行WORD模板--XML--FTL--java工具类生成需要的WORD文档


3、WORD模板,例如:(以下是一个WORD文档的模板test.doc,就一页,太大,分三个图截屏的,可自定义截图)

#注意事项:因为通过freemarker生成WORD的每一页数据是通过WORD模板填充进去的,所以WORD模板的最上方和最下方千万不要有多余的空行!

技术分享

技术分享

技术分享



4、另存为XML文档,比如test.xml

#由于这里要生成多页,所以在生成的test.xml中需要修改以下地方:

4、1打开test.xml文档,会发现所有的图片生成了BASE64编码,需要先把BASE64编码全部删掉。

#删除完之后可以使用XML格式化工具,先把XML文档格式化,以下操作过程按照格式化后的XML格式文件讲解。

格式化地址:http://tool.oschina.net/codeformat/xml。

4、2由于要生成多页,所以要加入list循环标签及对应值标签(以MAP形式获取)。

#以下只标注需要改动的地方

4、2、1加入list标签,直接搜索<w:tbl>和</w:tbl>即可,这一个XML按照我的例子只有一对。

#listdataMap是个list,这个list中放入了多个map,是dataMap。

技术分享

技术分享


4、2、2加入list标签中的值标签,搜索模板中的Test1替换成${dataMap.Test1},Test2和其他的同理.

#dataMap这是个Map,Test1是KEY值

技术分享

技术分享

4、2、3其中自定义的页码也要手工替换(此字段在上述list中间),发现用WORD自带的页码不好用(页脚插入的图片也是不好用),暂时自定义,如果发现能搞,那么我会更新此博客。

技术分享


4、2、4修改image标签内容,也就是4、1对应的BASE64编码的相关标签,

修改原理同4、2、1--4、2、3。

技术分享#因为每页都需要图片展示,所以图片也需要在每页同样的地方显示出来,图片放置顺序同WORD模板中从上到下的排列顺序。


4、3把上述XML文件保存之后另存为ftl文件,最好黏到java项目里,见4、4。


4、4项目格式为

技术分享



4、5DocumentHandler.java工具处理代码示例:

package org.mbox.test;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import sun.misc.BASE64Encoder;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class DocumentHandler {

	private Configuration configuration = null;

	public DocumentHandler() {
		configuration = new Configuration();
		configuration.setDefaultEncoding("utf-8");
	}
	
	private static String getImageStr(String imgFile) {
	     InputStream in = null;
	     byte[] data = null;
	     try {
	       in = new FileInputStream(imgFile);
	       data = new byte[in.available()];
	       in.read(data);
	       in.close();
	     } catch (IOException e) {
	       e.printStackTrace();
	     }
	     BASE64Encoder encoder = new BASE64Encoder();
	     return encoder.encode(data);
	   }
	
	public void createDoc(Map<String, Object> listdataMap,String fileName) throws UnsupportedEncodingException {
		configuration.setClassForTemplateLoading(this.getClass(), "/org/mbox/test");
		Template t=null;
		try {
			t = configuration.getTemplate("test.ftl");
		} catch (IOException e) {
			e.printStackTrace();
		}
		File outFile = new File(fileName);
		Writer out = null;
		FileOutputStream fos=null;
		try {
			fos = new FileOutputStream(outFile);
			OutputStreamWriter oWriter = new OutputStreamWriter(fos,"UTF-8");
			 out = new BufferedWriter(oWriter); 
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		 
        try {
			t.process(listdataMap, out);
			out.flush();
			fos.flush();
			out.close();
			fos.close();
		} catch (TemplateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
        
	}
	
	/**
	 * @param args
	 * @throws UnsupportedEncodingException 
	 */
	public static void main(String[] args) throws UnsupportedEncodingException {

		Map<String, Object> map = new HashMap<String,Object>();
		List<Map<String, Object>> listdataMap = new ArrayList<Map<String, Object>>();
		for (int i = 0; i < 5; i++) {
			Map<String, Object> dataMap = new HashMap<String, Object>();
			dataMap.put("image1", getImageStr("G:/1.jpg"));
			dataMap.put("image2", getImageStr("G:/2.jpg"));
			dataMap.put("image3", getImageStr("G:/3.jpg"));
			dataMap.put("Test1", "value"+i);
			dataMap.put("Test2", "value"+i);
			dataMap.put("Test3", "value"+i);
			dataMap.put("Test4", "value"+i);
			dataMap.put("Test5", "value"+i);
			dataMap.put("pagenum", (i+1));
			listdataMap.add(dataMap);
		}
		map.put("listdataMap", listdataMap);
		DocumentHandler mdoc = new DocumentHandler();
		mdoc.createDoc(map, "G:/outFile.doc");
	}
}



















本文出自 “你可以选择不平凡” 博客,请务必保留此出处http://ylcodes01.blog.51cto.com/5607366/1842693

以上是关于java通过freemarket生成word文档的主要内容,如果未能解决你的问题,请参考以下文章

使用freemarker生成的word文档,如何利用java代码将其转换为pdf格式?

求助关于java通过jacob操作word的问题

java生成word文档的问题

如何通过java将多个word文档合成一个wor

如何用java生成word

如何通过Java程序合并Word文档