最近因客户需求,需要在项目中动态导出动态表格。步骤如下:
模板准备
1.新建word文档

注:如果序号从1开始,可以写成${item_index+1},c标签的同样在这适用。
2.另存为.xml文件(注意不是直接改后缀名),格式化代码,注意检查是否存在变量分离问题,如图:


3.注意将循环遍历的list在表格取数据的tr前添加如下标签
4.格式化并修改完后,将.xml的后缀名修改为.ftl(直接修改)
springboot集成整合
1.pom.xml中添加freemarker依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
2.配置freemarker
#freemarker
freemarker:
allow-request-override: false
cache: true
check-template-location: false
charset: UTF-8
content-type: text/html;charset=utf-8
expose-request-attributes: false
expose-session-attributes: false
expose-spring-macro-helpers: fase
request-context-attribute:
suffix: .ftl
template-loader-path: classpath:/templates/
3.将test.ftl模板拷贝到项目的resource目录下

4.测试页面导出方法
function exportDoc(){
var elemIF = document.createElement("iframe");
elemIF.src = "${ctx}/exportDoc";
elemIF.style.display = "none";
document.body.appendChild(elemIF);
}
5.测试controller
@Controller
public class TestController {
@PostMapping("uploadFile")
@ResponseBody
public void exportDoc(HttpServletRequest request, HttpServletResponse response) throws Exception{
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
configuration.setClassicCompatible(true);
//既能保证本地运行找得到模板文件,又能保证jar包运行能找到得到模板文件
configuration.setClassForTemplateLoading(this.getClass(),"/template");
configuration.setTemplateLoader(new ClassTemplateLoader(this.getClass(),"/template"));
Template t=configuration.getTemplate("test.ftl","utf-8");
response.setContentType("application/msword; charset=UTF-8");// application/x-download
response.setHeader("Content-Disposition", "attachment; "
+ encodeFileName(request, "导出模板.doc"));
OutputStream outputStream = response.getOutputStream();
Writer out=new OutputStreamWriter(outputStream);
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("createUser","admin");
dataMap.put("tableName","tb_user_info");
dataMap.put("remark","用户信息");
List<DataItemBean> itemList = new ArrayList<DataItemBean>();
DataItemBean itemBean = new DataItemBean();
itemBean.setItemEnName("user_name");
itemBean.setItemZhName("用户名");
itemBean.setItemType("varchar");
itemBean.setItemLength("32");
itemList.add(itemBean);
itemBean.setItemEnName("password");
itemBean.setItemZhName("密码");
itemBean.setItemType("varchar");
itemBean.setItemLength("50");
itemList.add(itemBean);
dataMap.put("itemList",itemList);
t.process(dataMap, out);
outputStream.close();
out.close();
}
public static String encodeFileName(HttpServletRequest request, String fileName) throws UnsupportedEncodingException {
String new_filename = URLEncoder.encode(fileName, "UTF8").replaceAll("\\+", "%20");
String agent = request.getHeader("USER-AGENT").toLowerCase();
if (null != agent && -1 != agent.indexOf("msie"))
{
/**
* IE浏览器,只能采用URLEncoder编码
*/
return "filename=\"" + new_filename +"\"";
}else if (null != agent && -1 != agent.indexOf("applewebkit")){
/**
* Chrome浏览器,只能采用ISO编码的中文输出
*/
return "filename=\"" + new String(fileName.getBytes("UTF-8"),"ISO8859-1") +"\"";
} else if (null != agent && -1 != agent.indexOf("opera")){
/**
* Opera浏览器只可以使用filename*的中文输出
* RFC2231规定的标准
*/
return "filename*=" + new_filename ;
}else if (null != agent && -1 != agent.indexOf("safari")){
/**
* Safani浏览器,只能采用iso编码的中文输出
*/
return "filename=\"" + new String(fileName.getBytes("UTF-8"),"ISO8859-1") +"\"";
}else if (null != agent && -1 != agent.indexOf("firefox"))
{
/**
* Firfox浏览器,可以使用filename*的中文输出
* RFC2231规定的标准
*/
return "filename*=" + new_filename ;
} else
{
return "filename=\"" + new_filename +"\"";
}
}
}
DataItemBean
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* Created on 2021-12-24.
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DataItemBean implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private String id;
/**
* 父节点主键
*/
private String tableId;
/**
* 数据项中文名称
*/
private String itemZhName;
/**
* 数据项英文名称
*/
private String itemEnName;
/**
* 数据类型
*/
private String itemType;
/**
* 字段长度
*/
private String itemLength;
/**
* 备注
*/
private String remark;
}
导出效果

本文介绍了如何在SpringBoot项目中结合Freemarker动态生成Word文档,包括模板的准备,SpringBoot的集成配置,以及实际的导出效果展示。
4271

被折叠的 条评论
为什么被折叠?



