|
|
@@ -1,20 +1,50 @@
|
|
|
package cn.tr.module.excel.core.handler.write;
|
|
|
|
|
|
+import cn.hutool.core.collection.CollectionUtil;
|
|
|
+import cn.hutool.core.lang.Pair;
|
|
|
+import cn.hutool.core.util.CharUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.tr.module.constant.ExcelConstant;
|
|
|
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.Sheet;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.apache.poi.ss.util.CellRangeAddressList;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFDataValidation;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFDataValidationConstraint;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 固定表头和添加过滤
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
public class CustomSheetWriteHandler implements SheetWriteHandler {
|
|
|
|
|
|
public int colSplit = 0, rowSplit = 1, leftmostColumn = 0, topRow = 1;
|
|
|
|
|
|
- @Override
|
|
|
+ //excel中的属性列的位置
|
|
|
+ private final Map<String, Integer> excelColumnProperty;
|
|
|
+
|
|
|
+ //级联属性映射集合 map("下级属性","上级属性")
|
|
|
+ private final Map<String, String> linkagePropertyMap;
|
|
|
|
|
|
+ //属性所对应的级联集合
|
|
|
+ private final Map<String, List<Pair<String, List<String>>>> selectPropertyMap ;
|
|
|
+
|
|
|
+ public CustomSheetWriteHandler(Map<String, Integer> excelColumnProperty, Map<String, String> linkagePropertyMap, Map<String, List<Pair<String, List<String>>>> selectPropertyMap) {
|
|
|
+ this.excelColumnProperty = excelColumnProperty;
|
|
|
+ this.linkagePropertyMap = linkagePropertyMap;
|
|
|
+ this.selectPropertyMap = selectPropertyMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
|
|
|
|
|
|
}
|
|
|
@@ -23,7 +53,90 @@ public class CustomSheetWriteHandler implements SheetWriteHandler {
|
|
|
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
|
|
|
Sheet sheet = writeSheetHolder.getSheet();
|
|
|
sheet.createFreezePane(colSplit, rowSplit, leftmostColumn, topRow);
|
|
|
-// sheet.protectSheet("123456");
|
|
|
+ createLinkageSelectColumn(sheet);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建级联搜索列
|
|
|
+ * @param sheet
|
|
|
+ */
|
|
|
+ private void createLinkageSelectColumn(Sheet sheet){
|
|
|
+ //没有级联
|
|
|
+ if(CollectionUtil.isEmpty(linkagePropertyMap)){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //已经处理过的字段
|
|
|
+ List<Object> doneProperty = new ArrayList<>();
|
|
|
+ linkagePropertyMap.forEach((currentProperty,parentProperty)->{
|
|
|
+ if(StrUtil.isBlank(parentProperty)){
|
|
|
+ //非级联
|
|
|
+ noneLinkageSelectColumn(sheet,currentProperty);
|
|
|
+ }else {
|
|
|
+ //级联
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
+ private void noneLinkageSelectColumn(Sheet sheet,String property){
|
|
|
+ Integer columnIndex = excelColumnProperty.get(property);
|
|
|
+ if(ObjectUtil.isNull(columnIndex)){
|
|
|
+ log.warn("[execl文件导出],property:{}显示为级联属性,找不到对应的列数",property);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<Pair<String, List<String>>> optionalSelectValues = selectPropertyMap.get(property);
|
|
|
+ List<String> selectValues = new ArrayList<>();
|
|
|
+ if(CollectionUtil.isEmpty(optionalSelectValues)){
|
|
|
+ selectValues.add("--- 暂无数据 ---");
|
|
|
+ }else {
|
|
|
+ optionalSelectValues.forEach(pair->{
|
|
|
+ if(CollectionUtil.isNotEmpty(pair.getValue())){
|
|
|
+ selectValues.addAll(pair.getValue());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ doCreateNoneLinkageSelectColumn(property,sheet,selectValues,columnIndex,sheet.getWorkbook());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void doCreateNoneLinkageSelectColumn(String propertyName,Sheet sheet, Collection<String> options, int column, Workbook wb) {
|
|
|
+ Sheet hiddenSheet = wb.getSheet(propertyName);
|
|
|
+ if(hiddenSheet==null){
|
|
|
+ hiddenSheet = wb.createSheet(propertyName);
|
|
|
+ }
|
|
|
+ Row row;
|
|
|
+ //写入下拉数据到新的sheet页中
|
|
|
+ for (int i = 0; i < options.size(); i++) {
|
|
|
+ row = hiddenSheet.getRow(i);
|
|
|
+ if(row==null){
|
|
|
+ row=hiddenSheet.createRow(i);
|
|
|
+ }
|
|
|
+ Cell cell = row.createCell(column);
|
|
|
+ cell.setCellValue(CollectionUtil.get(options,i));
|
|
|
+ }
|
|
|
+ //获取新sheet页内容
|
|
|
+ String strFormula = propertyName + "!$"+ CharUtil.toString((char)(65+column))+"$1:$"+CharUtil.toString((char)(65+column))+"$65535";
|
|
|
+ XSSFDataValidationConstraint constraint = new XSSFDataValidationConstraint(DataValidationConstraint.ValidationType.LIST,strFormula);
|
|
|
+ // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
|
|
|
+ CellRangeAddressList regions = createColumnCellRange(column);
|
|
|
+ // 数据有效性对象
|
|
|
+ DataValidationHelper helper = sheet.getDataValidationHelper();
|
|
|
+ DataValidation dataValidation = helper.createValidation(constraint, regions);
|
|
|
+ if (dataValidation instanceof XSSFDataValidation) {
|
|
|
+ // 数据校验
|
|
|
+ dataValidation.setSuppressDropDownArrow(true);
|
|
|
+ dataValidation.setShowErrorBox(true);
|
|
|
+ } else {
|
|
|
+ dataValidation.setSuppressDropDownArrow(false);
|
|
|
+ }
|
|
|
+ // 作用在目标sheet上
|
|
|
+ sheet.addValidationData(dataValidation);
|
|
|
+ //将新建的sheet页隐藏掉
|
|
|
+ wb.setSheetHidden(wb.getSheetIndex(propertyName), true);
|
|
|
+ }
|
|
|
+
|
|
|
+ private CellRangeAddressList createColumnCellRange(int column){
|
|
|
+ return new CellRangeAddressList(1, ExcelConstant.MAX_ROW,column,column);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|