utils-api 使用说明文档
入门和安装
📚简介
utils-api是为了将大部分常用工具都集成到一起,为了让调用者更方便的引用,也为了让管理者更方便的管理而产生的项目,通过静态方法封装,降低相关API的学习成本,提高工作效率
🎁utils-api名称的由来
utils-api … … 可能就是单纯的字面意思吧~
🍺如何改变加入此项目的优化
公司内部可以查看 http://192.168.100.2/yanfabu/code/zz05/code22/java/xpaas-utils
公司外部现不支持~
🛠️包含组件
模块 | 介绍 |
---|---|
ExcelUtils | Excel表格导出 之前的项目用的大多是此工具 |
ExcelUtilsNew | Excel表格导入、导出、下载模板方法 |
FileUtils | 以EasyPoi 替换数据 导出 word 可以支持传入合并信息的那种导出 |
DateUtil | 时间类工具 继承了hutool.DateUtil 并写入了自己的 优化方法 |
EmptyUtils | 通用判空工具类 |
ComUtils | 一些公共的方法 |
MapUtils | Map工具类 |
OSinfoUtils | 关于操作系统工具类 |
HttpServletRequestUtil | 关于HttpServletRequest 这个参数的一些util,比如获取body里对的参数信息 |
GitLabApiExample | 通过Api操作gitLab某个项目的工具 |
IUtilService | 契合公司内部使用的注入型工具类,通常做一些辅助fegin接口调用的工具,校验工具等 |
AssignUtilService | 做一些给实体类二次封装公共属性的方法的注入型工具类,公司内部假审批都用这个做的封装 |
ApprovalUtil | 处理关于审批系列的操作工具类比如:通过审批状态获取审批状态字符名 |
📦安装
🍊maven
在项目的pom.xml的dependencies中加入以下内容:
<!-- 在项目 service 包和 entity 包中引入以下依赖即可 版本号可随更新日志自行决定使用-->
<dependency>
<groupId>com.xpaas</groupId>
<artifactId>xpaas-utils-api</artifactId>
<version>1.0.5</version>
</dependency>
<!-- 此项目需要引用hutool 版本大于等于 5.7.9-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.9</version>
</dependency>
<!-- 如果用到此项目 则最少需要以下版本支持 easypoi -->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.1.0</version>
</dependency>
更新日志
1.0.5
【增加】增加一点时间格式的校验
【新增】导入校验增加不只允许传入整数的校验
【新增】增加导出转换方法IUtilService 里的exportSetParameterValue(Object paramValue) 支持注解 ExportSetProperty和ExcelPropertyTemplate添加自定义转换器convert 可以自己做自己的实现类来进行转换
【优化】取消导出类方法返回值泛型需要继承TenantEntity类的要求
【版本】将core和admin升级到1.6.3
【新增】自定义格式限制,传入正则表达式,在此名单内,则进行提示(相当于黑名单)
【优化】优化提示语及部分默认值
【优化】优化导入map判空逻辑
【新增】导入时行号获取逻辑优化,如果遇到空行,则主动加一,与展示相同 【新增】导入空行取消导入,默认值设置为20行(当空行达到20行时,结束导入)
【新增】导出及模板增加列对齐方式 注解传入verifier值 默认是居中对齐
【新增】导入校验现支持自定义校验类的拓展,针对导入的单元格数据进行自定义校验,支持三种继承方法,有三种传参格式
1.0.4
【新增】导入校验现支持单位查询增加机构代码做危机校验的格式,但需要传入机构代码值的对应的字段 注解属性为auxiliaryFiledName且这个字段不能为空 支持多选
【新增】导入校验现支持自定义校验类的拓展,针对导入的单元格数据进行自定义校验,后续会持续优化
【新增】封装一个关于高级搜索的字段名与数据库名不一样,导致报数据库没有这个字段的错误。 传入的key名字 转换成传入的新key 就是数据库有的那个字段名
【新增】将Query里报错的字段(数据库不存在的字段)替换成存在的 或者直接删除
1.0.3
【优化】去掉导入错误提示语最后的 (请重新上传!)语句
【优化】重载一个readExcel方法
【优化】时间转换工具类的支持格式
【新增】支持导出设置列宽
【新增】ExcelUtilsNew.exportTemplateByBtList()方法 支持导出模板兼容源代码生成的list《字段名》的方式 【新增】导出模板支持 K_V自定义字典值作为下拉列表
1.0.2
【优化】verifyParameterOne 校验长度提示语
【新增】DateUtil 继承了 cn.hutool.core.date.DateUtil 调用者可以用更多的方法了
【新增】ExcelUtilsNew的导入方法返回的实体类ExcelDate 增加了字段isSuccess 用来提示调用者,导入数据是否全部通过预设校验
【新增】utilService校验字典和k_v类型增加多选情况
【新增】增加正则枚举类和验证器
1.0.1
优化部分bug及代码逻辑
项目起源1.0.0
2023/3/22 18:02 项目初始化
🍑工具集
ExcelUtils
ExcelUtilsNew
导入
方法
注解介绍
@ExcelPropertyNotNull
/**
* 判断该属性再导入导出时,不为空,但是不是为了切面用,是为了手动调用方法去区分判断用
* IUtilService.verifyParameterNotNull()方法
*
* @author liyunkai
* @since 2023-02-17
*/
public @interface ExcelPropertyNotNull {
/**
* 提示语
*/
String value() default "";
/**
* 如果选了60 查字典的,则必须给这个赋值,否则会一直查不到
* @return
*/
String dictCode() default "";
/**
* 如果类型为需要辅助字段协助判断 如(STR_DEPT_AND_JGBH)格式 则需要传入这个值,进行辅助验证
* 并且,如果辅助信息不能为空
* @return
*/
String auxiliaryFiledName() default "";
/**
* 是否必填
* @return
*/
boolean request() default true;
/**
* 如果加上这个值,则可以给传入的字段附上查出来的值,比如之前是姓名,可以把id赋给自己或另一个字段
* @return
*/
String setValueToPrpName() default "";
/**
* 类型
* 10.为正常字符串 只检查为空
* 20.纯数字的字符串 检查为空 同时判断为纯数字才可以
* 30.为时间字符串 检查为空 同时判断为时间格式 yyyy-MM-dd 才可以
* 31.为时间字符串 检查为空 同时判断为时间格式 yyyy-MM-dd HH:mm 才可以
* 32.为时间字符串 检查为空 同时判断为时间格式 yyyy-MM-dd HH:mm:ss 才可以
* 33.为时间字符串 检查为空 同时判断为时间格式 yyyy 才可以
* 40.为查询人员信息的 检查为空 同时判断为查不到人员信息也返回报错信息
* 50.为查询单位信息的 检查为空 同时判断为查不到单位信息也返回报错信息
*/
NotNullEnum type() default NotNullEnum.STR;
/**
* 如果类型为自定义(regex)格式 则需要传入这个值
* @return
*/
String regex() default "";
/**
* 如果类型为自定义(regex)格式 此项可作为提示语传入
* @return
*/
String regexTipsMsg() default "不符合数据格式要求!";
/**
* 如果类型为自定义(k_v)格式 则需要传入这个值<br/>
* 规定传入值为键值对 映射关系为 <b>[”枚举1_1“,”枚举2_2“...]</b><br/>
* 也支持只传如 <b>[”枚举1”,”枚举2”,。。。]</b><br/>
* 可以用过 【v】 将 【k】 的值导出转换
* 若是设置了setValueToPrpName 且是k_v 可以将转化后(K)的值进行赋值
* @return
*/
String[] k_v() default {};
/**
* 字符长度限制最低值
* @return
*/
long len_min() default 0;
/**
* 字符长度限制最高值
* @return
*/
long len_max() default Short.MAX_VALUE;
/**
* 自定义规则校验类e <br>
* 扩展器e <br>
* 返回的ExcelDate 如果通过,切记要将success设置为true 不通过则为false <br>
* errmsg是错误提示语,可以不写e <br>
* data 是校验后的数据 赋值后可与现有参数做替换 <br>
* @return ExcelDate
*/
Class<? extends IExcelValidation> verifier() default ExcelValidationImpl.class;
}
注解使用
实体类
//需要导入进行校验非空,直接传入标题名即可
@ExcelProperty(value = "校验非空")
@ExcelPropertyNotNull("校验非空")
private String test;
//所有的类型均支持加入 setValueToPrpName = "filedName" 值,当你写入了这个值,那么意味着,导入转换后的值,将赋值给传入的字段上 如下 不写这个 则不会赋值 切记! 切记! 切记!
//当然,某些时候不需要校验为空,是为了单纯的校验别的格式,那就传如 request = false
@ExcelProperty(value = "普通校验")
@ExcelPropertyNotNull(request = false, value = "普通校验" , setValueToPrpName = "test")
private String test;
//如果是数字格式?那有两种,1.支持小数点 STR_NUMBER 2.纯整数 STR_NUMBER_INT
@ExcelProperty(value = "数字格式")
@ExcelPropertyNotNull(value = "数字格式", type = NotNullEnum.STR_NUMBER)
private String test;
//如果是最让人头疼的时间格式? 好吧,为了这个事,我写了22种正则表达式及格式,兼容了能遇到的好多时间格式,后期再添加
@ExcelProperty(value = "时间格式")
@ExcelPropertyNotNull(value = "时间格式", type = NotNullEnum.STR_DATE*) *的意思是,还有好多
private String/Date test;
//如果是单位格式,需要将单位名称转换为id的 支持多选填入哦。 导入的名称是 (单位1,单位2,单位3...) ,号间隔即可
@ExcelProperty(value = "单位格式")
@ExcelPropertyNotNull(value = "单位格式", type = NotNullEnum.STR_DEPT)
private String test;
//如果是单位格式,需要将单位名称转换为id的 但是又需要辅助信息进行双重保证唯一性的,如需要另一个字段代表机构编号,那就需要用到新的成员了,auxiliaryFiledName = "" 用来指定另一个字段获取辅助信息 支持多选填入哦。 导入的名称是 (单位1,单位2,单位3...) ,号间隔即可
@ExcelProperty(value = "单位格式")
@ExcelPropertyNotNull(value = "单位格式", type = NotNullEnum.STR_DEPT_AND_JGBH, auxiliaryFiledName = "jgbh_filed")
private String test;
//如果是字典格式,需要将指定code字典的信息查出来,看导入的信息是否在此字典中,那就需要额外传入 code = "code" 支持多选填入哦。 导入的名称是 (字典1,字典2,字典3...) ,号间隔即可
@ExcelProperty(value = "字典格式")
@ExcelPropertyNotNull(value = "字典格式", type = NotNullEnum.STR_DICT, code = "code")
private String test;
//如果是单选格式,大多时候,会有单选按钮,用来代表是或者不是 ,那么此类就但提出来了,作为一个常用项,但是 代表的值为【1是,0否】如果满足不了你,那么继续看!
@ExcelProperty(value = "单选格式")
@ExcelPropertyNotNull(value = "单选格式", type = NotNullEnum.STR_RADIO)
private String test;
//如果是K_V格式,但是大多数情况下,字典或者单选框 是跟前端约定好的,写死的,那怎么办呢,那就指定key_value咯,这两种传参格式想必聪明的你也可以看出来,限制导入后的数据不在这个值的范围内则进行提醒,如果在,则做转换,若是设置了setValueToPrpName 且是k_v 可以将转化后(v)的值进行赋值
@ExcelProperty(value = "K_V格式")
@ExcelPropertyNotNull(value = "K_V格式", type = NotNullEnum.STR_K_V, k_v = {"k1_v1", "k2_v1", "k3_v1"})
@ExcelPropertyNotNull(value = "K_V格式", type = NotNullEnum.STR_K_V, k_v = {"k1", "k2", "k3"})
private String test;
//如果是正则格式,还有很多时候,自定义校验,比如车牌号,手机号,身份证号,等等。。。那我们就需要正则表达式来约定我们用户导入的格式进行限制,当然也可以传入错误提示语(regexTipsMsg),进行自定义提示, 不填写 则默认为 【不符合数据格式要求】
//当然 如果您觉得正则太多不好找,我也为你贴心的准备了 RegexEnum 来帮你确定大多数常用的格式验证进行使用
@ExcelProperty(value = "正则格式")
@ExcelPropertyNotNull(value = "正则格式", type = NotNullEnum.STR_REGEX, regex = "^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$", regexTipsMsg = "手机号码格式不正确")
private String test;
//如果是正则格式,什么,黑名单 行吧,给你提供了一个类型,专门用来放正则黑名单,把你不希望用户输入的符号 都写在里边吧
@ExcelProperty(value = "黑名单正则格式")
@ExcelPropertyNotNull(value = "黑名单正则格式", type = NotNullEnum.STR_REGEX_FAN, regex = ",*[!@#S%&*()_1-+=<>?: \"|,. /;\" [ ]! #¥%..&*()- -+=》?:[、J+*.*", regexTipsMsg = "不能包含特殊字符")
private String test;
//以上校验格式统统不能达到您的使用要求,哎,废了我几万脑细胞,又给您提供了一个自定义校验类,您可以重写这个类中的方法,进行客制化校验,还可以转换导入的值赋值给当前字段 只需要 你的类继承 ExcelValidationImpl 或者实现 IExcelValidation接口 进行重写操作,并结合相应的type来做校验即可
//只是校验此字段
@ExcelProperty(value = "自定义校验")
@ExcelPropertyNotNull(request = false,value = "自定义校验",type = NotNullEnum.STR_CLASS)
private String test;
//需要结合辅助信息进行校验
@ExcelProperty(value = "自定义校验_结合辅助字段")
@ExcelPropertyNotNull(request = false,value = "自定义校验_结合辅助字段",type = NotNullEnum.STR_CLASS_AND_FZ,verifier = ExcelValidationNewImpl.class,auxiliaryFiledName = "custom")
private String test;
//需要整行数据来帮助你进行校验
@ExcelProperty(value = "自定义校验_结合行信息")
@ExcelPropertyNotNull(request = false,value = "自定义校验_结合行信息",type = NotNullEnum.STR_CLASS_AND_ROW,verifier = ExcelValidationNewImpl.class)
private String test;
实现类
//设置好注解,那么接下来就好解决了,我写了几种重载的方法供您选择,从简入繁说 不过返回的参数都是ExcelDate 类 其中
//1.ExcelDate.getDataList() 为导入后的list 并转换成了你使用的类
//3.ExcelDate.isSuccess() 为导入是否成功(只要有一个字段不通过校验,则为false,都通过则为true)
//2.ExcelDate.getErrMsg() 为导入检验中,收集的个各种错误信息 如:第2行【单位名称】的值【单位1】不存在
//其中有规则如下:
//1.导入数据中有空行的话,超过20行则直接结束导入,返回数据
//2.导入数据中有空行数据,直接掠过,不予转换成实体类,避免空行数据影响,全都为空,则会抛出 “传入文件不能为空!” 信息
// 方法一
@PostMapping("/import")
public void import(MultipartFile file) {
//传入file 和实体类class 即可, 但是需要注意,此方法会主动进行校验并抛出校验失败的信息 errMsg 直到所有字段通过校验后,则继续往下执行
ExcelDate<DemoEntity> excelDate = ExcelUtilsNew.readExcel(file, DemoEntity.class);
//那如果不想抛出errMsg,想结合你的for里定义的自定义校验信息一起抛出呢,也简单 加个 false就好了
ExcelDate<DemoEntity> excelDate = ExcelUtilsNew.readExcel(file, DemoEntity.class, false);
//帮你写了个抛出校验
if(!excelDate.isSuccess() || errList.size()>0){
return R.fail((StringUtil.isNotBlank(s) ? s : "") + " "+(errList.size()>0 ? errList.toString() : ""));
}
//如果有子表,或者想单独的去导入表中其中某一个sheet页的数据? 那就传入 页数 用下角标算法 第一页是0 第二页是1...
//是否主动抛出异常信息参数往后移
ExcelDate<DemoEntity> excelDate = ExcelUtilsNew.readExcel(file, DemoEntity.class, 0);
ExcelDate<DemoEntity> excelDate = ExcelUtilsNew.readExcel(file, DemoEntity.class, 0, false);
// TODO 接下来你就可以做你想做的一些操作了
Lisr<DemoEntity> list = ExcelDate.getDataList();
for (DemoEntity demoEntity : list) {
//详细操作。。。
}
demoService.saveBatch(list)
}
// 方法二
//如果你已经有了很多的校验,还不想用我的导入方法,那你也可以选择,手动校验
@Autowired
IUtilService utilService;
@PostMapping("/import")
public void import(MultipartFile file) {
Lisr<DemoEntity> list = ExcelDate.getDataList();
// TODO 方法一、 此处调用验证数据有效
String s = utilService.verifyParameterNotNull(list);
if (StringUtil.isNotBlank(s)){
return R.fail(s);
}
// TODO 方法二、 在你的for循环中传入你的实体类,需要传入行号,来进行细致提示
for (DemoEntity demoEntity : list) {
//校验数据
String s = utilService.verifyParameterNotNull(rowNumber,demoEntity);
//你的其余详细操作。。。
}
demoService.saveBatch(list)
}
// 方法三
//如果你跟我一样懒,你可以在设置完所有字段的校验格式之后,全部交给AOP来完成操作 只需要使用 ExcelImportService
@PostMapping("/import")
//value 需要转换成的实体类 必填
//isAdd 是否进行保存操作 选填 默认不保存
//serviceClass 需要做保存操作的service类 选填 如果 isAdd 为true 则必填
//sheetNum 选择导入第几个sheet页 选填 默认0
@ExcelImportService(value = DemoEntity.class, isAdd=true, serviceClass = IGwcService.class, sheetNum = 0)
public void import(MultipartFile file) {
//是的,里边什么都不用写
}
导出
方法
如果导出需要转换kay_value的值,可以调用此方法之前,调用 IUtilService 里的 exportSetParameterValue(Object paramValue)
方法并借助
@ExportSetProperty 注解来约定导出需要转换的值
exportExcel
/**
* Excel表格导出
*
* @param response HttpServletResponse对象
* @param excelData Excel表格的数据,封装为List<List<String>>
* @param sheetName sheet的名字
* @param fileName 导出Excel的文件名
* @param columnWidth Excel表格的宽度,建议为15
* @throws IOException 抛IO异常
*/
exportExcel(HttpServletResponse response,
List<List<String>> excelData,
String sheetName,
String fileName,
List<int[]> merge,
int columnWidth
)
注解介绍
@ExportSetProperty
/**
* 判断该属性再导入导出时,不为空,但是不是为了切面用,是为了手动调用方法去区分判断用
* IUtilService.verifyParameterNotNull()方法
*
* @author liyunkai
* @since 2023-02-17
*/
public @interface ExportSetProperty {
/**
* 提示语
*/
String value() default "";
/**
* 如果选了60 查字典的,则必须给这个赋值,否则会一直查不到
* @return
*/
String dictCode() default "";
/**
* 如果加上这个值,则可以给传入的字段附上查出来的值,比如之前是姓名,可以把id赋给自己或另一个字段
* @return
*/
String setValueToPrpName() default "";
/**
* 类型
* 10.为正常字符串 只检查为空<br/>
* 20.纯数字的字符串 检查为空 同时判断为纯数字才可以<br/>
* 30.为时间字符串 检查为空 同时判断为时间格式 yyyy-MM-dd 才可以<br/>
* 31.为时间字符串 检查为空 同时判断为时间格式 yyyy-MM-dd HH:mm 才可以<br/>
* 32.为时间字符串 检查为空 同时判断为时间格式 yyyy-MM-dd HH:mm:ss 才可以<br/>
* 33.为时间字符串 检查为空 同时判断为时间格式 yyyy 才可以<br/>
* 以此类推。。。<br/>
* 60.为查询单位信息的 检查为空 同时判断为查不到单位信息也返回报错信息<br/>
* 70.为查询字典信息的 检查为空 同时判断为查不到人员信息也返回报错信息<br/>
* 以此类推。。。<br/>
*/
NotNullEnum type() default NotNullEnum.STR;
/**
* 如果类型为自定义(k_v)格式 则需要传入这个值<br/>
* 规定传入值为键值对 映射关系为 <b>[”枚举1_1“,”枚举2_2“...]</b><br/>
* 也支持只传如 <b>[”枚举1”,”枚举2”,。。。]</b><br/>
* 限制导入后的数据不在这个值的范围内则进行提醒,如果在,则做转换,若是设置了setValueToPrpName 且是k_v 可以将转化后(v)的值进行赋值
* @return
*/
String[] k_v() default {};
/**
* <font color="#ff5f56">
* <p>
* 暂时不启用
* </p>
* </font>
*
* 设置背景颜色
*/
ColorEnum cellColor() default ColorEnum.AUTOMATIC;
/**
* <font color="#ff5f56">
* <p>
* 暂时不启用
* </p>
* </font>
*
* 设置背景自定义颜色 如果设置了,则优先使用此颜色
* 可以通过 ColorEnum.getIntFromColor(255,255,255) 来设置颜色
*/
int cellDIYColor() default -1;
/**
* 标记导出excel列的日期格式(如果字段不是日期则为空)
*/
DateEnum dateFormat() default DateEnum.NULL;
/**
* 设置每列的列宽 只需要传汉字的个数,大概就是 (传入数 * 1个字) 那么宽 不传就是自适应
*/
int colWidth() default -1;
/**
* 设置每列的对齐方式 默认是居中
*/
HorizontalAlignment colAlign() default HorizontalAlignment.CENTER_SELECTION;
/**
* 自定义转换器 <br>
* 转换器 <br>
* 返回的Object <br>
* Object 是校验后的数据 赋值后可与现有参数做替换 <br>
* @return ExcelDate
*/
Class<? extends IExcelConvert> convert() default ExcelConvertImpl.class;
}
注解使用
实体类
//需要导出的字典类型
@ExcelProperty(value = "字典类型")
@ExportSetProperty(
value = "字典类型", //设置导出的标题名称,如果由此值,则用此名称,没有则用上个注解的名称
type = NotNullEnum.STR_DICT, //设置导出的type 默认可以不传
dictCode = "ditc_code", //选了字典的type,则必须给这个赋值,否则会查不到
colWidth = 8, //设置导出的标题列的列宽 大概就是 (传入数 * 1个字) 那么宽 不传就是自适应
dateFormat = DateEnum.DATE_TIME, //设置导出excel列的日期格式
colAlign = HorizontalAlignment.RIGHT, //设置导出的标题列的对齐方式 默认是居中
convert = ExcelConvertImpl.class //添加自定义转换器 可以自己做自己的实现类来进行转换 需要配合 IUtilService 里的 exportSetParameterValue(Object paramValue) 方法进行转换
)
private String test;
//需要导出的自定义字典K_V类型
@ExcelProperty(value = "K_V类型")
@ExportSetProperty(
value = "K_V类型", //设置导出的标题名称,如果由此值,则用此名称,没有则用上个注解的名称
type = NotNullEnum.STR_K_V, //设置导出的type 默认可以不传
k_v = {"mj11_1", "mj22_1", "mj33_1"}, //选了k_v的type,则必须给这个赋值,否则会查不到
colWidth = 8, //设置导出的标题列的列宽 大概就是 (传入数 * 1个字) 那么宽 不传就是自适应
dateFormat = DateEnum.DATE_TIME, //设置导出excel列的日期格式
colAlign = HorizontalAlignment.RIGHT, //设置导出的标题列的对齐方式 默认是居中
convert = ExcelConvertImpl.class //添加自定义转换器 可以自己做自己的实现类来进行转换 需要配合 IUtilService 里的 exportSetParameterValue(Object paramValue) 方法进行转换
)
private String test;
实现类
@Autowired
IUtilService utilService;
public void export(HttpServletResponse response) {
ArrayList<DemoEntity> list2 = new ArrayList<DemoEntity>();
DemoEntity demoEntity = new DemoEntity();
demoEntity.setSpr("审批ren");
demoEntity.setSpzt("2023-04-13 08:19:16.483");
demoEntity.setSpyj("auditIdsa:\r\n①您的测试一开始\r\n②测试不通过,快回来造BUG;\r\ntIdsauditIdsauditIdsauditIdsauditIdsauditIdsauditIdsauditIdsauditIdsauditIds");
demoEntity.setSprData("mj22");
demoEntity.setAuditIds("3");
list2.add(demoEntity);
//TODO 此处调用转换方法或者自己for进行转换数据
utilService.exportSetParameterValue(list2);
ExcelUtil.export(response, "fileName", "sheetName", columnFiledNames, list2, DemoEntity.class);
}
下载模板
方法
exportTemplate()
需要配合注解 ExcelPropertyTemplate 使用,在调用此方法时,会将实体类中所有带有@ExcelPropertyTemplate注解的字段导出【使用方法见下文】并支持导出下拉框及转换key_value的值
//传参: 传入所需要导出的 单个实体类 所需要导出的类 模板名称支持为空
exportTemplate(T paramValue, HttpServletResponse response, Class<T> clazz), String mbmc)
exportTemplateByBtList()
当然了,公司框架生成的是需要传入索要导出的字段名,那我也要兼容,所以写了这个方法,供大家选择,如果需要用下拉框,则还是需要@ExcelPropertyTemplat注解配合【使用方法见下文】
//传参: 传入所需要导出的 List<实体类>做示例数据用 所需要导出的字段名btList 模板名称支持为空
exportTemplateByBtList(T paramValue, HttpServletResponse response, List<String> btList, String mbmc)
//传参: 传入所需要导出的 List<实体类>做示例数据用 所需要导出的类 所需要导出的字段名btList
exportTemplateByBtList(List<T> paramValues, HttpServletResponse response, Class<T> clazz, List<String> btList)
//传参: 传入所需要导出的 List<实体类>做示例数据用 所需要导出的字段名btList 模板名称支持为空
exportTemplateByBtList(List<T> paramValues, HttpServletResponse response, Class<T> clazz, List<String> btList, String mbmc)
注解介绍
@ExcelPropertyTemplate
/**
* 判断该属性再导入导出时,不为空,但是不是为了切面用,是为了手动调用方法去区分判断用
* IUtilService.verifyParameterNotNull()方法
*
* @author liyunkai
* @since 2023-02-17
*/
public @interface ExcelPropertyTemplate {
/**
* 提示语
*/
String value() default "";
/**
* 如果选了60 查字典的,则必须给这个赋值,否则会一直查不到
*
* @return
*/
String dictCode() default "";
/**
* 类型
* 10.为正常字符串 只检查为空<br/>
* 20.纯数字的字符串 检查为空 同时判断为纯数字才可以<br/>
* 30.为时间字符串 检查为空 同时判断为时间格式 yyyy-MM-dd 才可以<br/>
* 31.为时间字符串 检查为空 同时判断为时间格式 yyyy-MM-dd HH:mm 才可以<br/>
* 32.为时间字符串 检查为空 同时判断为时间格式 yyyy-MM-dd HH:mm:ss 才可以<br/>
* 33.为时间字符串 检查为空 同时判断为时间格式 yyyy 才可以<br/>
* 以此类推。。。<br/>
* 60.为查询单位信息的 检查为空 同时判断为查不到单位信息也返回报错信息<br/>
* 70.为查询字典信息的 检查为空 同时判断为查不到人员信息也返回报错信息<br/>
* 以此类推。。。<br/>
*/
NotNullEnum type() default NotNullEnum.STR;
/**
* 如果类型为自定义(k_v)格式 则需要传入这个值<br/>
* 规定传入值为键值对 映射关系为 <b>[”枚举1_1“,”枚举2_2“...]</b><br/>
* 也支持只传如 <b>[”枚举1”,”枚举2”,。。。]</b><br/>
* 限制导入后的数据不在这个值的范围内则进行提醒,如果在,则做转换,若是设置了setValueToPrpName 且是k_v 可以将转化后(v)的值进行赋值
*
* @return
*/
String[] k_v() default {};
/**
* <font color="#ff5f56">
* <p>
* 暂时不启用
* </p>
* </font>
* 设置背景颜色
*/
ColorEnum cellColor() default ColorEnum.AUTOMATIC;
/**
* <font color="#ff5f56">
* <p>
* 暂时不启用
* </p>
* </font>
*
* 设置背景自定义颜色 如果设置了,则优先使用此颜色
* 可以通过 ColorEnum.getIntFromColor(255,255,255) 来设置颜色
*/
int cellDIYColor() default -1;
/**
* 标记导出excel列的日期格式(如果字段不是日期则为空)
*/
DateEnum dateFormat() default DateEnum.NULL;
/**
* 设置每列的列宽 只需要传汉字的个数,大概就是 (传入数 * 1个字) 那么宽 不传就是自适应
*/
int colWidth() default -1;
/**
* 设置每列的对齐方式 默认是居中
*/
HorizontalAlignment colAlign() default HorizontalAlignment.CENTER_SELECTION;
/**
* 自定义转换器 <br>
* 转换器 <br>
* 返回的Object <br>
* Object 是校验后的数据 赋值后可与现有参数做替换 <br>
* @return ExcelDate
*/
Class<? extends IExcelConvert> convert() default ExcelConvertImpl.class;
注解使用
实体类
//需要导出下拉框的字典类型
@ExcelProperty(value = "字典类型")
@ExcelPropertyTemplate(
value = "字典类型", //设置导出的标题名称,如果由此值,则用此名称,没有则用上个注解的名称
type = NotNullEnum.STR_DICT, //设置导出的type 默认可以不传
dictCode = "ditc_code", //选了字典的type,则必须给这个赋值,否则会查不到
colWidth = 8, //设置导出的标题列的列宽 大概就是 (传入数 * 1个字) 那么宽 不传就是自适应
dateFormat = DateEnum.DATE_TIME, //设置导出excel列的日期格式
colAlign = HorizontalAlignment.RIGHT, //设置导出的标题列的对齐方式 默认是居中
convert = ExcelConvertImpl.class //添加自定义转换器 可以自己做自己的实现类来进行转换 需要配合 IUtilService 里的 exportSetParameterValue(Object paramValue) 方法进行转换
)
private String test;
//需要导出下拉框的自定义字典K_V类型
@ExcelProperty(value = "K_V类型")
@ExcelPropertyTemplate(
value = "K_V类型", //设置导出的标题名称,如果由此值,则用此名称,没有则用上个注解的名称
type = NotNullEnum.STR_K_V, //设置导出的type 默认可以不传
k_v = {"mj11_1", "mj22_1", "mj33_1"}, //选了k_v的type,则必须给这个赋值,否则会查不到
colWidth = 8, //设置导出的标题列的列宽 大概就是 (传入数 * 1个字) 那么宽 不传就是自适应
dateFormat = DateEnum.DATE_TIME, //设置导出excel列的日期格式
colAlign = HorizontalAlignment.RIGHT, //设置导出的标题列的对齐方式 默认是居中
convert = ExcelConvertImpl.class //添加自定义转换器 可以自己做自己的实现类来进行转换 需要配合 IUtilService 里的 exportSetParameterValue(Object paramValue) 方法进行转换
)
private String test;
实现类
@Autowired
IUtilService utilService;
public void template(HttpServletResponse response) {
ArrayList<DemoEntity> list2 = new ArrayList<DemoEntity>();
DemoEntity demoEntity = new DemoEntity();
demoEntity.setSpr("审批ren");
demoEntity.setSpzt("2023-04-13 08:19:16.483");
demoEntity.setSpyj("auditIdsa:\r\n①您的测试一开始\r\n②测试不通过,快回来造BUG;\r\ntIdsauditIdsauditIdsauditIdsauditIdsauditIdsauditIdsauditIdsauditIdsauditIds");
demoEntity.setSprData("mj22");
demoEntity.setAuditIds("3");
list2.add(demoEntity);
//TODO 此处调用转换方法或者自己for进行转换数据
utilService.exportSetParameterValue(list2);
//要导出的字段列表
List<String> columnFiledNames = new ArrayList<>();
columnFiledNames.add("spr");
columnFiledNames.add("spzt");
columnFiledNames.add("spyj");
columnFiledNames.add("sprData");
columnFiledNames.add("auditIds");
columnFiledNames.add("custom");
columnFiledNames.add("regex");
//TODO 此处需要根据具体业务添加代码
ExcelUtilsNew.exportTemplateByBtList(list2,response, DemoEntity.class,columnFiledNames,"sss");
}
FileUtils
DateUtil
继承了hutool的DateUtil包,但是我还是写了几种我比较常用的方法
//根据秒数 获取 XX小时XX分钟X秒 格式的时间
String formatTimeStr(Long n);
//是否能转换成时间 普通校验,检测转换异常
boolean isDateValid(String dateStr,String dateFormat);
//是否符合传入的正则格式的时间字符串
boolean isDateValidToRegx(String dateStr,String regx);
//判断时间字符串是否符合时间格式,并返回时间Date格式 转换失败,或者不符合,则返回null 以下方法跟上边的不同的地方是他兼容了我写的常用的时间格式,只要符合其中一种,即可转换成功 如果还有非常用的,请联系我加上
Date dateStrZhuanDate(String dateStr);
//如果没转换成功,则返回当前时间 传入true即可
Date dateStrZhuanDate(String dateStr,boolean blankReturnNow);
//判断时间字符串是否符合时间格式,并返回指定格式的字符串。 转换失败,或者不符合,则返回空字符串 ""
String dateStrZhuanDateStr(String dateStr,String formatStr);
EmptyUtils
除了常用的判空,还写了两种
//判断为空 paichuName – 排除此字段的值,让他相当于不存在
ComUtils.isEmpty(Object obj,String paichuName);
ComUtils.isNotEmpty(Object obj,String paichuName);
判断该对象是否全部字段都为空 返回值: ture表示所有属性为null 返回false表示不是所有属性都是null
ComUtils.isAllFieldNull(Object obj);
ComUtils
将Query里报错的字段(数据库不存在的字段) 或者直接删除
ComUtils.replaceQueryToFiled(Query query, String oldName);
将Query里报错的字段(数据库不存在的字段)替换成存在的 或者直接删除,第三个参数不传就是直接删除
ComUtils.replaceQueryToFiled(Query query, String oldName, String newName);
封装一个删除多选字符串之后处理剩余【间隔符】多的问题 间隔符不传则默认为【,】
ComUtils.removeOne(String yuanStr, String oldName);
ComUtils.removeOne(String yuanStr, String oldName, String split);
封装一个关于高级搜索的字段名与数据库名不一样,导致报数据库没有这个字段的错误。 传入之前的key,直接删除这个搜索
ComUtils.replaceSearchMapToKey(Map<String, Object> map, String oldKey);
封装一个关于高级搜索的字段名与数据库名不一样,导致报数据库没有这个字段的错误。 将传入的key名字 转换成传入的新key 就是数据库有的那个字段名 第三个值,不传就是删除,支持传多个值 用逗号间隔
ComUtils.replaceSearchMapToKey(Map<String, Object> map, String oldKey, String newKey);