2019独角兽企业重金招聘Python工程师标准>>>
import com.mwkj.common.log.LogFactory;
import com.mwkj.common.log.LoggerUtil;
import com.mwkj.common.resp.ResponseMessage;
import com.mwkj.common.util.StringUtils;
import com.mwkj.web.util.ReflectionUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
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.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
/**
* 作者:
* 日期:2018-04-26
* 功能:Excel导出工具类
*/
public class ExcelUtils {
private static LoggerUtil logger = LogFactory.getLogger(ExcelUtils.class);
private static SXSSFWorkbook wb;
private static CellStyle titleStyle; // 标题行样式
private static Font titleFont; // 标题行字体
private static CellStyle dateStyle; // 日期行样式
private static Font dateFont; // 日期行字体
private static CellStyle headStyle; // 表头行样式
private static Font headFont; // 表头行字体
private static CellStyle contentStyle; // 内容行样式
private static Font contentFont; // 内容行字体
private static String REPALCESTR = ""; // 转为空字符
/**
* @param fileName
* @param response
* @param setInfo
* @param hasIndex 是否添加序列号
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @Description: 将Map里的集合对象数据输出Excel数据流
*/
public static ResponseMessage export2Excel(String fileName, HttpServletResponse response, ExportSetInfo setInfo, boolean hasIndex)
throws IOException, IllegalArgumentException, IllegalAccessException {
logger.info("开始导出" + fileName + ".xlsx文件");
response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
if (null == setInfo.getObjsMap()) {
wb.write(response.getOutputStream());
return ResponseMessage.successResponse(wb);
}
try {
init();
Set> set = setInfo.getObjsMap().entrySet();
String[] sheetNames = new String[setInfo.getObjsMap().size()];
int sheetNameNum = 0;
for (Entry entry : set) {
sheetNames[sheetNameNum] = ((String) entry.getKey());
sheetNameNum++;
}
SXSSFSheet[] sheets = getSheets(setInfo.getObjsMap().size(), sheetNames);
int sheetNum = 0;
for (Entry entry : set) {
// Sheet
List objs = (List) entry.getValue();
// 标题行
createTableTitleRow(setInfo, sheets, sheetNum, false);
// 日期行
createTableDateRow(setInfo, sheets, sheetNum, false);
// 表头
creatTableHeadRow(setInfo, sheets, sheetNum, false);
// 表体
String[] fieldNames = (String[]) setInfo.getFieldNames().get(sheetNum);
int rowNum = 3;
for (Object obj : objs) {
SXSSFRow contentRow = sheets[sheetNum].createRow(rowNum);
contentRow.setHeight((short) 300);
SXSSFCell[] cells = getCells(contentRow, ((String[]) setInfo.getFieldNames().get(sheetNum)).length, false);
int cellNum = hasIndex ? 1 : 0;// 去掉一列序号,因此从1开始
if (fieldNames != null) {
for (int num = 0; num < fieldNames.length; num++) {
Object value = null;
if ((obj instanceof Map)) {
value = ((Map) obj).get(fieldNames[num]);
} else {
value = ReflectionUtils.invokeGetterMethod(obj, fieldNames[num]);
}
cells[cellNum].setCellValue(value == null ? REPALCESTR : StringUtils.isBlank(value.toString()) ? REPALCESTR : value.toString());
cellNum++;
}
}
rowNum++;
}
adjustColumnSize(sheets, sheetNum, fieldNames);// 自动调整列宽
sheetNum++;
}
wb.write(response.getOutputStream());
return ResponseMessage.successResponse(wb);
} catch (Exception e) {
logger.info("导出Excel异常", e);
throw e;
} finally {
try {
if (wb != null) {
wb.close();
}
response.getOutputStream().close();
} catch (Exception e) {
logger.info("导出Excel异常", e);
throw e;
}
}
}
/**
* @Description: 初始化
*/
private static void init() {
wb = new SXSSFWorkbook();
titleFont = wb.createFont();
titleStyle = wb.createCellStyle();
dateStyle = wb.createCellStyle();
dateFont = wb.createFont();
headStyle = wb.createCellStyle();
headFont = wb.createFont();
contentStyle = wb.createCellStyle();
contentFont = wb.createFont();
initTitleCellStyle();
initTitleFont();
initDateCellStyle();
initDateFont();
initHeadCellStyle();
initHeadFont();
initContentCellStyle();
initContentFont();
}
/**
* @Description: 自动调整列宽
*/
private static void adjustColumnSize(SXSSFSheet[] sheets, int sheetNum, String[] fieldNames) {
for (int i = 0; i < fieldNames.length + 1; i++) {
sheets[sheetNum].trackColumnForAutoSizing(i);
sheets[sheetNum].autoSizeColumn(i, true);
/* 实际宽度 */
int curColWidth = 0;
/* 默认宽度 */
int[] defaultColWidth = { 2000, 2500, 3000, 3500, 4000, 4500 };
/* 实际宽度 < 默认宽度的时候、设置为默认宽度 */
for (int j = 0; j < 6; j++) {
curColWidth = sheets[sheetNum].getColumnWidth(i);
if (curColWidth < defaultColWidth[j]) {
sheets[sheetNum].setColumnWidth(i, defaultColWidth[j]);
break;
}
}
}
}
/**
* @Description: 创建标题行(需合并单元格)
*/
private static void createTableTitleRow(ExportSetInfo setInfo, SXSSFSheet[] sheets, int sheetNum, boolean withoutRownum) {
int length = ((String[]) setInfo.getFieldNames().get(sheetNum)).length;
if (withoutRownum) {
length -= 1;
}
CellRangeAddress titleRange = new CellRangeAddress(0, 0, 0, length);
sheets[sheetNum].addMergedRegion(titleRange);
SXSSFRow titleRow = sheets[sheetNum].createRow(0);
titleRow.setHeight((short) 800);
SXSSFCell titleCell = titleRow.createCell(0);
titleCell.setCellStyle(titleStyle);
titleCell.setCellValue(setInfo.getTitles()[sheetNum]);
}
/**
* @Description: 创建日期行(需合并单元格)
*/
private static void createTableDateRow(ExportSetInfo setInfo, SXSSFSheet[] sheets, int sheetNum, boolean withoutRownum) {
int length = ((String[]) setInfo.getFieldNames().get(sheetNum)).length;
if (withoutRownum) {
length -= 1;
}
CellRangeAddress dateRange = new CellRangeAddress(1, 1, 0, length);
sheets[sheetNum].addMergedRegion(dateRange);
SXSSFRow dateRow = sheets[sheetNum].createRow(1);
dateRow.setHeight((short) 350);
SXSSFCell dateCell = dateRow.createCell(0);
dateCell.setCellStyle(dateStyle);
dateCell.setCellValue(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
}
/**
* @Description: 创建表头行(需合并单元格)
*/
private static void creatTableHeadRow(ExportSetInfo setInfo, SXSSFSheet[] sheets, int sheetNum, boolean withoutRownum) {
int num = 1;
if (withoutRownum) {
num = 0;
}
// 表头
SXSSFRow headRow = sheets[sheetNum].createRow(2);
headRow.setHeight((short) 350);
if (!withoutRownum) {
// 列头名称
SXSSFCell snCell = headRow.createCell(0);
snCell.setCellStyle(headStyle);
snCell.setCellValue("序号");
}
int length = ((String[]) setInfo.getFieldNames().get(sheetNum)).length;
// 列头名称
for (int i = 0; i < length; i++) {
SXSSFCell headCell = headRow.createCell(num + i);
headCell.setCellStyle(headStyle);
headCell.setCellValue(((String[]) setInfo.getHeadNames().get(sheetNum))[i]);
}
}
/**
* @Description: 创建所有的Sheet
*/
private static SXSSFSheet[] getSheets(int num, String[] names) {
SXSSFSheet[] sheets = new SXSSFSheet[num];
for (int i = 0; i < num; i++) {
sheets[i] = wb.createSheet(names[i]);
}
return sheets;
}
/**
* @Description: 创建内容行的每一列(附加一列序号)
*/
private static SXSSFCell[] getCells(SXSSFRow contentRow, int num, boolean withoutRownum) {
if (!withoutRownum) {
num += 1;
}
SXSSFCell[] cells = new SXSSFCell[num];
int i = 0;
for (int len = cells.length; i < len; i++) {
cells[i] = contentRow.createCell(i);
cells[i].setCellStyle(contentStyle);
}
// 设置序号列值,因为出去标题行和日期行,所有-2
cells[0].setCellValue(contentRow.getRowNum() - 2);
return cells;
}
/**
* @Description: 初始化标题行样式
*/
private static void initTitleCellStyle() {
titleStyle.setAlignment(HorizontalAlignment.CENTER);
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
titleStyle.setFont(titleFont);
titleStyle.setFillBackgroundColor(IndexedColors.SKY_BLUE.index);
}
/**
* @Description: 初始化日期行样式
*/
private static void initDateCellStyle() {
dateStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION);
dateStyle.setVerticalAlignment(VerticalAlignment.CENTER);
dateStyle.setFont(dateFont);
dateStyle.setFillBackgroundColor(IndexedColors.SKY_BLUE.index);
}
/**
* @Description: 初始化表头行样式
*/
private static void initHeadCellStyle() {
headStyle.setAlignment(HorizontalAlignment.CENTER);
headStyle.setVerticalAlignment(VerticalAlignment.CENTER);
headStyle.setFont(headFont);
headStyle.setFillBackgroundColor(IndexedColors.YELLOW.index);
headStyle.setBorderTop(BorderStyle.MEDIUM);
headStyle.setBorderBottom(BorderStyle.THIN);
headStyle.setBorderLeft(BorderStyle.THIN);
headStyle.setBorderRight(BorderStyle.THIN);
headStyle.setTopBorderColor(IndexedColors.BLUE.index);
headStyle.setBottomBorderColor(IndexedColors.BLUE.index);
headStyle.setLeftBorderColor(IndexedColors.BLUE.index);
headStyle.setRightBorderColor(IndexedColors.BLUE.index);
}
/**
* @Description: 初始化内容行样式
*/
private static void initContentCellStyle() {
contentStyle.setAlignment(HorizontalAlignment.CENTER);
contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
contentStyle.setFont(contentFont);
contentStyle.setBorderTop(BorderStyle.THIN);
contentStyle.setBorderBottom(BorderStyle.THIN);
contentStyle.setBorderLeft(BorderStyle.THIN);
contentStyle.setBorderRight(BorderStyle.THIN);
contentStyle.setTopBorderColor(IndexedColors.BLUE.index);
contentStyle.setBottomBorderColor(IndexedColors.BLUE.index);
contentStyle.setLeftBorderColor(IndexedColors.ORANGE.index);
contentStyle.setRightBorderColor(IndexedColors.BLUE.index);
contentStyle.setWrapText(true);
}
/**
* @Description: 初始化标题行字体
*/
private static void initTitleFont() {
titleFont.setFontName("华文楷体");
titleFont.setFontHeightInPoints((short) 20);
titleFont.setBold(true);
titleFont.setCharSet((byte) 1);
titleFont.setColor(IndexedColors.BLUE_GREY.index);
}
/**
* @Description: 初始化日期行字体
*/
private static void initDateFont() {
dateFont.setFontName("隶书");
dateFont.setFontHeightInPoints((short) 10);
dateFont.setBold(true);
dateFont.setCharSet((byte) 1);
dateFont.setColor(IndexedColors.BLUE_GREY.index);
}
/**
* @Description: 初始化表头行字体
*/
private static void initHeadFont() {
headFont.setFontName("宋体");
headFont.setFontHeightInPoints((short) 10);
headFont.setBold(true);
headFont.setCharSet((byte) 1);
headFont.setColor(IndexedColors.BLUE_GREY.index);
}
/**
* @Description: 初始化内容行字体
*/
private static void initContentFont() {
contentFont.setFontName("宋体");
contentFont.setFontHeightInPoints((short) 10);
contentFont.setCharSet((byte) 1);
contentFont.setColor(IndexedColors.BLUE_GREY.index);
}
/**
* 作者:
* 日期:2018-04-26
* 功能:封装Excel导出的设置信息
*/
public static class ExportSetInfo {
private LinkedHashMap objsMap;
private String[] titles;
private List headNames;
private List fieldNames;
private OutputStream out;
public ExportSetInfo(LinkedHashMap objsMap, List fieldNames, String[] titles, List headNames, OutputStream out) {
this.objsMap = objsMap;
this.fieldNames = fieldNames;
this.titles = titles;
this.headNames = headNames;
this.out = out;
}
public LinkedHashMap getObjsMap() {
return this.objsMap;
}
/**
* @param-objsMap导出数据 泛型
* String : 代表sheet名称
* List : 代表单个sheet里的所有行数据
*/
public void setObjsMap(LinkedHashMap objsMap) {
this.objsMap = objsMap;
}
public List getFieldNames() {
return this.fieldNames;
}
/**
* @param-clazz对应每个sheet里的每行数据的对象的属性名称
*/
public void setFieldNames(List fieldNames) {
this.fieldNames = fieldNames;
}
/**
* @param-titles对应每个sheet里的标题,即顶部大字
*/
public String[] getTitles() {
return this.titles;
}
public void setTitles(String[] titles) {
this.titles = titles;
}
public List getHeadNames() {
return this.headNames;
}
/**
* @param headNames 对应每个页签的表头的每一列的名称
*/
public void setHeadNames(List headNames) {
this.headNames = headNames;
}
public OutputStream getOut() {
return this.out;
}
/**
* @param out Excel数据将输出到该输出流
*/
public void setOut(OutputStream out) {
this.out = out;
}
}
}
/**
* 导出出入统计Excel
* @param dto
* @param response
* @return
*/
@RequestMapping(value = "/exportAccessStatisticsExcel", method = RequestMethod.POST)
public ResponseMessage exportAccessStatisticsExcel(@RequestBody StatisticsQueryDto dto, HttpServletResponse response) {
logger.info("ExportExcelController.exportAccessStatisticsExcel begin dto:" + dto);
ResponseMessage resp = null;
try {
List