一 优点:简单方便
二 使用步骤
1.新建一个word,如export.docx。打开word编写模板,插入表格和图片。
2 另存word为 xml格式,再更改后缀为ftl格式 ,利用notepad的xml tool格式化这个文件。
3.修改ftl文件,动态插入数据。命令${param},集合方式<#list list as list></#list>和多个图片。
说明普通集合和图片的修改方式,红色部分为需要修改的。
3.1 集合 tr表示表格tr
<#list list as list><w:tr.......><w:t>${list.name}</w:t></#list>
3.2多个图片。index 是代码中自定义,每个图片不能重复。photo为base64字符串,测试中自己生成,实际项目可以是前端传参。
<#list images as images> <w:p wsp:rsidR="000D2920" .....>
<w:binData w:name="wordml://02000001${images.index}.jpg" xml:space="preserve">${images.photo}</w:binData>...
<v:imagedata src="wordml://02000001${images.index}.jpg" o:title=""/>1
</v:shape></w:pict></w:r></w:p> </#list>
4.后台代码
4.1 测试主要类 图片路径转字节数组
private byte[] getBytes(String filePath){
byte[] buffer = null;
try {
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
byte[] b = new byte[1000];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return buffer;
}
测试类
/**
* @param photo 注意该photo参数为前台传过来图片
*/
@RequestMapping("/exportWord")
public void exportWord(HttpServletResponse response){
ExportWordUtil ewUtil = new ExportWordUtil();
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("title", "标题");
Base64.Encoder base64 = Base64.getEncoder();
try {
// dataMap.put("photo", base64.encodeToString(getBytes("D:\\test\\Jellyfish.jpg")));
} catch (Exception e){
}
ArrayList<Photo> arrayList = new ArrayList<>();
arrayList.add(new Photo(base64.encodeToString(getBytes("D:\\test\\Jellyfish.jpg")),1));
arrayList.add(new Photo(base64.encodeToString(getBytes("D:\\test\\Chrysanthemum.jpg")),2));
dataMap.put("images", arrayList);
List<User> userList = new ArrayList<>();
userList.add(new User("名称1","男"));
userList.add(new User("名称2","男"));
dataMap.put("list", userList);
ewUtil.exportWord(dataMap, "test.ftl", response, "test1.doc");
}
导出工具类
package com.example.kafkatest;
import freemarker.template.*;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;
import static freemarker.template.Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS;
@Slf4j
public class ExportWordUtil {
private Configuration config;
public ExportWordUtil() {
config = new Configuration(DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
config.setDefaultEncoding("utf-8");
}
/**
* FreeMarker生成Word
* @param dataMap 数据
* @param templateName 模板名
* @param response HttpServletResponse
* @param fileName 导出的word文件名
*/
public void exportWord(Map<String, Object> dataMap, String templateName, HttpServletResponse response, String fileName) {
config.setClassForTemplateLoading(this.getClass(), "/templates");
config.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
try {
if(templateName.endsWith(".ftl")) {
templateName = templateName.substring(0, templateName.indexOf(".ftl"));
}
Template template = config.getTemplate(templateName + ".ftl");
response.setContentType("application/msword");
response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(fileName, "utf-8"));
OutputStream outputStream = response.getOutputStream();
Writer out = new BufferedWriter(new OutputStreamWriter(outputStream));
template.process(dataMap, out);
out.flush();
} catch (TemplateNotFoundException e) {
e.printStackTrace();
} catch (MalformedTemplateNameException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}