# diboot-file 使用说明

## 1、引入依赖
Gradle:
~~~gradle
compile("com.diboot:diboot-file-spring-boot-starter:{latestVersion}")
~~~
或Maven
~~~xml
<dependency>
    <groupId>com.diboot</groupId>
    <artifactId>diboot-file-spring-boot-starter</artifactId>
    <version>{latestVersion}</version>
</dependency>
~~~

diboot-file会自动依赖以下jar包，无需重复引入：
* commons-fileupload: 1.4
* easyexcel:2.x
* okhttp:4.7.x
* thumbnailator: 0.4.9 (图片压缩，不需要可剔除)
* easy-captcha: 1.6.x (验证码，不需要可剔除)

> file组件依赖一张表 upload_file ，用于存储文件/附件上传记录。该表将由diboot-file-starter初次加载时自动初始化。

> 如果使用diboot-devtools，还需要引入devtools相关依赖，可一键生成相关的上传下载的controller。

## 2、参数配置：
diboot-file组件有以下配置项，用于初始化及设置本地文件的存储起始目录（子目录会按分类与日期自动创建）
配置参数:
~~~properties
# 是否初始化sql，默认true，初始化之后可以关闭
diboot.component.file.init-sql=false
# 文件的本地存储路径
files.storage.directory=/myfile
~~~

## 3. 使用说明
### 3.1 EasyExcel的增强优化

* 支持基于Java validator注解的自动数据校验：
~~~java 
@NotNull(message = "用户名不能为空") // 支持validation注解自动校验
@ExcelProperty(value = "状态", index = 1)
private String username;
~~~

* 支持@ExcelBindDict注解自动转换字典显示值-存储值

@ExcelBindDict注解使用示例：
~~~java
@ExcelBindDict(type = "USER_STATUS")   // 自动转换数据字典 label-value
@ExcelProperty(value = "状态", index = 2)
private String userStatus;
~~~

* 支持@ExcelBindField注解自动转换关联字段name-id

@ExcelBindField注解使用示例：
~~~java
@ExcelBindField(entity = Department.class, field = "name", setIdField = "parentId")
@ExcelProperty(value = "上级部门", index = 0)
private String parentName;

// setIdField="parentId"，将转换后的id值设置到parentId
@ExcelIgnore
private Long parentId;
~~~

* 轻量封装增强的Excel Data Listener
继承后只需要实现自定义校验additionalValidate() 和 保存数据的saveData()方法。
~~~
// 适用于已知固定表头的excel读取
FixedHeadExcelListener

// 适用于动态表头的excel读取
DynamicHeadExcelListener
~~~

* 优化汇总校验错误的提示内容
校验失败提示示例：
~~~json
{
    "msg": "数据校验不通过: 1行3列: '测试' 无匹配字典定义; 2行: 姓名不能为空，职位长度不能超过10",
    "code": 500
}
~~~

### 3.2 常用文件处理封装

* 提供BaseFileController用于文件上传下载的Controller继承
使用示例：
~~~java
    //上传文件
    @PostMapping("/upload")
    public JsonResult upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception{
        // 保存文件并创建UploadFile上传记录
        return super.uploadFile(file, Dictionary.class, request);
    }

    // 下载文件
    @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(), "导出文件.txt", response);
        return null;
    }
    
    // 自定义文件存储
    @Override
    protected <T> UploadFile saveFile(MultipartFile file, Class<T> entityClass, HttpServletRequest request) throws Exception {
        // 自定义文件存储，默认本地存储
        return super.saveFile(file, entityClass, request);
    }
~~~

* 提供BaseExcelFileController用于Excel导入导出类的Controller继承
使用示例：
~~~java
    //预览excel数据
    @PostMapping("/preview")
    public JsonResult preview(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception {
        return super.excelPreview(file, request);
    }

    //预览无校验错误后 提交
    @PostMapping("/previewSave")
    public <T> JsonResult previewSave(@RequestParam("previewFileName")String previewFileName, @RequestParam("originFileName")String originFileName, HttpServletRequest request) throws Exception {
        return super.excelPreviewSave(Department.class, previewFileName, originFileName, request);
    }

    //无预览 直接导入
    @PostMapping("/import")
    public <T> JsonResult upload(@RequestParam("file")MultipartFile file, HttpServletRequest request) throws Exception {
        return super.uploadExcelFile(file, Department.class, request);
    }
    
~~~

### 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)
~~~


## 4 样例参考 - [diboot-file-example](https://github.com/dibo-software/diboot-example/tree/master/diboot-file-example)

> 使用过程中遇到问题，可加群交流。