- pom.xml 准备
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-MOXy-JAXBContext</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>3.2.1</version>
</dependency>
2.准备一个word文档编辑好格式
3,用notepad++ 打开xml 可以在notepad++上下载一个处理xml的插件(xml tools 的插件) 格式化xml
4,制作模板在模板中用${value} 替换你编辑好的word文档中需要替换的地方
比如
<w:r>
<w:rPr>
<w:rFonts w:ascii="仿宋_GB2312" w:fareast="仿宋_GB2312"
w:h-ansi="宋体" w:hint="fareast" />
<wx:font wx:val="仿宋_GB2312" />
<w:b />
<w:b-cs />
<w:sz-cs w:val="21" />
</w:rPr>
<w:t>模板</w:t>
</w:r>
将模板这个汉子替换为
<w:r>
<w:rPr>
<w:rFonts w:ascii="仿宋_GB2312" w:fareast="仿宋_GB2312"
w:h-ansi="宋体" w:hint="fareast" />
<wx:font wx:val="仿宋_GB2312" />
<w:b />
<w:b-cs />
<w:sz-cs w:val="21" />
</w:rPr>
<w:t>${templateName}</w:t>
</w:r>
如果遇到集合用<#list yourList as item> 这里放你要repeat的代码片段
public class WordGenerator {
private final static Logger _logger = LoggerFactory.getLogger(WordGenerator.class);
private static Configuration configuration = null;
public static Configuration getConfiguration() {
configuration = new Configuration(Configuration.VERSION_2_3_23);
try {
configuration.setDirectoryForTemplateLoading(这里设置你项目中存放ftl文件的目录));
} catch (IOException e) {
_logger.error(e.getMessage(),e);
}
configuration.setDefaultEncoding("utf-8");
configuration.setLogTemplateExceptions(false);
return configuration;
}
/**
*fileName 你要输出的文件名
*dataMap ftl 需要显示的值
*name ftl名称 ps: test.ftl
**/
public static File createDoc(String fileName,
Map<?, ?> dataMap, String name) {
configuration = getConfiguration();
Writer w = null;
File f = new File(fileName);
FileOutputStream fos =null;
try {
Template t =configuration.getTemplate(name);
fos =new FileOutputStream(f);
w = new OutputStreamWriter(fos, "utf-8");
t.process(dataMap, w);
w.close();
} catch (Exception ex) {
//TODO
} finally {
IOUtils.closeQuietly(w);
IOUtils.closeQuietly(fos);
}
return f;
}
}
7,使用例子
/**ftl 中出现的${value} 这样的值 表现为dataMap中的key value则为你要显示的值**/
Map<String,Object> dataMap = new HashMap<>();
dataMap.put("tempdateName","测试");
File resumeFile = WordGenerator.createDoc(“test.xml”, dataMap, "resume.ftl");
//这样你就能得到你想要的xml
//这个xml可以用office word 打开,但是如果你想得到docx的文件,你可能会直接把xml重命名为xx.docx 但事实是 你这样做了之后,office word打不开提示错误那么接下来的操作比较重要
WordprocessingMLPackage wmlPackage = (WordprocessingMLPackage) WordprocessingMLPackage.load(new FileInputStream(resumeFile));
File file = new File("test.docx");
wmlPackage.save(file, Docx4J.FLAG_SAVE_ZIP_FILE);
这样 test.docx就可以正常用office word打开,而且在手机上也是可以正常打开的
笔者在执行上面的代码的时候发现非常慢 而且经常内存溢出。慢是应为docx4j初始化的时候比较慢,只是第一次执行比较慢,后面的都很快,google了很多还没找到比较靠谱的解决方法。
内存溢出 是docx4j初始化jaxb的时候比较吃PermGen space 的内存
解决方法:设置tomcat的启动参数,把tomcatjvm的 PermGen space设大一点,默认大小为:85m
设置为tomcat的jvm之后,运行稳定,而且比较快。