This commit is contained in:
ran.shang
2025-12-29 16:06:48 +08:00
parent b853edcfde
commit ee95dfa2c2
1600 changed files with 6997 additions and 7445 deletions

View File

@@ -0,0 +1,156 @@
package com.senmesh.common.easyexcel;
import com.google.common.collect.Maps;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.AbstractCellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.senmesh.common.dto.ExportHeadDetailInfoDTO;
import com.senmesh.common.dto.ExportHeadInfoDTO;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
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.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import java.awt.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import cn.hutool.core.collection.CollUtil;
public class DynamicExportTemplateCellWriteHandler extends AbstractCellWriteHandler {
private Map<Integer, ExportHeadDetailInfoDTO> exportHeadIndexMap = null;
private Integer hiddenSheetIndex = 1;
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
super.afterCellDispose(writeSheetHolder, writeTableHolder, cellDataList, cell, head, relativeRowIndex, isHead);
int rowIndex = cell.getRowIndex();
int columnIndex = cell.getColumnIndex();
Workbook workbook = writeSheetHolder.getParentWriteWorkbookHolder().getWorkbook();
Sheet sheet = writeSheetHolder.getSheet();
if (rowIndex == 0) {
Row row = cell.getRow();
row.setHeight((short) (33 * 20));
ExportHeadInfoDTO exportInfo = (ExportHeadInfoDTO) ImportDataContext.get("exportInfo");
XSSFCellStyle cellStyle = (XSSFCellStyle) workbook.createCellStyle();
cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
cellStyle.setBottomBorderColor(IndexedColors.BLACK.index);
cellStyle.setBorderLeft(BorderStyle.THIN);//左边框
cellStyle.setLeftBorderColor(IndexedColors.BLACK.index);
cellStyle.setBorderTop(BorderStyle.THIN);//上边框
cellStyle.setTopBorderColor(IndexedColors.BLACK.index);
cellStyle.setBorderRight(BorderStyle.THIN);//右边框
cellStyle.setRightBorderColor(IndexedColors.BLACK.index);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
Color color = new Color(91, 155, 213);
cellStyle.setFillForegroundColor(new XSSFColor(color,null));
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
Font font = workbook.createFont();
cellStyle.setFont(font);
font.setFontName("Calibri");
font.setColor(HSSFColor.HSSFColorPredefined.WHITE.getIndex());
cell.setCellStyle(cellStyle);
if (Objects.isNull(exportHeadIndexMap)) {
List<ExportHeadDetailInfoDTO> heads = exportInfo.getHeads();
exportHeadIndexMap = Maps.newHashMap();
for (int i = 0; i < heads.size(); i++) {
ExportHeadDetailInfoDTO exportHead = heads.get(i);
exportHeadIndexMap.put(i, exportHead);
}
}
ExportHeadDetailInfoDTO exportHeadDetailInfoDTO = exportHeadIndexMap.get(columnIndex);
String name;
if (Objects.isNull(exportHeadDetailInfoDTO)) {
name = cell.getStringCellValue();
} else {
name = exportHeadDetailInfoDTO.getHead();
}
int length = ((name.getBytes(StandardCharsets.UTF_8).length + cell.toString().length()) * 3) / 5 + 5;
sheet.setColumnWidth(columnIndex, length * 290);
List<String> explicitList = Objects.isNull(exportHeadDetailInfoDTO) ? null : exportHeadDetailInfoDTO.getExplicitList();
// 设置下拉属性
// if (CollUtil.isNotEmpty(explicitList)) {
// DataValidationHelper helper = sheet.getDataValidationHelper();
// DataValidationConstraint constraint = helper.createExplicitListConstraint(explicitList.toArray(new String[]{}));
// //设置生效的起始行、终止行、起始列、终止列
// CellRangeAddressList cellAddressList = new CellRangeAddressList(1,
// 65535, columnIndex, columnIndex);
// DataValidation validation = helper.createValidation(constraint, cellAddressList);
// //适配xls和xlsx
// if (validation instanceof HSSFDataValidation) {
// validation.setSuppressDropDownArrow(false);
// } else {
// validation.setSuppressDropDownArrow(true);
// validation.setShowErrorBox(true);
// }
// sheet.addValidationData(validation);
// }
if (CollUtil.isNotEmpty(explicitList)){
String hiddenName = "hidden" + hiddenSheetIndex;
//1.创建隐藏的sheet页。 起个名字吧!叫"hidden"!
Sheet hiddenSheet = workbook.createSheet(hiddenName);
//2.循环赋值(为了防止下拉框的行数与隐藏域的行数相对应,将隐藏域加到结束行之后)
for (int i = 0; i < explicitList.size(); i++) {
hiddenSheet.createRow(65535 + i).createCell(columnIndex).setCellValue(explicitList.get(i));
}
Name category1Name = workbook.createName();
category1Name.setNameName(hiddenName);
//3 A1:A代表隐藏域创建第N列createCell(N)时。以A1列开始A行数据获取下拉数组
category1Name.setRefersToFormula(hiddenName + "!A1:A" + (explicitList.size() + 65535));
//
DataValidationHelper helper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = helper.createFormulaListConstraint(hiddenName);
CellRangeAddressList addressList = new CellRangeAddressList(1, 65535, columnIndex, columnIndex);
DataValidation dataValidation = helper.createValidation(constraint, addressList);
if (dataValidation instanceof XSSFDataValidation) {
// 数据校验
dataValidation.setSuppressDropDownArrow(true);
dataValidation.setShowErrorBox(true);
} else {
dataValidation.setSuppressDropDownArrow(false);
}
// 作用在目标sheet上
sheet.addValidationData(dataValidation);
// 设置hiddenSheet隐藏
workbook.setSheetHidden(hiddenSheetIndex, true);
hiddenSheetIndex++;
}
}
}
}

