# diboot-file 使用说明
# 1、引入依赖
Maven
<dependency>
<groupId>com.diboot</groupId>
<artifactId>diboot-file-spring-boot-starter</artifactId>
<version>{latestVersion}</version>
</dependency>
2
3
4
5
6
或Gradle:
compile("com.diboot:diboot-file-spring-boot-starter:{latestVersion}")
file组件依赖一张表 upload_file ,用于存储文件/附件上传记录。该表将由diboot-file-starter初次加载时自动初始化。
如果使用diboot-devtools,还需要引入devtools相关依赖,可一键生成相关的上传下载的controller。
# 2、参数配置:
diboot-file组件有以下配置项,用于初始化及设置本地文件的存储起始目录(子目录会按分类与日期自动创建) 配置参数:
# 是否初始化sql,默认true,初始化之后(或非开发环境)可以关闭
diboot.component.file.init-sql=false
# 文件的本地存储路径
diboot.component.file.storage-directory=/myfile
# 上传大小
spring.servlet.multipart.max-request-size=10M
2
3
4
5
6
# 3. 使用说明
# 3.1 EasyExcel的增强优化
- 支持基于Java validator注解的自动数据校验:
@NotNull(message = "用户名不能为空") // 支持validation注解自动校验
@ExcelProperty(value = "状态")
private String username;
2
3
- 支持@ExcelBindDict注解自动转换字典 显示值->存储值
@ExcelBindDict(type = "USER_STATUS") // 自动转换数据字典 label->value
@ExcelProperty(value = "状态")
private String userStatus;
2
3
- 支持@ExcelBindField注解自动转换关联字段 name->id
@ExcelBindField(entity = Department.class, field = "name", setIdField = "parentId")
@ExcelProperty(value = "上级部门")
private String parentName;
// setIdField="parentId",将转换后的id值设置到parentId
@ExcelIgnore
private Long parentId;
2
3
4
5
6
7
- 支持@ExcelOption注解Excel写入单元格验证 — 下拉选项 (since v2.3.0)
@ExcelOption(dict = "USER_STATUS") // Excel写入单元格下拉选项(关联字典)
@ExcelBindDict(type = "USER_STATUS") // 自动转换数据字典 label->value
@ExcelProperty(value = "状态")
private String userStatus;
2
3
4
注:同时也支持自定义选项;
关联字典
优先级大于自定义选项
。
- 支持@ExcelComment表头批注 (since v2.4.0)
@ExcelComment("该列的批注说明")
@ExcelProperty(value = "状态")
private String userStatus;
2
3
轻量封装增强的Excel Data Listener 继承后只需要实现自定义校验 additionalValidate() 和 保存数据的 saveData() 方法。
注:.csv文件默认读取 UTF8 格式的文件,其它格式可能导致读取不到数据
动态表头的excel读取
DynamicHeadExcelListener
(since start)已知表头的excel读取
ReadExcelListener
(since v2.4.0)主要特色:
- 数据转换异常修补,避免数据丢失
- 异常数据导出,以及异常批注提示
ExcelModel
的处理基类,读取的Model需继承BaseExcelModel
,以便于 修补、批注- 固定头读取
FixedHeadExcelListener
(since start)since v2.4.0
继承了ReadExcelListener
- 分页读取
PageReadExcelListener
(since v2.4.0)其采用分批处理模式,解决了大数据量导入时内存占用过高问题
Excel写入处理还提供一些常用封装
以下简单介绍一下其使用,需要时根据实际使用情况自行指定处理程序
- Sheet页密码写入
LockedWriteHandler
,用于导出数据的列锁定// 此处以ID列为例,当需要锁定ID列不可被更改时, // 1. 需指定ContentStyle的locked=true,同时也需要在ExcelModel上指定ContentStyle的locked=false(因为默认锁定所有列) @ContentStyle(locked = BooleanEnum.FALSE) public class EntityExportModel { @ExcelProperty("ID") @ContentStyle(locked = BooleanEnum.TRUE) private Long id; } // 2. 指定锁密码写入程序 // web 导出 ExcelHelper.exportExcel(response, fileName, EntityExportModel.class, dataList, new LockedWriteHandler()); // 写入文件 ExcelHelper.write(outputStream, fileName, EntityExportModel.class, dataList, new LockedWriteHandler());
1
2
3
4
5
6
7
8
9
10
11
12
13
14注:
LockedWriteHandler
的默认密码为当天日期(yyyyMMdd),也可在构造中指定密码;当指定密码为空字符串时,会加锁,但无密码 - 固定表头
FreezePaneWriteHandler
// 动态固定表头(自动识别表头行数进行固定) new FreezePaneWriteHandler() // 指定固定列行(以下是固定两列三行) new FreezePaneWriteHandler(2, 3); // web 导出 ExcelHelper.exportExcel(response, fileName, EntityExportModel.class, dataList, new FreezePaneWriteHandler()); // 写入文件 ExcelHelper.write(outputStream, fileName, EntityExportModel.class, dataList, new FreezePaneWriteHandler());
1
2
3
4
5
6
7
8
9 - 单元格验证
OptionWriteHandler
(下拉选项)、批注写入CommentWriteHandler
;都已默认填加
- Sheet页密码写入
优化汇总校验错误的提示内容 校验失败提示示例:
{
"msg": "数据校验不通过: 第 5 行: XXX",
"code": 4005
}
2
3
4
# 3.2 常用文件处理封装
- 提供BaseFileController用于文件上传下载的Controller继承 使用示例:
//上传文件
@PostMapping("/upload")
public JsonResult upload(@RequestParam("file") MultipartFile file)throws Exception{
// 保存文件并创建UploadFile上传记录
return super.uploadFile(file, Dictionary.class);
}
// 下载文件
@GetMapping("/download/{fileUuid}")
public JsonResult download(@PathVariable("fileUuid")String fileUuid,HttpServletResponse response)throws Exception{
UploadFile uploadFile=uploadFileService.getEntity(fileUuid);
if(uploadFile==null){
return JsonResult.FAIL_VALIDATION("文件不存在");
}
// 下载
HttpHelper.downloadLocalFile(uploadFile.getStoragePath(), uploadFile.getFileName(), response);
return null;
}
// 自定义文件存储
@Override
protected<T> UploadFile saveFile(MultipartFile file,Class<T> entityClass)throws Exception{
// 自定义文件存储,默认本地存储
return super.saveFile(file ,entityClass);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- 提供BaseExcelFileController用于Excel导入导出类的Controller继承 使用示例:
// 预览excel数据
@PostMapping("/preview")
public JsonResult preview(@RequestParam("file") MultipartFile file)throws Exception{
return super.excelPreview(file, Entity.class);
}
// 预览无校验错误后 提交
@PostMapping("/previewSave")
public<T> JsonResult previewSave(@RequestParam("uuid") String uuid)throws Exception{
return super.excelPreviewSave(uuid);
}
// 无预览 直接导入
@PostMapping("/upload")
public<T> JsonResult upload(@RequestParam("file") MultipartFile file)throws Exception{
return super.uploadExcelFile(file, Entity.class);
}
// 获取表头,用于动态导出列 (since v2.4.0)
@GetMapping("/tableHead")
public JsonResult tableHead() {
return JsonResult.OK(ExcelHelper.getTableHead(EntityExportModel.class));
}
// 导出数据 【案例一:普通导出;优势:耗时短,缺点:数据量大时耗内存】
@GetMapping("/export")
public JsonResult export(EntityDTO queryDto, @RequestParam(value = "columns", required = false) List<String> columns,
HttpServletResponse response) throws Exception{
QueryWrapper<Entity> queryWrapper = super.buildQueryWrapper(queryDto);
List<EntityVO> voList = entityService.getViewObjectList(queryWrapper, null, EntityVO.class);
if (V.isEmpty(voList)) {
return new JsonResult(Status.FAIL_OPERATION, "数据列表为空,导出失败");
}
String fileName = "数据列表导出_" + D.today() + ".xlsx";
List<EntityExportModel> dataList = this.entityList2ExcelList(voList);
ExcelHelper.exportExcel(response, fileName, EntityExportModel.class, columns, dataList);
return null;
}
// 导出数据 【案例二:分页导出;优势:大数据量导出时节省内存,缺点:多次查询耗时】(since v2.4.0)
@GetMapping("/export")
public JsonResult export(EntityDTO queryDto, @RequestParam(value = "columns", required = false) List<String> columns,
HttpServletResponse response) throws Exception{
QueryWrapper<Entity> queryWrapper = super.buildQueryWrapper(queryDto);
if (entityService.getEntityListCount(queryWrapper) == 0) {
return new JsonResult(Status.FAIL_OPERATION, "数据列表为空,导出失败");
}
String fileName = "数据列表导出_" + D.today() + ".xlsx";
// 创建分页
Pagination pagination = new Pagination();
pagination.setPageSize(BaseConfig.getBatchSize());
ExcelHelper.exportExcel(response, fileName, EntityExportModel.class, columns, () -> {
List<EntityVO> voList = entityService.getViewObjectList(queryWrapper, pagination, EntityVO.class);
pagination.setPageIndex(pagination.getPageIndex() + 1);
return this.entityList2ExcelList(voList);
});
return null;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
注:动态导出列前端参考
export组件
# 3.3 其他常用文件处理相关工具类
// 保存上传文件至本地
FileHelper.saveFile(MultipartFile file, String fileName)
// 下载本地文件
HttpHelper.downloadLocalFile(String localFilePath, String exportFileName, HttpServletResponse response)
// 下载网络文件至本地
HttpHelper.downloadHttpFile(String fileUrl, String targetFilePath)
// 图片保存,压缩,加水印等 (需依赖Thumbnails组件)
ImageHelper.saveImage(MultipartFile file, String imgName)
ImageHelper.generateThumbnail(String sourcePath, String targetPath, int width, int height)
ImageHelper.addWatermark(String filePath, String watermark)
// zip压缩
ZipHelper.zipFile(String srcRootDir, File file, ZipOutputStream zos, String... matchKeyword)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 4 样例参考 - diboot-file-example (opens new window)
使用过程中遇到问题,可加群交流。