Browse Source

下载excel增加下拉。

master
刘忱 2 years ago
parent
commit
3ea2a2e5cb
  1. 19
      win-framework/win-spring-boot-starter-biz-dict/src/main/java/com/win/framework/dict/core/util/DictFrameworkUtils.java
  2. 52
      win-framework/win-spring-boot-starter-excel/src/main/java/com/win/framework/excel/core/handler/CustomSheetWriteHandler.java
  3. 81
      win-framework/win-spring-boot-starter-excel/src/main/java/com/win/framework/excel/core/util/ExcelUtils.java
  4. 9
      win-module-system/win-module-system-api/src/main/java/com/win/module/system/api/dict/DictDataApi.java
  5. 14
      win-module-system/win-module-system-biz/src/main/java/com/win/module/system/api/dict/DictDataApiImpl.java
  6. 10
      win-module-system/win-module-system-biz/src/main/java/com/win/module/system/controller/user/UserController.java

19
win-framework/win-spring-boot-starter-biz-dict/src/main/java/com/win/framework/dict/core/util/DictFrameworkUtils.java

@ -52,6 +52,20 @@ public class DictFrameworkUtils {
});
/**
* 针对 {@link #parseDictDataValue(String, String)} 的缓存
*/
private static final LoadingCache<KeyValue<String, String>, String[]> DICT_TYPE_DICT_DATA_CACHE = CacheUtils.buildAsyncReloadingCache(
Duration.ofMinutes(1L), // 过期时间 1 分钟
new CacheLoader<KeyValue<String, String>, String[]>() {
@Override
public String[] load(KeyValue<String, String> key) {
return ObjectUtil.defaultIfNull(dictDataApi.getDictDataByType(key.getKey()), new String[0]);
}
});
public static void init(DictDataApi dictDataApi) {
DictFrameworkUtils.dictDataApi = dictDataApi;
log.info("[init][初始化 DictFrameworkUtils 成功]");
@ -72,4 +86,9 @@ public class DictFrameworkUtils {
return PARSE_DICT_DATA_CACHE.get(new KeyValue<>(dictType, label)).getValue();
}
@SneakyThrows
public static String[] dictTypeDictDataValue(String dictType) {
return DICT_TYPE_DICT_DATA_CACHE.get(new KeyValue<>(dictType, null));
}
}

52
win-framework/win-spring-boot-starter-excel/src/main/java/com/win/framework/excel/core/handler/CustomSheetWriteHandler.java

@ -0,0 +1,52 @@
package com.win.framework.excel.core.handler;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddressList;
import java.util.Map;
/**
* @author liuchen
*/
public class CustomSheetWriteHandler implements SheetWriteHandler {
private Map<Integer, String[]> mapDropDown;
public CustomSheetWriteHandler(Map<Integer, String[]> mapDropDown) {
this.mapDropDown = mapDropDown;
}
@Override
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
}
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
//获取工作簿
Sheet sheet = writeSheetHolder.getSheet();
///开始设置下拉框
DataValidationHelper helper = sheet.getDataValidationHelper();
//设置下拉框
for (Map.Entry<Integer, String[]> entry : mapDropDown.entrySet()) {
/*起始行、终止行、起始列、终止列 起始行为1即表示表头不设置**/
//这里设置65535可能又问题,因为这个是excel的最大行数,如果数据量超过这个数,就会报错
CellRangeAddressList addressList = new CellRangeAddressList(1, 65535, entry.getKey(), entry.getKey());
/*设置下拉框数据**/
DataValidationConstraint constraint = helper.createExplicitListConstraint(entry.getValue());
DataValidation dataValidation = helper.createValidation(constraint, addressList);
//阻止输入非下拉选项的值
dataValidation.setErrorStyle(DataValidation.ErrorStyle.STOP);
dataValidation.setShowErrorBox(true);
dataValidation.setSuppressDropDownArrow(true);
dataValidation.createErrorBox("提示", "输入值与单元格定义格式不一致");
dataValidation.createPromptBox("填写说明", "填写内容只能为下拉数据集中的类型");
sheet.addValidationData(dataValidation);
}
}
}

81
win-framework/win-spring-boot-starter-excel/src/main/java/com/win/framework/excel/core/util/ExcelUtils.java

