文章目录
1.虚拟机使用docker安装minio
1.拉取镜像
docker pull minio/minio
2.运行
docker run --net=host \
--name minio \
-d --restart=always \
-e "MINIO_ACCESS_KEY=minioadmin" \
-e "MINIO_SECRET_KEY=minioadmin" \
-v /mydata/minio/data:/data \
-v /mydata/minio/config:/root/.minio \
minio/minio server /data --console-address ":9090" --address ":9000"
3.登录控制台
http://[虚拟机ip]:9090/login
使用上面设置的账号密码登录
2.使用minio
1.新建桶
设置桶名即可
创建完之后可以新建path
这里的逻辑和普通文件夹一样
文件就上传在这些路径中
自己定义一个模板文件使用POI填充之后导出到本地
docx如下
{{}}直接填充
{{@}}用于填充图片
2.新建用户
隐私全选即可
3.新建组
编辑好名字之后选择要加入组的用户(刚刚已经新建的用户)
3.新建服务
自己创建AccessKey和SecretKey
这里要记住结束之后可以下载,完成之后点击Done
4.整合spring boot
1.添加依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.2</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
基础依赖,springboot 和 mysql以及mybatis-plus
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.0</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.4.2</version>
<exclusions>
<exclusion>
<artifactId>okhttp</artifactId>
<groupId>com.squareup.okhttp3</groupId>
</exclusion>
</exclusions>
</dependency>
这些依赖是和minio相关的
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.1</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
这里的依赖是和后面对文件操作有关的
2.配置类
server:
port: 8999
app:
version: 0.0.1
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/init_test?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
username: root
password: admin
3.启动类
package com.poplar;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 主入口
*
* @author Poplar
* @date 2023/11/27
*/
@SpringBootApplication
@MapperScan("com.poplar.mapper")
public class AppMain {
public static void main(String[] args) {
SpringApplication.run(AppMain.class, args);
}
}
4.controller
package com.poplar.controller;
import com.poplar.query.StudentQuery;
import com.poplar.service.FileTemplateService;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
/**
* 文件模板控制器
*
* @author Poplar
* @date 2023/12/10
*/
@RestController
@AllArgsConstructor
@RequestMapping("/v1/file")
public class FileTemplateController {
private FileTemplateService fileTemplateService;
/**
* 文件下载
*
* @param studentQuery 查询条件
* @param httpServletResponse HTTP-Servlet响应
**/
@GetMapping("download-template")
public void getFileDownload(StudentQuery studentQuery, HttpServletResponse httpServletResponse) {
fileTemplateService.getFileDownload(studentQuery, httpServletResponse);
}
}
5.service
package com.poplar.service;
import com.poplar.query.StudentQuery;
import javax.servlet.http.HttpServletResponse;
/**
* 文件模板服务
*
* @author Poplar
* @date 2023/12/10
*/
public interface FileTemplateService {
/**
* 文件下载
*
* @param studentQuery 查询条件
* @param httpServletResponse HTTP-Servlet响应
**/
void getFileDownload(StudentQuery studentQuery, HttpServletResponse httpServletResponse);
}
6.serviceImpl
package com.poplar.service.imp;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.poplar.entity.Student;
import com.poplar.mapper.StudentMapper;
import com.poplar.query.StudentQuery;
import com.poplar.service.FileTemplateService;
import io.minio.GetObjectArgs;
import io.minio.ListObjectsArgs;
import io.minio.MinioClient;
import io.minio.Result;
import io.minio.messages.Item;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 文件模板服务实现
*
* @author Poplar
* @date 2023/12/10
*/
@Service
@RequiredArgsConstructor
public class FileTemplateServiceImpl implements FileTemplateService {
private final StudentMapper studentMapper;
private static final String DEFAULT_BUCKET = "xxx";//你创建的桶名
private static final String END_POINT = "http://虚拟机ip:9000";
private static final String ACCESS_KEY = "xxx";//上面设置的ACCESS-KEY
private static final String SECRET_KEY = "xxx";//上面设置的SECRET-KEY
@Override
public void getFileDownload(StudentQuery studentQuery, HttpServletResponse response) {
MinioClient minioClient = MinioClient.builder()
.endpoint(END_POINT)
.credentials(ACCESS_KEY, SECRET_KEY)
.build();
InputStream inputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment;filename=\""
+ UriUtils.encode(DateUtil.format(DateUtil.date(), "yyMMddHHmmss"), StandardCharsets.UTF_8) + ".docx\"");
ServletOutputStream servletOutputStream = response.getOutputStream();
bufferedOutputStream = new BufferedOutputStream(servletOutputStream);
//前缀就是自己上传文件的路径(不包含桶名)
Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(DEFAULT_BUCKET).prefix("tmpl/test/测试专用.docx").build());
if (results.iterator().hasNext()) {
Item item = results.iterator().next().get();
inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(DEFAULT_BUCKET).object(item.objectName()).build());
XWPFTemplate.compile(inputStream).render(initOutData(minioClient, studentQuery)).write(bufferedOutputStream);
bufferedOutputStream.flush();
bufferedOutputStream.flush();
}
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
if (bufferedOutputStream != null) {
IoUtil.close(bufferedOutputStream);
}
if (bufferedOutputStream != null) {
IoUtil.close(bufferedOutputStream);
}
if (inputStream != null) {
IoUtil.close(inputStream);
}
}
}
/**
* 初始化输出数据
*
* @param client 客户端
* @param studentQuery 查询
* @return {@link Map }<{@link String }, {@link Object }>
**/
private Map<String, Object> initOutData(MinioClient client, StudentQuery studentQuery) {
LambdaQueryWrapper<Student> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(Student::getAge, studentQuery.getAge());
List<Student> students = studentMapper.selectList(lambdaQueryWrapper);
Student student = students.get(0);
Map<String, Object> data = new HashMap<>();
data.put("name", student.getName());
data.put("id", student.getId());
if (student.getPath() != null) {
data.put("image", getPictureData(client, student.getPath(), 180, 150));
}
if (student.getSign() != null) {
data.put("sign", getPictureData(client, student.getSign(), 130, 130));
}
return data;
}
/**
* 获取图片数据
*
* @param client 客户端
* @param path 文件路径
* @param width 宽度(单位是px)自己调
* @param height 高度(单位是px)自己调
* @return {@link PictureRenderData }
**/
private PictureRenderData getPictureData(MinioClient client, String path, int width, int height) {
PictureRenderData pictureRenderData = null;
try {
InputStream inputStream = client.getObject(GetObjectArgs.builder().bucket(DEFAULT_BUCKET).object(path).build());
pictureRenderData = Pictures.ofStream(inputStream, PictureType.JPEG).size(width, height).create();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return pictureRenderData;
}
}
7.实体类
package com.poplar.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* 学生实体类
*
* @author Poplar
* @date 2023/11/28
*/
@Data
@TableName("init_tb")
public class Student {
/**
* 主键id
*/
private Integer id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 照片路径
*/
private String path;
/**
* 签名
*/
private String sign;
}
8.mapper
这里只是基础的查询
package com.poplar.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.poplar.entity.Student;
import org.apache.ibatis.annotations.Mapper;
/**
* 学生mapper接口
*
* @author Poplar
* @date 2023/11/28
*/
@Mapper
public interface StudentMapper extends BaseMapper<Student> {
}
9.自己封装的查询类
package com.poplar.query;
import lombok.Data;
/**
* 查询类
* @author Poplar
* @date 2023/12/10
*/
@Data
public class StudentQuery {
/**
* 主键id
*/
private Integer id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
}
5.启动&测试
启动项目之后使用postman测试
最终效果~