1 创建word模板
2 动态数据占位
格式:${xxxxx}
3 点击另存为xml格式
4 修改后缀名为ftl
5 导入到idea中
6 修改文件编码为utf-8
7 复制模板内容在线代码格式化
8 编辑模板中内容
如果有空值会报错,可以 ${xxxx !''}处理,网上查看可以在配置文件中配置,但是我试了总是不生效
spring.freemarker.settings.classic_compatible=true
有需要遍历的表格
9 导出
因为使用ftl模板,需要引入jar包
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
模板取值需要从map中取值,对象转map就可以了
public void exportReport(HttpServletResponse response, Integer receiptId) throws IOException, TemplateException {
Map<String, Object> dataMap = new HashMap<>();
//获取,可忽略
PrintReceiptInfoVO printReceiptInfoVO = this.getPrintReceiptInfo(receiptId);
if(printReceiptInfoVO != null) {
String ecpNoticeId = printReceiptInfoVO.getEcpNoticeId();
if(!StringUtils.isEmpty(ecpNoticeId)) {
String ecpResult = ecpApi.getOrderNoticeInfoMain(ecpNoticeId);
if(!StringUtils.isEmpty(ecpResult)) {
RemoteResult remoteResult = JSON.parseObject(ecpResult, new TypeReference<RemoteResult>() {});
if ("200".equals(remoteResult.getStatus()) && remoteResult.getData() != null && !"[]".equals(remoteResult.getData().toString())){
List<EcpPrintInfoVO> ecpReceiptVOS = JSON.parseObject(remoteResult.getData().toString(),new TypeReference<List<EcpPrintInfoVO>>(){});
if(!CollectionUtils.isEmpty(ecpReceiptVOS)) {
EcpPrintInfoVO ecpPrintInfoVO = ecpReceiptVOS.get(0);
if(ecpPrintInfoVO != null) {
BeanUtils.copyProperties(ecpPrintInfoVO,printReceiptInfoVO);
printReceiptInfoVO.setConsignorRemark("样机");
}
}
}
}
}
dataMap = MapBeanUtil.object2Map(printReceiptInfoVO);
}
//获取数据end
PrintWriter out = response.getWriter();
//配置对象
Configuration configuration = new Configuration();
//设置配置的字符编码为utf-8,避免字符集问题
configuration.setDefaultEncoding("UTF-8");
//获取resources下指定的文件夹路径,如果项目需要打成jar包,
//此举很重要,别的方式可能无法获取到模板文件夹的相对路径
configuration.setClassForTemplateLoading(this.getClass(), "/templates");
// 获取模板实例,上行配置了模板文件所在路径
Template t = configuration.getTemplate("exportReceipt.ftl", "utf-8");//以utf-8的编码读取ftl文件
//设置响应类型为word
response.setContentType("application/msword");
//设置响应头,注意如果导出的word名含有汉字则需要将文件名
//变成byte并且指定字符集为gbk,表示将GBK汉字转为byte
//然后将其转为iso8859-1的字符串
response.setHeader("Content-Disposition", "attachment;filename=\""
+ new String(("导出报告.doc").getBytes("GBK"), "iso8859-1") + "\"");
//此句非常关键,不然word文档全是乱码
response.setCharacterEncoding("utf-8");
//使用数据填充模板
t.process(dataMap, out);
//以流的输出到浏览器,即下载
out.close();
}
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
/**
* map转bean,bean转map
*/
public class MapBeanUtil {
/**
* 实体对象转成Map
*
* @param obj 实体对象
* @return
*/
public static Map<String, Object> object2Map(Object obj) {
Map<String, Object> map = new HashMap<>();
if (obj == null) {
return map;
}
Class clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
try {
for (Field field : fields) {
field.setAccessible(true);
map.put(field.getName(), field.get(obj));
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
/**
* Map转成实体对象
*
* @param map 实体对象包含属性
* @param clazz 实体对象类型
* @return
*/
public static Object map2Object(Map<String, Object> map, Class<?> clazz) {
if (map == null) {
return null;
}
Object obj = null;
try {
obj = clazz.newInstance();
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
int mod = field.getModifiers();
if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
continue;
}
field.setAccessible(true);
field.set(obj, map.get(field.getName()));
}
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
}