1.POI工具类java
package com.lshaci.utils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFPalette; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.RegionUtil; /** * 使用POI导出EXCEL * * @author lshaci * */ public class ExcelExportUtilWithPOI { /** * 使用POI建立Excel * * @param sheetName Excel标签名字 * @param firstTitleName 一级标题名字(第一行合并单元格内) * @param secondTitleNames 二级标题名字集合(第二行) * @param secondTitleColumns 二级标题所跨列的集合 * @param columnHeaders 列标题集合(第三行) * @param fieldNames 对象字段名集合 * @param datas 数据集合 * @param otherData 其它的数据(表格最后一行合并的单元格内) * * @return 返回流信息 */ public static <T> InputStream createWorkBook(String sheetName, String firstTitleName, List<String> secondTitleNames, List<Integer> secondTitleColumns, List<String> columnHeaders, List<String> fieldNames, List<T> datas, String otherData) { try ( ByteArrayOutputStream os = new ByteArrayOutputStream(); ) { // 声明一个工做薄 HSSFWorkbook workbook = new HSSFWorkbook(); // 建立一个sheet HSSFSheet sheet = workbook.createSheet(sheetName); // 设置列宽 sheet.setDefaultColumnWidth(12); // 设置序号列的宽度 sheet.setColumnWidth(0, 1500); // 设置一级标题行 setFirstTitleRow(workbook, sheet, firstTitleName, columnHeaders.size()); // 设置二级标题行 setSecondTitleRows(workbook, sheet, secondTitleNames, secondTitleColumns); // 设置列的标题 setColumnTitles(workbook, sheet, columnHeaders); List<String[]> rowDatas = javaBean2StringArrays(datas, fieldNames); // 设置表格中的内容 setSheetRows(workbook, sheet, rowDatas); // 若是其它数据存在,则进行填充 if (otherData != null && otherData != "") { setOtherDataRows(workbook, sheet, otherData, 3 + rowDatas.size(), columnHeaders.size()); } workbook.write(os); return new ByteArrayInputStream(os.toByteArray()); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("建立excel表格出错"); } } /** * 设置表格一级标题行 * * @param workbook 工做簿 * @param sheet 标签 * @param firstTitleName 一级标题名称 * @param size 一级标题所跨列数 */ private static void setFirstTitleRow(HSSFWorkbook workbook, HSSFSheet sheet, String firstTitleName, int size) { HSSFRow row = sheet.createRow(0); row.setHeight((short) 1600); CellRangeAddress region = new CellRangeAddress(0, 0, 0, size); sheet.addMergedRegion(region); HSSFCell cell = row.createCell(0); cell.setCellValue(firstTitleName); cell.setCellStyle(createFirstTitleStyle(workbook)); // 设置合并单元格的边框 setMergeCellBorder(region, sheet, workbook); } /** * 建立一级标题样式 * */ private static HSSFCellStyle createFirstTitleStyle(HSSFWorkbook workbook) { // 生成一个样式 HSSFCellStyle style = workbook.createCellStyle(); HSSFPalette customPalette = workbook.getCustomPalette(); HSSFColor color = customPalette.findSimilarColor(102, 102, 153); // 设置这些样式 style.setFillForegroundColor(HSSFColor.WHITE.index); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 生成一个字体 HSSFFont font = workbook.createFont(); font.setColor(color.getIndex()); font.setFontHeightInPoints((short) 20); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); font.setFontName("华文楷体"); // 把字体应用到当前的样式 style.setFont(font); style.setWrapText(true); // 使用 \n 换行设置为true return style; } /** * 设置表格二级标题行 * * @param workbook 工做簿 * @param sheet 标签 * @param secondTitleNames 二级标题名称集合 * @param secondTitleColumns 二级标题所跨列数集合 */ private static void setSecondTitleRows(HSSFWorkbook workbook, HSSFSheet sheet, List<String> secondTitleNames, List<Integer> secondTitleColumns) { if (secondTitleNames.isEmpty() || secondTitleColumns.isEmpty() || secondTitleNames.size() != secondTitleColumns.size()) { throw new RuntimeException("二级标题名对应所跨的列数量不一致!"); } HSSFRow row = sheet.createRow(1); row.setHeight((short) 400); for (int i = 0; i < secondTitleNames.size(); i++) { Integer now = secondTitleColumns.get(i) - 1; Integer last = i == 0 ? 0 : secondTitleColumns.get(i - 1); HSSFCell cell = row.createCell(last);; cell.setCellValue(secondTitleNames.get(i)); cell.setCellStyle(createSecondTitleStyle(workbook)); if (now > 0) { CellRangeAddress region = new CellRangeAddress(1, 1, last, last + now); sheet.addMergedRegion(region); // 设置合并单元格的边框 setMergeCellBorder(region, sheet, workbook); } } } /** * 建立二级标题样式 */ private static HSSFCellStyle createSecondTitleStyle(HSSFWorkbook workbook) { // 生成一个样式 HSSFCellStyle style = workbook.createCellStyle(); HSSFPalette customPalette = workbook.getCustomPalette(); HSSFColor color = customPalette.findSimilarColor(102, 102, 153); // 设置这些样式 style.setFillForegroundColor(HSSFColor.WHITE.index); // 设置表格边框 setBorder(style); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 生成一个字体 HSSFFont font = workbook.createFont(); font.setColor(color.getIndex()); font.setFontHeightInPoints((short) 12); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); font.setFontName("微软雅黑"); // 把字体应用到当前的样式 style.setFont(font); return style; } /** * 设置表格的列标题 * * @param workbook 工做薄 * @param sheet 表格中的一个标签页 * @param headers 列标题名称的字符串数组 * @throws ExcelHanlderException */ private static void setColumnTitles(HSSFWorkbook workbook, HSSFSheet sheet, List<String> columnHeaders) { if (columnHeaders.isEmpty()) { throw new RuntimeException("列标题集合为空!"); } HSSFRow row = sheet.createRow(2); row.setHeight((short) 360); HSSFCellStyle columnTitleStyle = createColumnTitleStyle(workbook); for (int i = 0; i <= columnHeaders.size(); i++) { HSSFCell cell = row.createCell(i); String value = i == 0 ? "序号" : columnHeaders.get(i - 1); cell.setCellValue(value); cell.setCellStyle(columnTitleStyle); } } /** * 建立列标题栏样式 */ private static HSSFCellStyle createColumnTitleStyle(HSSFWorkbook workbook) { // 生成一个样式 HSSFCellStyle style = workbook.createCellStyle(); // 根据RGB获取类似的颜色 HSSFPalette customPalette = workbook.getCustomPalette(); HSSFColor color = customPalette.findSimilarColor(102, 102, 153); // 设置这些样式 style.setFillForegroundColor(HSSFColor.WHITE.index); setBorder(style); // 设置水平和垂直居中 style.setAlignment(HSSFCellStyle.ALIGN_CENTER); style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 生成一个字体 HSSFFont font = workbook.createFont(); font.setColor(color.getIndex()); font.setFontHeightInPoints((short) 10); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); font.setFontName("宋体"); // 把字体应用到当前的样式 style.setFont(font); return style; } /** * 设置表格中的内容 * * @param workbook 工做薄 * @param sheet 表格中的一个标签页 * @param rows 内容字符串数组集合 * @throws ExcelHanlderException */ private static void setSheetRows(HSSFWorkbook workbook, HSSFSheet sheet, List<String[]> rowDatas) { if (rowDatas.isEmpty()) { throw new RuntimeException("内容集合为空!"); } HSSFCellStyle contentStyle = createContentStyle(workbook); for (int i = 0; i < rowDatas.size(); i++) { HSSFRow row = sheet.createRow(3 + i); row.setHeight((short) 320); String[] rowData = rowDatas.get(i); for (int j = 0; j <= rowData.length; j++) { HSSFCell cell = row.createCell(j); String value = j == 0 ? (i + 1) + "" : rowData[j - 1]; cell.setCellValue(value); cell.setCellStyle(contentStyle); } } } /** * 建立表格内容样式 * * @param workbook 工做薄 * @return */ private static HSSFCellStyle createContentStyle(HSSFWorkbook workbook) { // 生成一个样式 HSSFCellStyle style = workbook.createCellStyle(); // 设置这些样式 style.setFillForegroundColor(HSSFColor.WHITE.index); // style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); setBorder(style); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 生成一个字体 HSSFFont font = workbook.createFont(); font.setColor(HSSFColor.BLACK.index); font.setFontHeightInPoints((short) 10); font.setFontName("宋体"); // 把字体应用到当前的样式 style.setFont(font); return style; } /** * 设置合并单元格的边框 * * @param region 合并的单元格 * @param sheet 标签 * @param workbook 工做簿 */ private static void setMergeCellBorder(CellRangeAddress region, HSSFSheet sheet, HSSFWorkbook workbook) { RegionUtil.setBorderBottom(1, region, sheet, workbook); RegionUtil.setBorderLeft(1, region, sheet, workbook); RegionUtil.setBorderRight(1, region, sheet, workbook); RegionUtil.setBorderTop(1, region, sheet, workbook); } /** * 设置表格边框 * * @param style 表格样式 */ private static void setBorder(HSSFCellStyle style) { style.setBorderBottom(HSSFCellStyle.BORDER_THIN); style.setBorderLeft(HSSFCellStyle.BORDER_THIN); style.setBorderRight(HSSFCellStyle.BORDER_THIN); style.setBorderTop(HSSFCellStyle.BORDER_THIN); } /** * 设置一些其它数据,在表格最后一行合并单元格内 * * @param workbook * @param sheet * @param otherData * @param rowIndex * @param size */ private static void setOtherDataRows(HSSFWorkbook workbook, HSSFSheet sheet, String otherData, int rowIndex, int size) { HSSFRow row = sheet.createRow(rowIndex); row.setHeight((short) 320); CellRangeAddress region = new CellRangeAddress(rowIndex, rowIndex, 0, size); sheet.addMergedRegion(region); HSSFCell cell = row.createCell(0); cell.setCellValue(otherData); HSSFCellStyle style = createContentStyle(workbook); style.setAlignment(HSSFCellStyle.ALIGN_LEFT); style.setWrapText(true); cell.setCellStyle(style); // 设置合并单元格的边框 setMergeCellBorder(region, sheet, workbook); } /** * javaBean转换为String数组集合 * * @param datas 须要转换的数据集合(对象类型,符合javaBean规范) * @param fields 指定须要转换的字段集合 * @return * @throws SecurityException * @throws NoSuchMethodException * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException */ private static <T> List<String[]> javaBean2StringArrays(List<T> datas, List<String> fieldNames) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (datas.isEmpty()) { throw new RuntimeException("数据为空!"); } List<String[]> rows = new ArrayList<>(); Class<?> clazz = datas.get(0).getClass(); if (fieldNames.isEmpty()) { throw new RuntimeException("字段名为空!"); } Method[] methods = getMethods(clazz, fieldNames); for (T data : datas) { int length = methods.length; String[] row = new String[length]; for (int i = 0; i < length; i++) { Object obj = methods[i].invoke(data); if (obj != null) { row[i] = obj.toString(); } else { row[i] = ""; } } rows.add(row); } return rows; } /** * 根据字段名获取get方法 * * @param clazz 须要获取get方法对象的Class * @param fieldNames 字段名字符串集合 * @return * @throws NoSuchMethodException * @throws SecurityException */ private static Method[] getMethods(Class<?> clazz, List<String> fieldNames) throws NoSuchMethodException, SecurityException { int length = fieldNames.size(); Method[] methods = new Method[length]; for (int i = 0; i < length; i++) { String fieldName = fieldNames.get(i); String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); methods[i] = clazz.getMethod(methodName); } return methods; } }
2.controllerapache
@RequestMapping(value = "exportDoctorsSummary", method = RequestMethod.GET) public void exportDoctorsSummary(HttpServletRequest request, HttpServletResponse response) throws IOException { String fileName = new String("文件名.xls".getBytes(), "iso-8859-1"); InputStream is = service.createExcel();//TODO 本身实现 // 设置response参数,能够打开下载页面 response.reset(); response.setContentType("application/vnd.ms-excel;charset=utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName); ServletOutputStream out = response.getOutputStream(); try ( BufferedInputStream bis = new BufferedInputStream(is); BufferedOutputStream bos = new BufferedOutputStream(out); ) { byte[] buff = new byte[2048]; int bytesRead; // Simple read/write loop. while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) { bos.write(buff, 0, bytesRead); } } catch (final IOException e) { throw e; } }