故障修复,新增列表导出功能

This commit is contained in:
daiqy88
2025-11-20 09:45:04 +08:00
parent d94a7778af
commit d24a6214b9
21 changed files with 361 additions and 17 deletions

View File

@@ -0,0 +1,24 @@
package com.sdm.common.entity;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.springframework.http.codec.json.Jackson2SmileDecoder;
@Data
public class ExportExcelFormat {
@Schema(description = "表属性值")
@NotNull(message = "表属性值不能为空")
private String key;
@Schema(description = "excel表头")
@NotNull(message = "excel表头不能为空")
private String title;
@Schema(description = "属性值对应的字典编码")
private String dictCode;
@Schema(description = "字典值")
private JSONObject dictData;
}

View File

@@ -0,0 +1,13 @@
package com.sdm.common.utils.excel;
import lombok.Data;
@Data
public class ExcelCellValue {
private Object value = "";
private String valueType; //string or num
private boolean isMerge;
private Object mergeValue;
private int firstRow;
private int lastRow;
}

View File

@@ -0,0 +1,15 @@
package com.sdm.common.utils.excel;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class ExcelSheet {
private String sheetName;
private List<HeadVO> heads = new ArrayList<HeadVO>();
private List<RowValue> rowValues = new ArrayList<>();
}

View File

@@ -2,12 +2,21 @@ package com.sdm.common.utils.excel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.sdm.common.entity.ExportExcelFormat;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
@@ -93,4 +102,175 @@ public class ExcelUtil {
return list;
}
private static class ColumnMergeInfo
{
public int beginColumn;
public int endColumn;
}
/**
* 写excel表头
* @param headerData
* @return
*/
private static List<ColumnMergeInfo> writeSheetHeader(Workbook workbook,Sheet sheet,List<HeadVO> headerData)
{
Row headRow = sheet.createRow(0);
headRow.setHeight((short) -1);
Font font = makeFont(workbook,"微软雅黑",true,(short) 12,IndexedColors.BLACK.getIndex());
CellStyle headerStyle = makeStyle(workbook,font,BorderStyle.THIN);
headerStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
List<ColumnMergeInfo> mergeInfos = new ArrayList<>();
int cellIndex = 0;
for(HeadVO headVO : headerData)
{
Cell cell = headRow.createCell(cellIndex);
cell.setCellStyle(headerStyle);
cell.setCellValue(headVO.getKey());
sheet.autoSizeColumn(cellIndex);
cellIndex++;
}
return mergeInfos;
}
/**
* 写入excel行数据
* @param sheet
* @param rowValues
*/
private static void writeSheetRows(Workbook workbook,Sheet sheet,List<RowValue> rowValues,List<ColumnMergeInfo> columnMergeInfos)
{
int rowIndex = 1;
Map<String, CellRangeAddress> cellRangeAddressHashMap = new HashMap<>();
Font cellFont = makeFont(workbook,"宋体",false,(short) 11,IndexedColors.BLACK.getIndex());
CellStyle cellStyle = makeStyle(workbook,cellFont,BorderStyle.THIN);
for(RowValue rowValue : rowValues)
{
Row row = sheet.createRow(rowIndex);
int columnIndex = 0;
for(ExcelCellValue cellValue : rowValue.getCells())
{
Cell cell = row.createCell(columnIndex);
cell.setCellStyle(cellStyle);
cell.setCellValue(String.valueOf(cellValue.getValue()));
if(cellValue.isMerge())
{
String rangekey = cellValue.getFirstRow()+"-"+cellValue.getLastRow()+"-"+columnIndex;
if(!cellRangeAddressHashMap.containsKey(rangekey))
{
CellRangeAddress rangeAddress = new CellRangeAddress(cellValue.getFirstRow(),cellValue.getLastRow(),columnIndex,columnIndex);
cellRangeAddressHashMap.put(rangekey,rangeAddress);
}
}
columnIndex++;
}
rowIndex++;
}
cellRangeAddressHashMap.values().forEach(sheet::addMergedRegion);
}
/**
* 获取字体
* @param fontName
* @param isBold
* @param fontSize
* @return
*/
private static Font makeFont(Workbook workbook,String fontName,boolean isBold,short fontSize,short colorIndex)
{
Font font = workbook.createFont();
font.setBold(isBold);
font.setFontHeightInPoints(fontSize);
font.setFontName(fontName);
font.setColor(colorIndex);
return font;
}
/**
* 创建单元格风格
* @param workbook
* @param font
* @param
* @param borderStyle
* @return
*/
private static CellStyle makeStyle(Workbook workbook,Font font,BorderStyle borderStyle)
{
CellStyle style = workbook.createCellStyle();
style.setBorderBottom(borderStyle);
style.setBorderLeft(borderStyle);
style.setBorderTop(borderStyle);
style.setBorderRight(borderStyle);
style.setFont(font);
return style;
}
/**
* 导出excel
* @param sheets
* @param response
*/
public static void exportExcel(List<ExcelSheet> sheets, HttpServletResponse response) {
try {
Workbook workBook = new XSSFWorkbook();
for (ExcelSheet sheetData : sheets) {
Sheet sheet = workBook.createSheet(sheetData.getSheetName());
List<ColumnMergeInfo> columnMergeInfos = writeSheetHeader(workBook,sheet, sheetData.getHeads());
writeSheetRows(workBook,sheet, sheetData.getRowValues(), columnMergeInfos);
}
workBook.write(response.getOutputStream());
workBook.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
/**
* 导出没有合并单元格excel
* @param dataArray
* @param exportExcelFormats
*/
public static void exportExcelNoMerge(JSONArray dataArray,List<ExportExcelFormat> exportExcelFormats,HttpServletResponse response)
{
ExcelSheet excelSheet = new ExcelSheet();
excelSheet.setSheetName("export sheet1");
//获取excel表头
List<HeadVO> excelHeader = new ArrayList<>();
for(ExportExcelFormat exportExcelFormat : exportExcelFormats)
{
HeadVO headVO = HeadVO.builder().build();
headVO.setKey(exportExcelFormat.getTitle());
excelHeader.add(headVO);
}
excelSheet.setHeads(excelHeader);
//获取excel表行数据
for(int index=0;index<dataArray.size();index++)
{
JSONObject rowObj = dataArray.getJSONObject(index);
RowValue rowValue = new RowValue();
for (ExportExcelFormat exportExcelFormat : exportExcelFormats)
{
ExcelCellValue cellValue = new ExcelCellValue();
String value = rowObj.getString(exportExcelFormat.getKey());
if(value != null && !"null".equalsIgnoreCase(value)) {
JSONObject dictData = exportExcelFormat.getDictData();
if(dictData != null)
{
value = dictData.getString(value);
}
cellValue.setValue(value);
}
rowValue.getCells().add(cellValue);
}
excelSheet.getRowValues().add(rowValue);
}
List<ExcelSheet> excelSheets = new ArrayList<>();
excelSheets.add(excelSheet);
exportExcel(excelSheets,response);
}
}

View File

@@ -3,6 +3,7 @@ package com.sdm.common.utils.excel;
import lombok.Builder;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
@@ -11,7 +12,7 @@ public class HeadVO implements Comparable<HeadVO> {
/**
* 列头名
*/
private List<String> headTitle;
private List<String> headTitle = new ArrayList<>();
/**
* 字段名
*/

View File

@@ -0,0 +1,12 @@
package com.sdm.common.utils.excel;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class RowValue {
private List<ExcelCellValue> cells = new ArrayList<ExcelCellValue>();
}