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; } }