使用Easyexcel导出数据 设置任一单元格颜色 ,固定列,设置样式,设置公式,一个处理器搞定。
使用
EasyExcel.write(outputStream, MaBillSocialSecurityInfoExcelVo.class)
.registerWriteHandler(new MaBillFormulaHandler(insurePlaceDigitMap, insurePlaceMap, supplementPayConfigMap))
.sheet()
.doWrite(excelVoList);
源码
传进入的三个集合,用于设置公式的取整方式和保留位数。
@Slf4j
public class MaBillFormulaHandler implements RowWriteHandler {
private final short BLUE_HEAD_1 = covertHSSFColor("#305496");
private final short BLUE_HEAD_2 = covertHSSFColor("#00B0F0");
private final short BLUE_BODY_1 = covertHSSFColor("#D9E1F2");
private final short WHITE = covertHSSFColor("#FFFFFF");
private final short ORANGE_HEAD = covertHSSFColor("#FFC000");
private short covertHSSFColor(String color) {
java.awt.Color color1 = java.awt.Color.decode(color);
HSSFWorkbook wb = new HSSFWorkbook();
HSSFPalette palette = wb.getCustomPalette();
return palette.findSimilarColor((byte) color1.getRed(),
(byte) color1.getGreen(), (byte) color1.getBlue()).getIndex();
}
private Map<String, MaBillSocialSecurityInsurePlaceDigit> dataMap;
Map<String, MaBaseProportion> proportionMap;
Map<Short, CellStyle> cellStyleMap;
Map<String, MaSocialSecuritySupplementPayConfig> supplementPayConfigMap;
public MaBillFormulaHandler(Map<String, MaBillSocialSecurityInsurePlaceDigit> dataMap,
Map<String,MaBaseProportion> proportionMap,
Map<String, MaSocialSecuritySupplementPayConfig> supplementPayConfigMap) {
this.dataMap = dataMap;
this.proportionMap = proportionMap;
this.supplementPayConfigMap = supplementPayConfigMap;
this.cellStyleMap= new ConcurrentHashMap<>();
}
private Map<String,Integer> map = new HashMap<>();
@Override
public void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {
Sheet sheet = writeSheetHolder.getSheet();
sheet.createFreezePane(8, 0, 8, 0);
sheet.setAutoFilter(CellRangeAddress.valueOf("1:1"));
}
@Override
public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {
if (isHead){
for (int index = row.getFirstCellNum(); index < row.getLastCellNum(); index++) {
Cell cell = row.getCell(index);
map.put(cell.getStringCellValue(), cell.getColumnIndex());
if(index > 66){
continue;
}
int i = index;
if (i < 13 || i >= 50) {
this.setColor(i, row, BLUE_HEAD_1);
} else if (i == 15 ||i == 18 || i == 23 || i == 27 || i == 31 || i == 34 ||i == 38 || i == 41|| i == 46 || i == 49 ) {
this.setColor(i, row, ORANGE_HEAD);
} else if (i == 19 || i == 28 || i == 35 || i == 42 || i == 43) {
this.setColor(i, row, BLUE_HEAD_2);
} else {
this.setColor(i, row, WHITE);
}
}
}else {
for (int columnIndex = row.getFirstCellNum(); columnIndex < row.getLastCellNum(); columnIndex++) {
if(columnIndex > 66){
continue;
}
if (columnIndex == 4 || columnIndex == 54) {
this.setColor(columnIndex, row, ORANGE_HEAD);
} else if (columnIndex == 19 || columnIndex == 28 || columnIndex == 35 || columnIndex == 42 || columnIndex == 43) {
this.setColor(columnIndex, row, BLUE_BODY_1);
} else {
this.setColor(columnIndex, row, WHITE);
}
}
String name = row.getCell(map.get("参保地")).getStringCellValue();
setIndex(row,"序号");
if (dataMap.containsKey(name)){
MaBaseProportion proportion = proportionMap.get(name);
MaBillSocialSecurityInsurePlaceDigit digit = new MaBillSocialSecurityInsurePlaceDigit();
if (proportionMap.containsKey(name)){
digit = dataMap.get(name);
}
BeanMap digitObjectMap = BeanMap.create(digit);
BeanMap proportionObjectMap = BeanMap.create(proportion);
setMultiplyFormula1(row,digitObjectMap,"pensionUnit","养老企业汇缴","养老企业基数","养老企业比例");
setMultiplyFormula1(row,digitObjectMap,"pensionPerson","养老个人汇缴","养老个人基数","养老个人比例");
setSumFormula(row,digitObjectMap,"pension","养老合计","养老企业汇缴","养老个人汇缴");
setMultiplyFormula2(row,digitObjectMap,"healthUnit","医疗企业汇缴","医疗企业基数","医疗企业比例","医疗企业大病");
setMultiplyFormula2(row,digitObjectMap,"healthPerson","医疗个人汇缴","医疗个人基数","医疗个人比例","医疗个人大病");
setSumFormula(row,digitObjectMap,"health","医疗医疗合计","医疗企业汇缴","医疗个人汇缴");
if (supplementPayConfigMap.get(name).getIllnessPay() == 1){
setIllnessFormula(row,digitObjectMap,"unitIllness",proportionObjectMap,"医疗企业大病","医疗企业基数");
setIllnessFormula(row,digitObjectMap,"personIllness",proportionObjectMap,"医疗个人大病","医疗个人基数");
}
setMultiplyFormula1(row,digitObjectMap,"unemploymentUnit","失业企业汇缴","失业企业基数","失业企业比例");
setMultiplyFormula1(row,digitObjectMap,"unemploymentPerson","失业个人汇缴","失业个人基数","失业个人比例");
setSumFormula(row,digitObjectMap,"unemployment","失业合计","失业企业汇缴","失业个人汇缴");
setMultiplyFormula1(row,digitObjectMap,"procreateUnit","生育企业汇缴","生育企业基数","生育企业比例");
setMultiplyFormula1(row,digitObjectMap,"injuryUnit","工伤企业汇缴","工伤企业基数","工伤企业比例");
setFormula(row,digitObjectMap,"unitAmount","单位社保",new String[]{"养老企业汇缴","医疗企业汇缴","失业企业汇缴","生育企业汇缴","工伤企业汇缴"});
setFormula(row,digitObjectMap,"personAmount","个人社保",new String[]{"养老个人汇缴","医疗个人汇缴","失业个人汇缴"});
setSumFormula(row,digitObjectMap,"socialAmount","社保合计","单位社保","个人社保");
setMultiplyFormula1(row,digitObjectMap,"fundUnit","公积金企业汇缴","公积金企业基数","公积金企业比例");
setMultiplyFormula1(row,digitObjectMap,"fundPerson","公积金个人汇缴","公积金个人基数","公积金个人比例");
setSumFormula(row,digitObjectMap,"fundAmount","公积金合计","公积金企业汇缴","公积金个人汇缴");
if (proportion.getDisabilityBenefitRule().equals(MaSocialSecurityDisabilityBenefitRule.PROPORTIONAL_CHARGE.rule)){
setDisabilityBenefitFormula(row,digitObjectMap,proportion,"disability","残保金","养老企业基数");
}
setFormula(row,digitObjectMap,"subtotal","小计",new String[]{"社保合计","公积金合计","残保金","采暖费","滞纳金","其它费用"});
setFormula(row,digitObjectMap,"total","合计",new String[]{"小计","服务费","服务费增值税"});
setAgeFormula(row,"年龄","身份证号");
setSexFormula(row,"性别","身份证号");
}
}
}
private void setColor(Integer index, Row row, short colorIndex) {
Cell cell = row.getCell(index);
if(Objects.isNull(cell)){
return;
}
SXSSFSheet sheet = (SXSSFSheet) row.getSheet();
sheet.trackAllColumnsForAutoSizing();
sheet.autoSizeColumn(0);
// sheet.setColumnWidth(index,70);
CellStyle cellStyle;
if (cellStyleMap.containsKey(colorIndex)) {
cellStyle = cellStyleMap.get(colorIndex);
} else {
Workbook workbook = sheet.getWorkbook();
cellStyle = workbook.createCellStyle();
cellStyleMap.put(colorIndex, cellStyle);
cellStyle.setFillForegroundColor(colorIndex);
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyle.setAlignment(HorizontalAlignment.CENTER.CENTER);
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
if (colorIndex == BLUE_HEAD_1) {
Font font = workbook.createFont();
font.setColor(IndexedColors.WHITE.index);
cellStyle.setFont(font);
} else {
Font font = workbook.createFont();
font.setColor(IndexedColors.BLACK.index);
cellStyle.setFont(font);
}
}
if(index == 4 && row.getRowNum() != 0) {
String name = row.getCell(index).getStringCellValue();
if (!"补缴".equals(name)) {
cellStyle = cellStyleMap.get(WHITE);
}
}
row.getCell(index).setCellStyle(cellStyle);
row.setHeightInPoints(20);
}
public void setIndex(Row row,String name){
Cell cell = row.getCell(map.get(name));
int rowNum = row.getRowNum();
cell.setCellValue(rowNum);
}
public void setMultiplyFormula1(Row row,BeanMap objectMap,String name,String amount,String base,String ratio){
Cell cell = row.getCell(map.get(amount));
int rowNum = row.getRowNum()+1;
String formula = getWay((Integer) objectMap.get(name+"Way"))+"("+getColumnName(map.get(base)+1)+rowNum+"*"+getColumnName(map.get(ratio)+1)+rowNum+","+objectMap.get(name+"Digit")+")";
cell.setCellFormula(formula);
}
public void setMultiplyFormula2(Row row,BeanMap objectMap,String name,String amount,String base,String ratio,String illness){
Cell cell = row.getCell(map.get(amount));
int rowNum = row.getRowNum()+1;
String formula = getWay((Integer) objectMap.get(name+"Way"))+"("+getColumnName(map.get(base)+1)+rowNum+"*"+getColumnName(map.get(ratio)+1)+rowNum+","+objectMap.get(name+"Digit")+")"+"+"+getColumnName(map.get(illness)+1)+rowNum;
cell.setCellFormula(formula);
}
public void setSumFormula(Row row,BeanMap objectMap,String name,String amount,String amount1,String amount2){
Cell cell = row.getCell(map.get(amount));
int rowNum = row.getRowNum()+1;
String formula = getWay((Integer) objectMap.get(name+"Way"))+"("+getColumnName(map.get(amount1)+1)+rowNum+"+"+getColumnName(map.get(amount2)+1)+rowNum+","+objectMap.get(name+"Digit")+")";
cell.setCellFormula(formula);
}
public void setAgeFormula(Row row,String age,String idNumber) {
Cell cell = row.getCell(map.get(age));
int rowNum = row.getRowNum() + 1;
String formula = "DATEDIF(TEXT(MID(" + getColumnName(map.get(idNumber) + 1) + rowNum + ",7,8),\"#-00-00\"),NOW(),\"y\")&\"岁\"&DATEDIF(TEXT(MID(" + getColumnName(map.get(idNumber) + 1) + rowNum + ",7,8),\"#-00-00\"),NOW(),\"ym\")&\"月\"&DATEDIF(TEXT(MID(" + getColumnName(map.get(idNumber) + 1) + rowNum + ",7,8),\"#-00-00\"),NOW(),\"md\")&\"日\"";
cell.setCellFormula(formula);
}
public void setDisabilityBenefitFormula(Row row,BeanMap objectMap,MaBaseProportion proportion , String name,String disabilityBenefit,String pensionUnitBase){
Cell cell = row.getCell(map.get(disabilityBenefit));
int rowNum = row.getRowNum()+1;
String formula = getWay((Integer) objectMap.get(name+"Way"))+"("+getColumnName(map.get(pensionUnitBase)+1)+rowNum+"*"+proportion.getDisabilityBenefit()+","+objectMap.get(name+"Digit")+")";
cell.setCellFormula(formula);
}
public void setIllnessFormula(Row row,BeanMap objectMap,String name,BeanMap proportion,String illness,String base){
Cell cell = row.getCell(map.get(illness));
int rowNum = row.getRowNum()+1;
String ratio = (String) proportion.get(name);
if (ratio.contains("%")){
String formula = getWay((Integer) objectMap.get(name+"Way"))+"("+getColumnName(map.get(base)+1)+rowNum+"*"+getHealthIllness(ratio)+","+objectMap.get(name+"Digit")+")";
cell.setCellFormula(formula);
}
}
public void setSexFormula(Row row,String sex,String idNumber){
Cell cell = row.getCell(map.get(sex));
int rowNum = row.getRowNum()+1;
String formula = "IF(MOD(MID("+getColumnName(map.get(idNumber)+1)+rowNum+",17,1),2),\"男\",\"女\")";
cell.setCellFormula(formula);
}
public void setFormula(Row row,BeanMap objectMap,String name,String amount ,String [] params){
Cell cell = row.getCell(map.get(amount));
int rowNum = row.getRowNum()+1;
StringBuilder formula = new StringBuilder(getWay((Integer) objectMap.get(name+"Way")) + "(");
for (String s : params) {
formula.append("+").append(getColumnName(map.get(s) + 1)).append(rowNum);
}
formula.append(",").append(objectMap.get(name+"Digit")).append(")");
cell.setCellFormula(formula.toString());
}
public String getWay(Integer way){
if (way == 1){
return "ROUNDDOWN";
}
if (way == 2){
return "ROUND";
}
if (way == 3){
return "ROUNDUP";
}
return "0";
}
public static String getColumnName(int columnIndex) {
StringBuilder columnNameBuilder = new StringBuilder();
while (columnIndex > 0) {
int remainder = columnIndex % 26;
if (remainder == 0) {
columnNameBuilder.append('Z');
columnIndex = (columnIndex / 26) - 1;
} else {
columnNameBuilder.append((char) ('A' + remainder - 1));
columnIndex = columnIndex / 26;
}
}
return columnNameBuilder.reverse().toString();
}
private String getHealthIllness(String healthIllness) {
//提取数字和百分比的正则表达式模式
String pattern = "\\d*\\.?\\d*%?";
String percent = "%";
// 创建 Pattern 对象
Pattern regexPattern = Pattern.compile(pattern);
// 创建 Matcher 对象
Matcher matcher = regexPattern.matcher(healthIllness);
// 查找匹配的数字和百分比
while (matcher.find()) {
// 提取整个匹配的内容,包括百分比符号
String match = matcher.group();
if (isNotBlank(match)) {
if (match.contains(percent)) {
//带百分号,百分比数据
return match;
}
}
}
return "";
}
}