没有哪个需求是一开始就不变的,如果真有,那这个需求大概率不会真的上线了(目前我还没有见过需求一次就确定好,然后就上线的)。
前两天说了那个下载模板的需求,历尽千辛万苦,终于在测试环境测完了,然后迎来的就是需求的小变更。模板中原来有一列,是下拉筛选的,不允许自己填写,而且当时需求说,下拉内容是固定不变的(永远不要相信产品的这句话!)。测试环境测完,准备上线的时候,需求变了,要下拉筛选的内容变成动态的,数据库内容更新了,下载模板中这一列的下拉内容也同步更新。因为我只是在excel中固定写了下拉的内容,然后实现了下拉筛选(想了解的可以参考我这个excel实现下拉筛选),现在让我把下拉内容实现动态,当时内心是有些崩溃的... 但是,没办法,也只能考虑怎么实现了。
刚开始自己找了很多资料,也没周到特别好的办法,然后通过请教同事,最后终于把功能实现了。先直接上代码:
/**
* 模板下载
*/
public void downloadTemplate(HttpServletResponse response){
OutputStream out = null;
InputStream in = null;
ByteArrayOutputStream bos = null;
String fileName = "导入模版";
try {
// 读取模板
Resource res = new ClassPathResource("template.xlsx");
XSSFWorkbook workbook = new XSSFWorkbook(res.getInputStream());
XSSFSheet sheet = workbook.getSheetAt(0);
//添加渠道下拉信息
addValidationForChannel(sheet);
// 转换为字节流
bos = new ByteArrayOutputStream();
workbook.write(bos);
byte[] barray = bos.toByteArray();
in = new ByteArrayInputStream(barray);
response.reset();
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
out = response.getOutputStream();
byte[] b = new byte[1024];
int len;
while ((len = in.read(b)) > 0) {
out.write(b, 0, len);
}
out.flush();
} catch (Exception e) {
log.error("下载模板失败",e);
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
log.error("关闭资源异常",e);
}
in = null;
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
log.error("关闭资源异常",e);
}
out = null;
}
if (null != bos) {
try {
bos.flush();
bos.close();
} catch (IOException e) {
log.error("关闭资源异常",e);
}
out = null;
}
}
}
/**
* 添加渠道下拉选择
* @param sheet
*/
private void addValidationForChannel(XSSFSheet sheet) {
// 查询xxx信息
List<Channel> channelList = channelService.queryListByCode(Constants.CHANNEL_AGENCY);
if(CollectionUtil.isEmpty(channelList)){
return;
}
List<String> collect = channelList.stream().map(Channel::getChannelName).distinct().collect(Collectors.toList());
String[] datas = collect.toArray(new String[collect.size()]);
XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper.createExplicitListConstraint(datas);
CellRangeAddressList addressList = null;
XSSFDataValidation validation = null;
addressList = new CellRangeAddressList(2, MAX_VALUE, 4, 4);
validation = (XSSFDataValidation) dvHelper.createValidation(dvConstraint, addressList);
//这两行设置单元格只能是列表中的内容,否则报错
validation.setSuppressDropDownArrow(true);
validation.setShowErrorBox(true);
sheet.addValidationData(validation);
}
这个是用原生的POI做的处理,虽然里面代码看的也不太懂,但是起码功能实现了,下载出来之后,筛选框默认就是数据库查出来的内容,如果想增加删除下拉内容,直接更改数据库就可以了,不用再去修改代码,发版上线了。
但是对于小白的我来说,也是花费了一天多没有实现,这个筛选功能还是同事帮我解决的,他以前做过好几个关于excel的功能,所以说,还是接触的太少,所以才不知道如何去解决。看来还是要不断的学习呀。好了,今天的分享就到这里吧!