Spring boot集成freemarker导出excel,excel 模板有图片
时间: 2024-06-09 22:10:57 浏览: 174
springboot中使用freemarker动态生成word文档,以及使用POI导出自定义格式Excel
在 Spring Boot 中集成 Freemarker 导出 Excel,可以通过以下步骤实现:
1. 首先,需要在 Spring Boot 中添加 Freemarker 和 Apache POI 依赖:
```xml
<dependencies>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${apache.poi.version}</version>
</dependency>
</dependencies>
```
2. 创建 Excel 模板文件,可以使用 Freemarker 的模板语法来定义表头和数据内容,同时在模板中可以使用 `img` 标签来引用图片,例如:
```html
<html>
<head>
<title>Excel Template</title>
</head>
<body>
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Photo</th>
</tr>
</thead>
<tbody>
<#list users as user>
<tr>
<td>${user.name}</td>
<td>${user.age}</td>
<td><img src="${user.photo}" /></td>
</tr>
</#list>
</tbody>
</table>
</body>
</html>
```
其中,`users` 是一个包含数据的列表,每个元素是一个包含 `name`、`age` 和 `photo` 属性的对象,`photo` 属性是图片的 URL。
3. 在 Spring Boot 中定义一个控制器,用于处理导出 Excel 的请求:
```java
@Controller
public class ExcelController {
@Autowired
private Configuration freemarkerConfig;
@GetMapping("/export")
public void exportExcel(HttpServletResponse response) throws Exception {
// 读取 Excel 模板文件
Template template = freemarkerConfig.getTemplate("excel-template.ftl");
// 准备数据
List<User> users = prepareData();
// 创建 Excel 工作簿
Workbook workbook = new XSSFWorkbook();
// 渲染模板,生成 Excel 文件
Map<String, Object> model = new HashMap<>();
model.put("users", users);
StringWriter out = new StringWriter();
template.process(model, out);
InputStream is = new ByteArrayInputStream(out.toString().getBytes("UTF-8"));
workbook = WorkbookFactory.create(is);
// 设置响应头,告诉浏览器文件类型是 Excel
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-disposition", "attachment; filename=users.xlsx");
// 将 Excel 文件写入响应流中
OutputStream os = response.getOutputStream();
workbook.write(os);
os.flush();
os.close();
}
private List<User> prepareData() {
// TODO: 从数据库或其他来源读取数据
return Arrays.asList(
new User("Alice", 25, "https://example.com/alice.jpg"),
new User("Bob", 30, "https://example.com/bob.jpg"),
new User("Charlie", 20, "https://example.com/charlie.jpg")
);
}
private static class User {
private String name;
private int age;
private String photo;
public User(String name, int age, String photo) {
this.name = name;
this.age = age;
this.photo = photo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
}
}
```
在该控制器中,我们注入了 `Configuration` 类,它是 Freemarker 的配置类,用于加载 Excel 模板文件。在 `exportExcel` 方法中,我们先准备数据,然后通过 `template.process` 方法渲染模板,生成 Excel 文件。最后将 Excel 文件写入响应流中,浏览器会自动下载该文件。
4. 如果 Excel 模板中包含图片,那么需要在渲染模板之前,将图片下载到本地,然后将图片的本地路径传递给模板。例如:
```java
private String downloadImage(String imageUrl) throws Exception {
URL url = new URL(imageUrl);
String fileName = url.getFile();
String filePath = "images/" + fileName.substring(fileName.lastIndexOf("/") + 1);
FileUtils.copyURLToFile(url, new File(filePath));
return filePath;
}
@GetMapping("/export")
public void exportExcel(HttpServletResponse response) throws Exception {
// 读取 Excel 模板文件
Template template = freemarkerConfig.getTemplate("excel-template.ftl");
// 准备数据
List<User> users = prepareData();
// 下载图片并将本地路径传递给模板
for (User user : users) {
String photoPath = downloadImage(user.getPhoto());
user.setPhoto(photoPath);
}
// 创建 Excel 工作簿
Workbook workbook = new XSSFWorkbook();
// 渲染模板,生成 Excel 文件
Map<String, Object> model = new HashMap<>();
model.put("users", users);
StringWriter out = new StringWriter();
template.process(model, out);
InputStream is = new ByteArrayInputStream(out.toString().getBytes("UTF-8"));
workbook = WorkbookFactory.create(is);
// 设置响应头,告诉浏览器文件类型是 Excel
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-disposition", "attachment; filename=users.xlsx");
// 将 Excel 文件写入响应流中
OutputStream os = response.getOutputStream();
workbook.write(os);
os.flush();
os.close();
}
```
在该示例中,我们定义了一个 `downloadImage` 方法,用于下载图片,并将图片保存到 `images` 目录下。然后在 `exportExcel` 方法中,遍历用户列表,调用 `downloadImage` 方法下载每个用户的图片,并将本地路径传递给模板。注意,模板中使用的图片路径应该和下载到本地的路径一致。
阅读全文