使用freemaker进行生成word文档并实现预览
这里是有两个功能,一个是word文档生成,还有一个就实现word文档的预览,由于freemaker的原因,生成的word文档不是标准格式的word文档,所以在转换html格式时,会出现错误,无法转换,为了不浪费时间,没有深入研究,我选择了将文件先转成html,再对html进行动态数据绑定,以此来实现浏览器页面预览的效果。
!!!请仔细阅读,我这很多地方做了说明,防止查看遗漏,导致时间成本增加。
一、导入依赖
我这里使用的是springboot自带的freemaker
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
二、导出word文件步骤
1.将word文档转成ftl文件
1.使用wps或者office打开文件,选择另存为
2.将文件改成xml格式
3.保存到桌面,将文件后缀改为 ftl
2.文件数据绑定
- 将刚刚生成的ftl文件使用文件编辑器打开,建议将内容格式化,方便阅读
我这里使用的是Notepad++
- 对文档内容进行数据绑定,我将举例几个使用示例(如图)
a. list循环
b.合并单元格
c.条件判断
d.动态绑定
e.判断list是否为空
<#if testList?? && (testList?size > 0) >
<#list testList as test> 这里是list列表循环
<w:tr>
<w:tc>
<w:tcPr>
<#if test.isHead == 1> 合并单元格
<w:vMerge w:val="restart"/> 第一行
<#else>
<w:vMerge w:val="continue"/> 其他要合并的行
</#if>
<w:tcBorders>
<#if test.isLast == 1> 通过表示来判断展示
<w:bottom w:val="single"
w:color="000000"
w:sz="4"
w:space="0"/>
<#else>
<w:bottom w:val="single"
w:color="000000"
w:sz="24"
w:space="0"/>
</#if>
</w:tcBorders>
<w:p>
<w:r>
<#if test.isHead == 1>
<w:t>${test.number}</w:t> 动态数据
</#if>
</w:r>
</w:p>
</w:tcPr>
</w:tc>
</w:tr>
</#list>
- 文件编辑好之后,将其放到项目内
我这边的话是放到resources目录的templates文件夹下
三、导出html文件步骤
-
步骤与word转xml类似,这次只需将原word文件转换成html格式,并将后缀修改成 ftl 即可,这里就不详细介绍了。
-
html文件动态数据(重点)
list循环和条件判断是一样的
html与xml的格式有区别所以有些地方是不一样的
例:
- 单元格合并,合并第一行展示改属性,其他合并行无需展示
- 针对style的动态数据绑定,根据动态值来对样式进行动态展示
- if条件判断和数据绑定
四、解析文件并生成文档
- 废话不多说,直接上代码。
类中有两个方法,一个是生成word(createWord)文档,
一个是生成html(createHtml)文档
package cn.hzreal.lqm.util;
import cn.hzreal.lqm.model.vo.VZxCqBaseVo;
import cn.hzreal.lqm.model.vo.ZxRenVO;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.dom4j.Document;
import org.dom4j.io.*;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WordUtil {
private Configuration configuration = null;
/***
* 模板文件名称
*/
//word-ftl文件
private static final String templateFile = "test.ftl";
//html-ftl文件
private static final String templateFileHtml = "toHtml2.ftl";
/***
* word生成的输出目录
*/
//线上下载目录(自定义目录即可)
private static final String outputDir = "/templates/";
//本地下载地址
// private static final String outputDir = "D:/files/";
public WordUtil(){
configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
}
public static void main(String[] args) {
WordUtil test = new WordUtil();
test.createWord();
}
/*****
*
* Project Name: maventest
* <p>转换成word<br>
*/
public void createWord() throws Exception {
Map<String,Object> dataMap=new HashMap<>();
//构造参数
getData(dataMap);
//模板文件所在路径
configuration.setClassForTemplateLoading(this.getClass(), "/templates/");
Template t=null;
try {
t = configuration.getTemplate(templateFile);
} catch (IOException e) {
e.printStackTrace();
}
//导出文件
File outFile = new File(outputDir+Math.random()*10000+".doc");
Writer out = null;
response.setContentType("application/x-msdownload;");
response.addHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode("文档名称", "UTF-8") + ".doc");
try {
//本地下载
// out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
//响应到浏览器
out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
//将填充数据填入模板文件并输出到目标文件
t.process(dataMap, out);
System.out.println("生成成功...");
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/*****
*
* Project Name: maventest
* <p>转换成html<br>
*/
public void createHtml() throws Exception {
Map<String,Object> dataMap=new HashMap<>();
//构造参数
getData(dataMap);
//由于html的编码问题,我在这里做了编码转换
configuration.setDefaultEncoding("GBK");
//模板文件所在路径
configuration.setClassForTemplateLoading(this.getClass(), "/templates/");
Template t=null;
try {
// configuration.setDirectoryForTemplateLoading(new File(baseDir));
t = configuration.getTemplate(templateFileHtml);
} catch (IOException e) {
e.printStackTrace();
}
//导出文件
// File outFile = new File(outputDir+Math.random()*10000+".html");
Writer out = null;
response.setContentType("application/x-msdownload;");
response.addHeader("Content-Disposition", "attachment;filename="+ "test.html");
try {
// out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(),"UTF-8"));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
String content="";
try {
//将填充数据填入模板文件并输出到目标文件
t.process(dataMap, out);
content=t.getRootTreeNode().getTemplate().toString();
System.out.println("生成成功...");
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/****
*
* Project Name: maventest
* <p>初始化数据map <br>
*/
private void getData(Map<String, Object> dataMap) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//根据自己的数据进行添加即可
dataMap.put("number", 1);
dataMap.put("nowDate", formatter.format(new Date()));
}
}
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。