JAVA通过模板生成DOCX文档
第二篇文章,代码更精简,增加生成图片的思路
大致流程:
1.创建模板docx并取出document.xml
新建一个docx文档,放在D盘命名test_template.docx
![Image 1][]
2.用winrar打开test_template.docx,取出word/document.xml
把xml文件格式化一下看起来更清晰,并且把要替换的内容用freemarker的指令代替,最后将文件重命名为test.xml放在D盘下面
3.准备工作完毕,上代码了,这个类是把内容填充到xml
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class XmlToExcel {
private static XmlToExcel tplm = null;
private Configuration cfg = null;
private XmlToExcel() {
cfg = new Configuration();
try {
// 注册tmlplate的load路径
// cfg.setClassForTemplateLoading(this.getClass(), "/template/");
cfg.setDirectoryForTemplateLoading(new File("D:/"));
} catch (Exception e) {
}
}
private static Template getTemplate(String name) throws IOException {
if (tplm == null) {
tplm = new XmlToExcel();
}
return tplm.cfg.getTemplate(name);
}
/**
*
* @param templatefile 模板文件
* @param param 需要填充的内容
* @param out 填充完成输出的文件
* @throws IOException
* @throws TemplateException
*/
public static void process(String templatefile, Map param, Writer out) throws IOException, TemplateException {
// 获取模板
Template template = XmlToExcel.getTemplate(templatefile);
template.setOutputEncoding("UTF-8");
// 合并数据
template.process(param, out);
if (out != null) {
out.close();
}
}
}
4.这个类是把填充完毕的xml转成docx
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
/**
* 其实docx属于zip的一种,这里只需要操作word/document.xml中的数据,其他的数据不用动
*
* @author yigehui
*
*/
public class XmlToDocx {
/**
*
* @param documentFile 动态生成数据的docunment.xml文件
* @param docxTemplate docx的模板
* @param toFileName 需要导出的文件路径
* @throws ZipException
* @throws IOException
*/
public void outDocx(File documentFile, String docxTemplate, String toFilePath) throws ZipException, IOException {
try {
File docxFile = new File(docxTemplate);
ZipFile zipFile = new ZipFile(docxFile);
Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(toFilePath));
int len = -1;
byte[] buffer = new byte[1024];
while (zipEntrys.hasMoreElements()) {
ZipEntry next = zipEntrys.nextElement();
InputStream is = zipFile.getInputStream(next);
// 把输入流的文件传到输出流中 如果是word/document.xml由我们输入
zipout.putNextEntry(new ZipEntry(next.toString()));
if ("word/document.xml".equals(next.toString())) {
InputStream in = new FileInputStream(documentFile);
while ((len = in.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}
in.close();
} else {
while ((len = is.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}
is.close();
}
}
zipout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
5.main方法调用
public static void main(String[] args) throws IOException, TemplateException {
try {
// xml的文件名
String xmlTemplate = "test.xml";
// docx的路径和文件名
String docxTemplate = "d:\\test_template.docx";
// 填充完数据的临时xml
String xmlTemp = "d:\\temp.xml";
// 目标文件名
String toFilePath = "d:\\test.docx";
Writer w = new FileWriter(new File(xmlTemp));
// 1.需要动态传入的数据
Map<String, Object> p = new HashMap<String, Object>();
List<String> students = new ArrayList<String>();
students.add("张三");
students.add("李四");
students.add("王二");
p.put("ddeptdept", "研发部门");
p.put("ddatedate", "2016-12-15");
p.put("dnamename", students);
// 2.把map中的数据动态由freemarker传给xml
XmlToExcel.process(xmlTemplate, p, w);
// 3.把填充完成的xml写入到docx中
XmlToDocx xtd = new XmlToDocx();
xtd.outDocx(new File(xmlTemp), docxTemplate, toFilePath);
} catch (Exception e) {
e.printStackTrace();
}
}
[Image 1]:
还没有评论,来说两句吧...