View File

@@ -0,0 +1,77 @@
package com.senmesh.common.easyexcel;
import com.google.common.collect.Lists;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.senmesh.common.dto.ExportHeadDetailInfoDTO;
import com.senmesh.common.dto.ExportHeadInfoDTO;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
public class ExcelUtil {
private ExcelUtil() {
}
/**
* 动态导出excel模板
*
* @param reqDto 点播dto
*/
public static void dynamicExportTemplate(ExportHeadInfoDTO reqDto) {
if (CollUtil.isEmpty(reqDto.getHeads())) {
return;
}
ImportDataContext.set("exportInfo", reqDto);
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletResponse response = attr.getResponse();
if (Objects.isNull(response)) {
return;
}
String fileName = reqDto.getFileName() + ".xlsx";
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
String fileNamePrefix = StrUtil.subBefore(fileName, ".", true);
String fileNameSuffix = StrUtil.subAfter(fileName, ".", true);
try {
String fileNamePrefix2 = URLEncoder.encode(fileNamePrefix, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;" + fileNamePrefix2 + "." + fileNameSuffix);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new IllegalArgumentException("下载文件异常");
}
response.addHeader("Param", "no-cache");
response.addHeader("Cache-Control", "no-cache");
try (OutputStream out = response.getOutputStream();) {
ExcelWriter writer = EasyExcel.write(out).registerWriteHandler(new DynamicExportTemplateCellWriteHandler()).build();
List<List> objects = Lists.newArrayList();
objects.add(reqDto.getHeads().stream().map(ExportHeadDetailInfoDTO::getHead).collect(Collectors.toList()));
objects.addAll(reqDto.getDatas());
writer.write(objects, EasyExcel.writerSheet("sheet").build());
writer.finish();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,35 @@
package com.senmesh.common.easyexcel;
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.Objects;
public class ImportDataContext {
public static final ThreadLocal<Map<String, Object>> THREAD_LOCAL_MAP = new ThreadLocal<>();
public static Object get(String key) {
Map<String, Object> stringObjectMap = THREAD_LOCAL_MAP.get();
if (Objects.isNull(stringObjectMap)) {
THREAD_LOCAL_MAP.set(Maps.newHashMap());
return null;
}
return stringObjectMap.get(key);
}
public static void set(String key,Object value) {
Map<String, Object> stringObjectMap = THREAD_LOCAL_MAP.get();
if (Objects.isNull(stringObjectMap)) {
THREAD_LOCAL_MAP.set(Maps.newHashMap());
}
THREAD_LOCAL_MAP.get().put(key,value);
}
public static void putAll(Map<String, Object> extraInfoMap){
Map<String, Object> stringObjectMap = THREAD_LOCAL_MAP.get();
if (Objects.isNull(stringObjectMap)) {
THREAD_LOCAL_MAP.set(Maps.newHashMap());
}
THREAD_LOCAL_MAP.get().putAll(extraInfoMap);
}
}