|
|
@ -3,22 +3,32 @@ package com.ruoyi.common.utils.poi; |
|
|
|
import cn.hutool.core.collection.CollUtil; |
|
|
|
import cn.hutool.core.convert.Convert; |
|
|
|
import cn.hutool.core.date.DateUtil; |
|
|
|
import cn.hutool.core.io.IoUtil; |
|
|
|
import cn.hutool.core.util.ObjectUtil; |
|
|
|
import cn.hutool.core.util.StrUtil; |
|
|
|
import com.ruoyi.common.annotation.Excel; |
|
|
|
import com.ruoyi.common.utils.DictUtils; |
|
|
|
import org.apache.poi.ss.usermodel.*; |
|
|
|
import org.apache.poi.util.IOUtils; |
|
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
|
|
|
import org.slf4j.Logger; |
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import java.io.Closeable; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.UnsupportedEncodingException; |
|
|
|
import java.lang.reflect.Field; |
|
|
|
import java.net.URLEncoder; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.*; |
|
|
|
|
|
|
|
public class ExcelMultipleSheetsUtil { |
|
|
|
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); |
|
|
|
|
|
|
|
/** |
|
|
|
* 样式列表 |
|
|
|
*/ |
|
|
|
private Map<String, CellStyle> styles; |
|
|
|
|
|
|
|
/** |
|
|
|
* 导出excel:可多个sheet页 |
|
|
@ -29,9 +39,11 @@ public class ExcelMultipleSheetsUtil { |
|
|
|
* @param response 响应 |
|
|
|
* @throws IOException 异常 |
|
|
|
*/ |
|
|
|
public static void excelMultipleSheets(Map<String, Object> data, String excelFileName, String suffixName, HttpServletResponse response) throws IOException { |
|
|
|
public void excelMultipleSheets(Map<String, Object> data, String excelFileName, String suffixName, HttpServletResponse response) { |
|
|
|
|
|
|
|
// 创建工作簿
|
|
|
|
try (Workbook workbook = new XSSFWorkbook()) { |
|
|
|
Workbook workbook = new XSSFWorkbook(); |
|
|
|
this.styles = createStyles(workbook); |
|
|
|
for (Map.Entry<String, Object> entry : data.entrySet()) { |
|
|
|
String sheetName = entry.getKey(); |
|
|
|
Object sheetData = entry.getValue(); |
|
|
@ -40,10 +52,14 @@ public class ExcelMultipleSheetsUtil { |
|
|
|
createSheetWithData(sheet, sheetData); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
setResponseHeader(response, excelFileName, suffixName); |
|
|
|
// 写出文件
|
|
|
|
try { |
|
|
|
workbook.write(response.getOutputStream()); |
|
|
|
} catch (IOException e) { |
|
|
|
log.error("导出Excel异常{}", e.getMessage()); |
|
|
|
}finally { |
|
|
|
IOUtils.closeQuietly(workbook); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -53,7 +69,7 @@ public class ExcelMultipleSheetsUtil { |
|
|
|
* @param sheet 表单 |
|
|
|
* @param data 数据 |
|
|
|
*/ |
|
|
|
private static void createSheetWithData(Sheet sheet, Object data) { |
|
|
|
private void createSheetWithData(Sheet sheet, Object data) { |
|
|
|
if (data instanceof List) { |
|
|
|
createSheetWithListData(sheet, (List<?>) data); |
|
|
|
} else { |
|
|
@ -67,7 +83,7 @@ public class ExcelMultipleSheetsUtil { |
|
|
|
* @param sheet 表单 |
|
|
|
* @param dataList 数据列表 |
|
|
|
*/ |
|
|
|
private static void createSheetWithListData(Sheet sheet, List<?> dataList) { |
|
|
|
private void createSheetWithListData(Sheet sheet, List<?> dataList) { |
|
|
|
if (CollUtil.isNotEmpty(dataList)) { |
|
|
|
Object firstItem = dataList.get(0); |
|
|
|
createHeaderRow(sheet, firstItem.getClass()); |
|
|
@ -84,7 +100,7 @@ public class ExcelMultipleSheetsUtil { |
|
|
|
* @param sheet 表单 |
|
|
|
* @param data 数据 |
|
|
|
*/ |
|
|
|
private static void createSheetWithObjectData(Sheet sheet, Object data) { |
|
|
|
private void createSheetWithObjectData(Sheet sheet, Object data) { |
|
|
|
createHeaderRow(sheet, data.getClass()); |
|
|
|
createDataRow(sheet, data, 1); |
|
|
|
} |
|
|
@ -95,13 +111,13 @@ public class ExcelMultipleSheetsUtil { |
|
|
|
* @param sheet 表单 |
|
|
|
* @param clazz 数据类 |
|
|
|
*/ |
|
|
|
private static void createHeaderRow(Sheet sheet, Class<?> clazz) { |
|
|
|
private void createHeaderRow(Sheet sheet, Class<?> clazz) { |
|
|
|
// 创建单元格样式
|
|
|
|
CellStyle headerCellStyle = createCellStyle(sheet.getWorkbook()); |
|
|
|
|
|
|
|
//CellStyle headerCellStyle = createCellStyle(sheet.getWorkbook());
|
|
|
|
CellStyle headerCellStyle = this.styles.get("header"); |
|
|
|
// 创建标题行
|
|
|
|
Row headerRow = sheet.createRow(0); |
|
|
|
Field[] fields = clazz.getDeclaredFields(); |
|
|
|
Field[] fields = getFields(clazz); |
|
|
|
for (int i = 0; i < fields.length; i++) { |
|
|
|
createHeaderCell(sheet, headerCellStyle, fields, headerRow, i); |
|
|
|
} |
|
|
@ -114,25 +130,36 @@ public class ExcelMultipleSheetsUtil { |
|
|
|
* @param data 数据 |
|
|
|
* @param rowIndex 行号 |
|
|
|
*/ |
|
|
|
private static void createDataRow(Sheet sheet, Object data, int rowIndex) { |
|
|
|
private void createDataRow(Sheet sheet, Object data, int rowIndex) { |
|
|
|
// 创建单元格样式
|
|
|
|
CellStyle dataCellStyle = createCellStyle(sheet.getWorkbook()); |
|
|
|
|
|
|
|
//CellStyle dataCellStyle = createCellStyle(sheet.getWorkbook());
|
|
|
|
CellStyle dataCellStyle = this.styles.get("data"); |
|
|
|
// 创建数据行
|
|
|
|
Row dataRow = sheet.createRow(rowIndex); |
|
|
|
Field[] fields = data.getClass().getDeclaredFields(); |
|
|
|
Field[] fields = getFields(data.getClass()); |
|
|
|
for (int i = 0; i < fields.length; i++) { |
|
|
|
createDataCell(dataCellStyle,fields, dataRow, i, data); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private Field[] getFields(Class<?> clazz) { |
|
|
|
List<Field> fieldList = new ArrayList<>(); |
|
|
|
Field[] fields = clazz.getDeclaredFields(); |
|
|
|
for (Field field : fields) { |
|
|
|
if (field.isAnnotationPresent(Excel.class)) { |
|
|
|
fieldList.add(field); |
|
|
|
} |
|
|
|
} |
|
|
|
return fieldList.toArray(new Field[0]); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 创建单元格样式 |
|
|
|
* |
|
|
|
* @param workbook 工作簿 |
|
|
|
* @return 单元格样式 |
|
|
|
*/ |
|
|
|
private static CellStyle createCellStyle(Workbook workbook) { |
|
|
|
private CellStyle createCellStyle(Workbook workbook) { |
|
|
|
CellStyle cellStyle = workbook.createCellStyle(); |
|
|
|
|
|
|
|
// 设置 水平和垂直 居中对齐
|
|
|
@ -167,7 +194,7 @@ public class ExcelMultipleSheetsUtil { |
|
|
|
* @param headerRow 标题行 |
|
|
|
* @param i 序号 |
|
|
|
*/ |
|
|
|
private static void createHeaderCell(Sheet sheet, CellStyle headerCellStyle, Field[] fields, Row headerRow, int i) { |
|
|
|
private void createHeaderCell(Sheet sheet, CellStyle headerCellStyle, Field[] fields, Row headerRow, int i) { |
|
|
|
// 默认宽度
|
|
|
|
double width = 16; |
|
|
|
Excel excelAnnotation = fields[i].getAnnotation(Excel.class); |
|
|
@ -194,7 +221,7 @@ public class ExcelMultipleSheetsUtil { |
|
|
|
* @param i 序号 |
|
|
|
* @param data 数据 |
|
|
|
*/ |
|
|
|
private static void createDataCell(CellStyle dataCellStyle, Field[] fields, Row dataRow, int i, Object data) { |
|
|
|
private void createDataCell(CellStyle dataCellStyle, Field[] fields, Row dataRow, int i, Object data) { |
|
|
|
Cell cell = dataRow.createCell(i); |
|
|
|
cell.setCellStyle(dataCellStyle); |
|
|
|
|
|
|
@ -214,7 +241,7 @@ public class ExcelMultipleSheetsUtil { |
|
|
|
* @param field 字段 |
|
|
|
* @param value 值 |
|
|
|
*/ |
|
|
|
private static void handleAnnotationAndSetValue(Cell cell, Field field, Object value) { |
|
|
|
private void handleAnnotationAndSetValue(Cell cell, Field field, Object value) { |
|
|
|
if (field.isAnnotationPresent(Excel.class) && field.getAnnotation(Excel.class).dictType().length() > 0) { |
|
|
|
value = DictUtils.getDictLabel(field.getAnnotation(Excel.class).dictType(), String.valueOf(value)); |
|
|
|
} |
|
|
@ -232,9 +259,79 @@ public class ExcelMultipleSheetsUtil { |
|
|
|
* @param suffixName 后缀名 |
|
|
|
* @throws UnsupportedEncodingException 编码异常 |
|
|
|
*/ |
|
|
|
private static void setResponseHeader(HttpServletResponse response, String excelFileName, String suffixName) throws UnsupportedEncodingException { |
|
|
|
private void setResponseHeader(HttpServletResponse response, String excelFileName, String suffixName) { |
|
|
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); |
|
|
|
try { |
|
|
|
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(excelFileName + suffixName, "utf-8")); |
|
|
|
} catch (UnsupportedEncodingException e) { |
|
|
|
log.error("下载文件名编码格式错误,文件名:" + excelFileName); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 创建表格样式 |
|
|
|
* |
|
|
|
* @param wb 工作薄对象 |
|
|
|
* @return 样式列表 |
|
|
|
*/ |
|
|
|
private Map<String, CellStyle> createStyles(Workbook wb) |
|
|
|
{ |
|
|
|
// 写入各条记录,每条记录对应excel表中的一行
|
|
|
|
Map<String, CellStyle> styles = new HashMap<String, CellStyle>(); |
|
|
|
CellStyle style = wb.createCellStyle(); |
|
|
|
style.setAlignment(HorizontalAlignment.CENTER);//单元格水平对齐方式
|
|
|
|
style.setVerticalAlignment(VerticalAlignment.CENTER);//单元格垂直对齐方式
|
|
|
|
Font titleFont = wb.createFont(); |
|
|
|
titleFont.setFontName("Arial");//字体
|
|
|
|
titleFont.setFontHeightInPoints((short) 16);//字号
|
|
|
|
titleFont.setBold(true);//加粗
|
|
|
|
style.setFont(titleFont);//设置字体
|
|
|
|
styles.put("title", style); |
|
|
|
|
|
|
|
style = wb.createCellStyle(); |
|
|
|
style.setAlignment(HorizontalAlignment.CENTER);//单元格水平对齐方式
|
|
|
|
style.setVerticalAlignment(VerticalAlignment.CENTER);//单元格垂直对齐方式
|
|
|
|
style.setBorderRight(BorderStyle.THIN);//右边框细线
|
|
|
|
style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());//右边框颜色
|
|
|
|
style.setBorderLeft(BorderStyle.THIN);//左边框细线
|
|
|
|
style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());//左边框颜色
|
|
|
|
style.setBorderTop(BorderStyle.THIN);//上边框细线
|
|
|
|
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());//上边框颜色
|
|
|
|
style.setBorderBottom(BorderStyle.THIN); //下边框细线
|
|
|
|
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());//下边框颜色
|
|
|
|
Font dataFont = wb.createFont(); |
|
|
|
dataFont.setFontName("Arial");//字体
|
|
|
|
dataFont.setFontHeightInPoints((short) 10);//字号
|
|
|
|
style.setFont(dataFont);//设置字体
|
|
|
|
styles.put("data", style); |
|
|
|
|
|
|
|
style = wb.createCellStyle(); |
|
|
|
style.cloneStyleFrom(styles.get("data")); |
|
|
|
style.setAlignment(HorizontalAlignment.CENTER); |
|
|
|
style.setVerticalAlignment(VerticalAlignment.CENTER); |
|
|
|
style.setFillForegroundColor(IndexedColors.BLUE_GREY.getIndex());//填充前景色为25%灰色
|
|
|
|
style.setFillPattern(FillPatternType.SOLID_FOREGROUND); |
|
|
|
Font headerFont = wb.createFont(); |
|
|
|
headerFont.setFontName("Arial"); |
|
|
|
headerFont.setFontHeightInPoints((short) 12); |
|
|
|
headerFont.setBold(true); |
|
|
|
headerFont.setColor(IndexedColors.WHITE.getIndex()); |
|
|
|
style.setFont(headerFont); |
|
|
|
styles.put("header", style); |
|
|
|
|
|
|
|
style = wb.createCellStyle(); |
|
|
|
style.setAlignment(HorizontalAlignment.CENTER); |
|
|
|
style.setVerticalAlignment(VerticalAlignment.CENTER); |
|
|
|
Font totalFont = wb.createFont(); |
|
|
|
totalFont.setFontName("Arial"); |
|
|
|
totalFont.setFontHeightInPoints((short) 10); |
|
|
|
style.setFont(totalFont); |
|
|
|
styles.put("total", style); |
|
|
|
|
|
|
|
//styles.putAll(annotationStyles(wb));
|
|
|
|
|
|
|
|
return styles; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|