Excel导出工具类 (jdk1.8)


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<Entry<String, List>> set = setInfo.getObjsMap().entrySet();
			String[] sheetNames = new String[setInfo.getObjsMap().size()];
			int sheetNameNum = 0;
			for (Entry<String, List> entry : set) {
				sheetNames[sheetNameNum] = ((String) entry.getKey());
				sheetNameNum++;
			}
			SXSSFSheet[] sheets = getSheets(setInfo.getObjsMap().size(), sheetNames);
			int sheetNum = 0;
			for (Entry<String, List> 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<String, List> objsMap;
		private String[] titles;
		private List<String[]> headNames;
		private List<String[]> fieldNames;
		private OutputStream out;

		public ExportSetInfo(LinkedHashMap<String, List> objsMap, List<String[]> fieldNames, String[] titles, List<String[]> headNames, OutputStream out) {
			this.objsMap = objsMap;
			this.fieldNames = fieldNames;
			this.titles = titles;
			this.headNames = headNames;
			this.out = out;
		}

		public LinkedHashMap<String, List> getObjsMap() {
			return this.objsMap;
		}

		/**
		 * @param-objsMap导出数据 泛型
		 * String : 代表sheet名称
		 * List : 代表单个sheet里的所有行数据
		 */
		public void setObjsMap(LinkedHashMap<String, List> objsMap) {
			this.objsMap = objsMap;
		}

		public List<String[]> getFieldNames() {
			return this.fieldNames;
		}

		/**
		 * @param-clazz对应每个sheet里的每行数据的对象的属性名称
		 */
		public void setFieldNames(List<String[]> fieldNames) {
			this.fieldNames = fieldNames;
		}

		/**
		 * @param-titles对应每个sheet里的标题,即顶部大字
		 */
		public String[] getTitles() {
			return this.titles;
		}

		public void setTitles(String[] titles) {
			this.titles = titles;
		}

		public List<String[]> getHeadNames() {
			return this.headNames;
		}

		/**
		 * @param headNames 对应每个页签的表头的每一列的名称
		 */
		public void setHeadNames(List<String[]> 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<Map<String, Object>> dataList = this.prkPassRecordService.getAccessStatisticsReportList(dto);
            if (CollectionUtils.isEmpty(dataList)){
                return  ResponseMessage.createResponse(ResponseMessageCodeEnum.export_no_data,null);
            }
            String name = "出入统计列表";
            String fileName = new String((dto.getCreateTimeBegin() + "_" + dto.getCreateTimeEnd() + name + ".xlsx").getBytes("gb2312"), "iso8859-1");
            List<String[]> headNames = new ArrayList();
            List<String[]> fieldNames = new ArrayList();
            headNames.add("记录编号,记录类型,通行类型,通行方式,停靠车场,通行通道,车辆类型,车牌号码,识别号码,车牌颜色,记录时间".split(","));
            fieldNames.add("recordId,recordType,passType,passMode,parkName,gateName,vehicleType,plateNumber,recognizeNumber,plateColor,recordTime".split(","));
            LinkedHashMap<String, List> map = new LinkedHashMap();
            map.put(name, dataList);
            ExcelUtils.ExportSetInfo setInfo = new ExcelUtils.ExportSetInfo(map, fieldNames, new String[]{name}, headNames, response.getOutputStream());
            resp = ExcelUtils.export2Excel(fileName, response, setInfo, true);
        } catch (Exception e) {
            e.printStackTrace();
            resp = ResponseMessage.createResponse(ResponseMessageCodeEnum.export_faulted,null);
        }

        logger.info("ExportExcelController.exportAccessStatisticsExcel end dto:" + dto);
        return resp;
    }

猜你喜欢

转载自my.oschina.net/u/1052192/blog/1819790