Word模板导出
制作导出模板
1、创建word模板,添加替换数据的占位符
2、保存模板为XML格式
3、修改文件后缀,改为ftl
4、添加FreeMark标签(Ctrl+Alt+L格式化文件)
5、添加FreeMark标签
编写替换代码
/**
* 导出word
* @param dataMap 数据集
* @param templateName 模板名称
* @param fileName 导出的文件名
* @param response
* @param request
*/
private void createDoc(Map<String, Object> dataMap, String templateName, String fileName, HttpServletResponse response,
HttpServletRequest request) throws IOException, TemplateException {
String templatePath = "templates" + File.separator + templateName;
ClassPathResource classPathResource = new ClassPathResource(templatePath);
// 将模板文件拷贝到临时文件夹
InputStream templateStream = classPathResource.getInputStream();
String templatePrefix = "template-";
File templateFile = File.createTempFile(templatePrefix, templateName);
try {
FileUtils.copyInputStreamToFile(templateStream, templateFile);
} finally {
IOUtils.closeQuietly(templateStream);
}
// freemarker 模板文件夹设置
Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
cfg.setDefaultEncoding("utf-8");
cfg.setOutputEncoding("utf-8");
cfg.setDirectoryForTemplateLoading(new File(templateFile.getParent()));
// 临时文件,生成 word 文档
File outFile = File.createTempFile("doc-" + fileName, ".doc");
FileOutputStream fileOutputStream = new FileOutputStream(outFile);
// 将模板和数据模型合并生成文件
Writer writer = new BufferedWriter(new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8));
// 生成文件
Template template = cfg.getTemplate(templateFile.getName());
template.process(dataMap, writer);
// 关闭流
writer.flush();
writer.close();
fileOutputStream.flush();
fileOutputStream.close();
// 文件写入输出流
byte[] bFile = Files.readAllBytes(outFile.toPath());
OutputStream out = response.getOutputStream();
fileName = getFileName(fileName, request);
response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".doc");
response.setContentType("application/octet-stream;charset=UTF-8");
out.write(bFile);
out.flush();
out.close();
outFile.deleteOnExit();
}
/**
* 对文件名进行转码
* @param fileName
* @param request
* @return
*/
private String getFileName(String fileName, HttpServletRequest request) {
String header = request.getHeader("User-Agent");
try {
if (header.toLowerCase().indexOf("firefox") > 0) {
fileName = new String(fileName.getBytes(StandardCharsets.ISO_8859_1), "ISO8859-1");
} else if (header.toUpperCase().indexOf("MSIE") > 0) {
fileName = URLEncoder.encode(fileName, "UTF-8");
} else {
fileName = URLEncoder.encode(fileName, "UTF-8");
}
} catch (UnsupportedEncodingException e) {
logger.debug("文件名转码失败!", e);
}
return fileName;
}
附录
附录1
word标签
<w:body>//文档主体
<w:tbl>//表格
<w:tblPr>//表格属性
……
</w:tblPr>
<w:tblGrid>//表格列宽
<w:gridCol w:w="xxx"/>
<w:gridCol w:w="xxx"/>
</w:tblGrid>
<w:tr w:rsidR="00BD68AB">//表格的一行
<w:trPr>//表格行属性
<w:trHeight w:val="427"/>
</w:trPr>
<w:tc>//表格的一个单元格
<w:tcPr>//单元格属性
……
</w:tcPr>
<w:p>//一个段落
<w:pPr>//段落属性
<w:jc w:val="center"/>//设置内容居中
<w:spacing w:line="360" w:lineRule="exact"/>//设置行距(line为行距值,240为单倍行距,以此类推)
<w:rPr>//设置区域内文本属性
……
</w:rPr>
</w:pPr>
<w:r>//表示一个样式串,指明它包括的文本的显示样式
<w:rPr>//设置区域内文本属性(与<w:pPr>标签内属性一样)
……
</w:rPr>
<w:t>………………</w:t>//文字内容(真正能看到的,前面的若干行都是为这一行做铺垫)
//注;文字内容可以写死,也可以动态取值,如:${Detail1.companyName!}
</w:r>
</w:p>
</w:tc>
</w:tr>
</w:tbl>
<w:sectPr>//设置整个页面的属性
<w:footerReference w:type="default" r:id="rId8"/>
<w:pgSz w:w="16838" w:h="11906" w:orient="landscape"/>
<w:pgMar w:top="851" w:right="851" w:bottom="851" w:left="851" w:header="851" w:footer="454" w:gutter="0"/>
</w:sectPr>
</w:body>