// 在前一个文章有讲到如何修复导出数据到 Excle 是空数据的问题;
今天讲讲指定数据进行搜索和指定数据导出 Excle 的方法,以及时间段的数据查询;那么要准备好你的前端效果;
首先讲指定数据搜索和导出Excel的方法:
重点是前端要有个搜索框吧,部分代码:
在 controller 层添加调用的方法;
(方法在视频、文章里有:)
@Log(title = "合同", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:dict:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysSignedContract signedContract) throws IllegalAccessException {
List<SysSignedContract> list = signedContractService.list(qw);
ExcelUtil<SysSignedContract> util = new ExcelUtil<>(SysSignedContract.class);
util.exportExcel(response, list, "参数数据");
}
根据上面的这段代码呢已经可以将所有的数据都导出到 Excel 当中了;(如果不行就去看这里👉:)
现在你要增加一个条件进行查询:增加这几行代码;添加到 export 这个方法当中;示例代码下:要注意这个 getxxx() 这个你要改成你自己的字段的定义名喔;额 signedContract 也是;如果新增上去后部分地方爆红的有可能是你缺少那个依赖包;把鼠标放上去会有解决方法帮你导入缺少的依赖包。
LambdaQueryWrapper<SysSignedContract> qw = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(signedContract.getContractName())) {
qw.like(SysSignedContract::getContractName, signedContract.getContractName());
}
那么通过刚才的添加,你就可以指定查询并导出相应的数据到 Excel 了啦;
那么整体效果就是基本完成了
但突然想到如果我有多个要查询的条件那就会有多个 if 查询语句,而且有时候我只是指定1个条件,但是 其它 if 语句还是会执行,而且未来要是想加个7、8个搜索条件,那我还得再加7、8个 if 语句;我个人还是喜欢稍微高级化下;自动识别哪些字段要进行查询,哪些不需要。
可以通过 Java 反射机制动态获取对象的字段值,并判断哪些字段有值。以下是一个示例代码,用于输出 `SysSignedContract` 对象中有值的字段名:
Field[] fields = signedContract.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
try {
Object value = field.get(signedContract);
if (value != null) {
System.out.println(field.getName() + " 字段有值:" + value);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
在上述代码中,我首先使用反射获取了 `SysSignedContract` 类中声明的所有字段,然后遍历这些字段。通过 `field.get(signedContract)` 获取字段的值,并判断是否为 null。如果字段的值不为 null,则输出字段名和对应的数值。
这样修改后,你可以动态判断哪些字段有值,并输出这些字段的名称及对应数值。
当然,你可以在代码中避免使用 try-catch 块,通过在方法签名中声明可能抛出的异常来处理。以下是修改后不使用 try-catch 的示例代码:
Field[] fields = signedContract.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object value = field.get(signedContract);
if (value != null) {
System.out.println(field.getName() + " 字段有值:" + value);
}
}
在这段代码中,我移除了 try-catch 块,并假设 `IllegalAccessException` 是一个受检异常,如果发生异常,你可以在方法签名处声明该异常。
这样修改后,你可以动态判断哪些字段有值,并输出这些字段的名称及对应数值,而不需要使用 try-catch 块。
最后你可以根据字段是否有值来动态构建 LambdaQueryWrapper 条件。以下是根据有值的字段来添加 like 查询条件的示例代码:
LambdaQueryWrapper<SysSignedContract> qw = new LambdaQueryWrapper<>();
Field[] fields = signedContract.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object value = field.get(signedContract);
if (value != null) {
System.out.println(field.getName() + " 字段有值:" + value);
if (field.getType() == String.class && StringUtils.isNotBlank((String) value)) {
qw.like((column) -> getColumn(field.getName()), value);
}
}
}
private String getColumn(String fieldName) {
// 这里可以根据实际情况进行字段名到数据库列名的映射
return fieldName;
}
在上述代码中,我根据字段是否有值来判断是否需要添加 like 查询条件,并且只有当字段类型为 String 并且值不为空时才添加 like 查询条件。另外,你可能需要实现一个 `getColumn` 方法来将字段名转换为数据库表的列名。
这样修改后,你可以根据 SysSignedContract 对象中有值的字段动态构建查询条件来实现你的需求。
你可以根据自己的实际情况来编写 `getColumn` 方法,以下是一个简单的示例:
private String getColumn(String fieldName) {
switch (fieldName) {
case "contractName":
return "contract_name";
// 其他字段的映射关系
default:
return fieldName;
}
}
在这个示例中,我使用了一个简单的 switch 语句来将字段名转换为数据库表的列名,你可以根据实际情况添加更多的字段映射关系。
如果你的表字段和实体类字段的命名规则不同,你可能需要在 `getColumn` 方法中添加更多的映射关系。
那么动态方法也就是这样了;
(os:但是回头看下发现,代码量超多的,感觉还不如写多个 if 判断来的快)
接着讲时间段的查询方法:
那时间段查询,首先你也要有个前端效果吧:
vue前端部分代码:
<el-form-item label="发起时间">
<el-date-picker
@change="checktime"
v-model="text"
type="daterange"
value-format="yyyy-MM-dd"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
当然你的前端要有一个接收暂存时间的地方,这里用的是(text);再随意定义个例如:starttime、endtime;一会可以用上(但是要和你数据库的字段有对应,不然一会传不了值;os:或许可以但朕不会😅你就将就吧)。我这里临时利用原有数据库的 contractTime、deleteTime 这两个字段值。
text:[],
contractTime: undefined,
deleteTime:undefined,
然后你就可以去方法里面给这两个赋值(为啥我这还有queryparams呢?因为我的那两个time变量放到这个数组里;你自己改就好)
checktime(){
this.queryParams.contractTime = this.text[0];
this.queryParams.deleteTime = this.text[1];
},
到这里前端就完成了;后端:
你找到你后端查数据的位置(文件名应该在 service 层那里)像👇这个就是我查找的位置代码;
(在这里有前一个,搜索指定数据的 if )
在这里添加一个新的 if 来进行判断
if(search.getContractTime() != null && search.getDeleteTime() != null){
qw.between(SysSignedContract::getContractTime, search.getContractTime(), search.getDeleteTime());
}
【注意:search 是我自己定义的如下图,你要自己改;然后我前面说的定义的变量来了,contractTime、deleteTime,这两个是要去 demo 那里定义才可以,而且数据库也要有这个字段名才可以】
这里是显示查找的;同样如果你想要导出的话,就把这个 if 多复制一份到导出的方法里面就可以了;如下图所示:(其它代码在前面有讲了)
这样就可以查并可以导出从 xxx ~ yyy 这段时间的数据了;
如果你有其它问题欢迎在评论区留言或私信我
如果觉得对你有帮助,记得一键三连 点赞、收藏、关注👍⭐🧧