@ -2,13 +2,22 @@ package com.win.framework.excel.core.util;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.win.framework.excel.core.handler.CustomSheetWriteHandler;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
/**
* Excel 工具类
@ -36,7 +45,30 @@ public class ExcelUtils {
.sheet(sheetName).doWrite(data);
// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
response.addHeader("excel-count", String.valueOf(data.size()));
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
}
/**
* 将列表以 Excel 响应给前端
*
* @param response 响应
* @param filename 文件名
* @param sheetName Excel sheet
* @param head Excel head
* @param data 数据列表哦
* @param mapDropDown 下拉数据
* @param <T> 泛型保证 head data 类型的一致性
* @throws IOException 写入失败的情况
*/
public static <T> void write(HttpServletResponse response, String filename, String sheetName, Class<T> head, List<T> data, Map<Integer, String[]> mapDropDown) throws IOException {
// 输出 Excel
EasyExcel.write(response.getOutputStream(), head)
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
.registerWriteHandler(new CustomSheetWriteHandler(mapDropDown))
.registerWriteHandler(getStyleStrategy()) // 设置excel样式
.sheet(sheetName).doWrite(data);
// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
}
@ -51,5 +83,52 @@ public class ExcelUtils {
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
.doReadAllSync();
}
/**
* 设置excel样式
*
* @return
*/
public static HorizontalCellStyleStrategy getStyleStrategy() {
// 头的策略 样式调整
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
// 头背景 浅绿
headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
WriteFont headWriteFont = new WriteFont();
// 头字号
headWriteFont.setFontHeightInPoints((short) 14);
// 字体样式
headWriteFont.setFontName("宋体");
headWriteCellStyle.setWriteFont(headWriteFont);
// 自动换行
headWriteCellStyle.setWrapped(true);
// 设置细边框
headWriteCellStyle.setBorderBottom(BorderStyle.THIN);
headWriteCellStyle.setBorderLeft(BorderStyle.THIN);
headWriteCellStyle.setBorderRight(BorderStyle.THIN);
headWriteCellStyle.setBorderTop(BorderStyle.THIN);
// 设置边框颜色 25灰度
headWriteCellStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
headWriteCellStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
headWriteCellStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
headWriteCellStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.getIndex());
// 水平对齐方式
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
// 垂直对齐方式
headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 内容的策略 宋体
WriteCellStyle contentStyle = new WriteCellStyle();
// 设置垂直居中
contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置 水平居中
contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
WriteFont contentWriteFont = new WriteFont();
// 内容字号
contentWriteFont.setFontHeightInPoints((short) 12);
// 字体样式
contentWriteFont.setFontName("宋体");
contentStyle.setWriteFont(contentWriteFont);
// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
return new HorizontalCellStyleStrategy(headWriteCellStyle, contentStyle);
}
}

9
win-module-system/win-module-system-api/src/main/java/com/win/module/system/api/dict/DictDataApi.java

@ -39,4 +39,13 @@ public interface DictDataApi {
*/
DictDataRespDTO parseDictData(String type, String label);
/**
* 解析获得指定的字典数据从缓存中
*
* @param type 字典类型
* @return 字典数据
*/
String[] getDictDataByType(String type);
}

14
win-module-system/win-module-system-biz/src/main/java/com/win/module/system/api/dict/DictDataApiImpl.java

@ -1,6 +1,7 @@
package com.win.module.system.api.dict;
import com.win.module.system.api.dict.dto.DictDataRespDTO;
import com.win.module.system.controller.dict.vo.data.DictDataExportReqVO;
import com.win.module.system.convert.dict.DictDataConvert;
import com.win.module.system.dal.dataobject.dict.DictDataDO;
import com.win.module.system.service.dict.DictDataService;
@ -8,6 +9,8 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* 字典数据 API 实现类
@ -37,4 +40,15 @@ public class DictDataApiImpl implements DictDataApi {
return DictDataConvert.INSTANCE.convert02(dictData);
}
@Override
public String[] getDictDataByType(String type) {
List<DictDataDO> dataDOList = dictDataService.getDictDataList(new DictDataExportReqVO().setDictType(type));
String[] result = new String[dataDOList.size()];
List<String> labels = dataDOList.stream().map(DictDataDO::getLabel).collect(Collectors.toList());
if(!labels.isEmpty()) {
labels.toArray(result);
}
return result;
}
}

10
win-module-system/win-module-system-biz/src/main/java/com/win/module/system/controller/user/UserController.java

@ -5,12 +5,14 @@ import com.win.framework.common.enums.CommonStatusEnum;
import com.win.framework.common.pojo.CommonResult;
import com.win.framework.common.pojo.PageResult;
import com.win.framework.common.util.collection.MapUtils;
import com.win.framework.dict.core.util.DictFrameworkUtils;
import com.win.framework.excel.core.util.ExcelUtils;
import com.win.framework.operatelog.core.annotations.OperateLog;
import com.win.module.system.controller.user.vo.user.*;
import com.win.module.system.convert.user.UserConvert;
import com.win.module.system.dal.dataobject.dept.DeptDO;
import com.win.module.system.dal.dataobject.user.AdminUserDO;
import com.win.module.system.enums.DictTypeConstants;
import com.win.module.system.enums.common.SexEnum;
import com.win.module.system.service.dept.DeptService;
import com.win.module.system.service.user.AdminUserService;
@ -171,9 +173,13 @@ public class UserController {
UserImportExcelVO.builder().username("yuanma").deptId(2L).email("yuanma@iocoder.cn").mobile("15601701300")
.nickname("源码").status(CommonStatusEnum.DISABLE.getStatus()).sex(SexEnum.FEMALE.getSex()).build()
);
Map<Integer, String[]> mapDropDown = new HashMap<>();
String[] sex = DictFrameworkUtils.dictTypeDictDataValue(DictTypeConstants.USER_SEX);
mapDropDown.put(5, sex);
String[] status = DictFrameworkUtils.dictTypeDictDataValue(DictTypeConstants.COMMON_STATUS);
mapDropDown.put(6, status);
// 输出
ExcelUtils.write(response, "用户导入模板.xls", "用户列表", UserImportExcelVO.class, list);
ExcelUtils.write(response, "用户导入模板.xls", "用户列表", UserImportExcelVO.class, list, mapDropDown);
}
@PostMapping("/import")

Loading…
Cancel
Save