Java使用freemarker动态导出word
适用于Java项目导出word文件,通过freemarker模板引擎动态填充word模板并导出。
1. 所需依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.13</version>
</dependency>
2. word模板
模板位置放在resource/ftl下面
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Welcome ${user}!</h1>
<p>Your Blog Site:
<a href="${blog.url}">${blog.name}</a>!
<table border="1">
<tr>
<#list headers as header>
<th>${header}</th>
</#list>
</tr>
<#list fansList as fans>
<tr>
<td>${fans.name}</td>
<td>${fans.gender}</td>
<td>${fans.age}</td>
</tr>
</#list>
</table>
</body>
</html>
3. 工具类
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;
/**
* @author zxg
* @date Created in 2022/02/08 17:19
* Description 文档导出工具类
*/
@Component
@Slf4j
public class DocumentHandler {
public void createDoc(Map<String,Object> dataMap, String fileName) {
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
//dataMap 要填入模本的数据文件
//这里我们的模板是放在/resource/ftl包下面
configuration.setClassForTemplateLoading(this.getClass(), "/ftl");
Template t=null;
try {
//test.ftl为要装载的模板
t = configuration.getTemplate("test.ftl");
} catch (IOException e) {
log.error("load template error, err: <{}>",e.getMessage(),e);
}
//输出文档路径及名称
File outFile = new File(fileName);
Writer out = null;
try(FileOutputStream fos = new FileOutputStream(outFile)) {
OutputStreamWriter oWriter = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
out = new BufferedWriter(oWriter);
t.process(dataMap, out);
} catch (Exception e) {
log.error("export word error,err: <{}>",e.getMessage(),e);
}
try {
if(out!=null){
out.close();
}
} catch (IOException e) {
log.error("error: {}",e.getMessage(),e);
}
}
}
业务代码
@RestController
@RequestMapping("/export")
public class ExportController {
@Autowired
private ExportService exportService;
@PostMapping("/word")
public void auditReport(HttpServletResponse response) {
exportService.exportAuditReport(response);
}
}
import com.study.exportword.util.DocumentHandler;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author zxg
* @date Created in 2022/02/08 17:16
* Description 导出word文件
*/
@Service
@Slf4j
public class ExportService {
@Data
@Builder
public static class User {
private String name;
private String gender;
private int age;
}
@Autowired
private DocumentHandler documentHandler;
public void exportAuditReport(HttpServletResponse response) {
// dataMap未模板填充的数据
HashMap<String, Object> dataMap = new HashMap<>();
generateDataMap(dataMap);
String tmpFile = "C:\\Users\\lenovo\\Desktop\\test.docx";
documentHandler.createDoc(dataMap, tmpFile);
File file = new File(tmpFile);
//文件名编码
String fileName = file.getName();
log.info("download file: {}", fileName);
try {
fileName = URLEncoder.encode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
log.error("file download error, error msg <{}>", e.getMessage(), e);
}
//输出流
try (FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream()) {
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName);
byte[] buffer = new byte[1024];
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer);
i = bis.read(buffer);
}
} catch (Exception e) {
log.error("file download error, error msg <{}>", e.getMessage(), e);
}
}
private void generateDataMap(HashMap<String, Object> dataMap) {
dataMap.put("user", "admin");
HashMap<String, String> blog = new HashMap<>();
blog.put("url","http://www.baidu.com");
blog.put("name","admin的博客");
dataMap.put("blog", blog);
dataMap.put("headers", Lists.newArrayList("粉丝姓名", "性别", "年龄"));
List<User> fansList = Stream.of(
User.builder().name("张三").gender("男").age(20).build(),
User.builder().name("李四").gender("女").age(21).build(),
User.builder().name("王五").gender("男").age(24).build())
.collect(Collectors.toList());
dataMap.put("fansList",fansList);
}
}