package geoinfo.util; import java.io.IOException; import java.io.PrintWriter; import java.net.URLEncoder; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.FillPatternType; 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.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFDataFormat; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import egovframework.rte.psl.dataaccess.util.EgovMap; public class ExcelMergeHeaderUtil { public static boolean isEmpty(final Object obj) { return !isNotEmpty(obj); } public static boolean isNotEmpty(final Object obj) { if(null == obj) return false; else { if(obj instanceof String) return "".equals(obj) ? false : true; else if(obj instanceof List) return !((List)obj).isEmpty(); else if(obj instanceof Map) return !((Map)obj).isEmpty(); // else if(obj instanceof Object[]) return 0 == Array.getLength(obj) ? false : true; else if(obj instanceof Integer) return !(null == obj); else if(obj instanceof Long) return !(null == obj); else if(obj instanceof LocalDate) return !(null == obj); else return false; } } public static String getTimeStampString(final String format) { return getTimeStampString(new Date(), format); } public static String getTimeStampString(final Date date) { return getTimeStampString(date, "yyyyMMddHHmmss"); } public static String getTimeStampString(final Date date, final String format){ java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat (format, java.util.Locale.KOREA); return formatter.format(date); } public static String getTimeStampString(String date, final String format) { try { if(null == date || "".equals(date)) return ""; Date d = null; date= date.replaceAll("-", ""); switch(date.length()) { case 14: break; case 12: date += "00"; break; case 10: date += "0000"; break; case 8: date += "000000"; break; case 6: date += "01000000"; break; case 4: date += "0101000000"; break; default: return ""; } java.text.SimpleDateFormat tmpFormat = new java.text.SimpleDateFormat("yyyyMMddHHmmss", java.util.Locale.KOREA); if("".equals(date)) d = new Date(); else { tmpFormat.setLenient(true); d = tmpFormat.parse(date); } return getTimeStampString(d, format); } catch(Exception e) { e.printStackTrace(); return ""; } } public static String getFileExtention(final String filename) { if(null == filename || "".equals(filename)) return ""; return -1 < filename.lastIndexOf(".") ? filename.substring(filename.lastIndexOf(".") + 1).toLowerCase() : ""; } public static String generationSaveName() { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } return ExcelMergeHeaderUtil.getTimeStampString("yyyyMMdd_HHmmss_SSS"); } public static void listToExcel(List list, HttpServletResponse response, String[] headers, String[] headerNames, String[] columnType, String sheetName, String excelFileName) throws IOException { if(ExcelMergeHeaderUtil.isNotEmpty(list)) { // 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다. XSSFWorkbook wb = new XSSFWorkbook(); Sheet sheet = wb.createSheet(sheetName); Row headerRow = sheet.createRow(0); CellStyle cellStyle1 = wb.createCellStyle(); //쉼표들어간 숫자 양식 CellStyle cellStyle2 = wb.createCellStyle(); //숫자양식 CellStyle headerStyle = wb.createCellStyle(); //헤더 스타일 CellStyle borderStyle = wb.createCellStyle(); // 기본 검정 테두리 스타일 // 기본 검정 테두리 스타일 설정 borderStyle.setBorderTop(BorderStyle.THIN); borderStyle.setBorderBottom(BorderStyle.THIN); borderStyle.setBorderLeft(BorderStyle.THIN); borderStyle.setBorderRight(BorderStyle.THIN); // 글꼴 색상 흰색으로 설정 Font headerFont = wb.createFont(); headerFont.setColor(IndexedColors.WHITE.getIndex()); // 글씨 색상 흰색 headerStyle.setFont(headerFont); // 헤더 스타일에 적용 XSSFDataFormat format = wb.createDataFormat(); cellStyle1.setDataFormat(format.getFormat("#,##0")); cellStyle2.setDataFormat(format.getFormat("#")); headerStyle.setBorderTop(BorderStyle.THIN); headerStyle.setBorderBottom(BorderStyle.THIN); headerStyle.setBorderLeft(BorderStyle.THIN); headerStyle.setBorderRight(BorderStyle.THIN); headerStyle.setAlignment(HorizontalAlignment.CENTER); headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); headerStyle.setFillForegroundColor((short)3); headerStyle.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.getIndex()); for(int i=0; i list, HttpServletResponse response, String[] headers, String[][] headerNames, int[] headerWidths, String[] columnType, String sheetName, String excelFileName) throws IOException { if(ExcelMergeHeaderUtil.isNotEmpty(list)) { // 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다. XSSFWorkbook wb = new XSSFWorkbook(); Sheet sheet = wb.createSheet(sheetName); Row headerRow = sheet.createRow(headerNames.length); CellStyle cellStyle1 = wb.createCellStyle(); //쉼표들어간 숫자 양식 CellStyle cellStyle2 = wb.createCellStyle(); //숫자양식 CellStyle headerStyle = wb.createCellStyle(); //헤더 스타일 CellStyle borderStyle = wb.createCellStyle(); // 기본 검정 테두리 스타일 // 기본 검정 테두리 스타일 설정 borderStyle.setBorderTop(BorderStyle.THIN); borderStyle.setBorderBottom(BorderStyle.THIN); borderStyle.setBorderLeft(BorderStyle.THIN); borderStyle.setBorderRight(BorderStyle.THIN); // 글꼴 색상 흰색으로 설정 Font headerFont = wb.createFont(); headerFont.setColor(IndexedColors.WHITE.getIndex()); // 글씨 색상 흰색 headerStyle.setFont(headerFont); // 헤더 스타일에 적용 XSSFDataFormat format = wb.createDataFormat(); cellStyle1.setDataFormat(format.getFormat("#,##0")); cellStyle2.setDataFormat(format.getFormat("#")); headerStyle.setBorderTop(BorderStyle.THIN); headerStyle.setBorderBottom(BorderStyle.THIN); headerStyle.setBorderLeft(BorderStyle.THIN); headerStyle.setBorderRight(BorderStyle.THIN); headerStyle.setAlignment(HorizontalAlignment.CENTER); headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // headerStyle.setFillForegroundColor((short)3); headerStyle.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.getIndex()); // 바디 스타일 CellStyle bodyStyle = wb.createCellStyle(); bodyStyle.setAlignment(HorizontalAlignment.CENTER); // ---------- 헤더구성 ------------------------------------ Row hRow = null; // rows int rowCnt = 0; // 헤더 셀 병합 // === 세로 병합 (단일 컬럼) === sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0)); // 연번 sheet.addMergedRegion(new CellRangeAddress(0, 1, 1, 1)); // 사업명 sheet.addMergedRegion(new CellRangeAddress(0, 1, 2, 2)); // 입력상태 // === 가로 병합 (대분류) === sheet.addMergedRegion(new CellRangeAddress(0, 0, 3, 4)); // 사업내용 sheet.addMergedRegion(new CellRangeAddress(0, 0, 5, 8)); // 발주기관현황 sheet.addMergedRegion(new CellRangeAddress(0, 0, 9, 11)); // 건설사현황 // 헤더 정보 구성 for (int i = 0; i < headerNames.length; i++) { hRow = sheet.createRow(rowCnt++); for (int j = 0; j < headerNames[i].length; j++) { Cell cell = headerRow.createCell(j); cell = hRow.createCell(j); cell.setCellStyle(headerStyle); cell.setCellValue(headerNames[i][j]); sheet.setColumnWidth(j, (sheet.getColumnWidth(j)) + 1000); sheet.setColumnWidth(j, headerWidths[j]); } } // ---------- 헤더구성 끝------------------------------------ for (int i = 0; i < list.size(); i++) { EgovMap rowData = list.get(i); Row row = sheet.createRow(i + 2); for (int j = 0; j < headers.length; j++) { Cell cell = row.createCell(j); // 특정 컬럼 중앙 정렬 -----참고용------------ // if ("lvl1_rate".equals(headers[j]) || // "lvl2_rate".equals(headers[j]) || // "lvl3_rate".equals(headers[j]) || // "lvl2_organ_up".equals(headers[j]) || // "lvl3_organ_up".equals(headers[j])) { // cell.setCellStyle(bodyStyle); // } -----참고용------------ Object value = rowData.get(headers[j]); // Money 타입 if ("Money".equalsIgnoreCase(columnType[j])) { if (value instanceof Number) { cell.setCellValue(((Number) value).doubleValue()); } else { cell.setCellValue(0); } cell.setCellStyle(cellStyle1); // Int 타입 } else if ("Int".equalsIgnoreCase(columnType[j])) { if (value instanceof Number) { cell.setCellValue(((Number) value).doubleValue()); } else { cell.setCellValue(0); } cell.setCellStyle(cellStyle2); // String 타입 } else { cell.setCellValue(value == null ? "" : String.valueOf(value)); } // 검정 테두리 적용 cell.setCellStyle(borderStyle); } } //엑셀이름 한글깨짐방지 String outputFileName = new String(excelFileName.getBytes("KSC5601"), "8859_1"); response.setHeader("Set-Cookie", "fileDownload=true; path=/"); response.setHeader("Content-Disposition", String.format("attachment; filename=\""+outputFileName+"_"+ExcelMergeHeaderUtil.getTimeStampString("yyyyMMdd_HHmm")+".xlsx\"")); wb.write(response.getOutputStream()); wb.close(); } else { createNoDataAlert(response); } } private static void createNoDataAlert(HttpServletResponse response) throws IOException { response.setHeader("Content-Type", "text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.write(""); out.write(""); out.write(""); out.write(""); out.write(""); out.write(""); out.flush(); out.close(); } public static void setDisposition(String filename, HttpServletRequest request, HttpServletResponse response) throws IOException { String browser = getBrowser(request); String dispositionPrefix = "attachment; filename="; String encodedFilename = null; if (browser.equals("MSIE")) { encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20"); } else if (browser.equals("Trident")) { // IE11 문자열 깨짐 방지 encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20"); } else if (browser.equals("Firefox")) { encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\""; } else if (browser.equals("Opera")) { encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\""; } else if (browser.equals("Chrome")) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < filename.length(); i++) { char c = filename.charAt(i); if(c==','){ sb.append(URLEncoder.encode(",", "UTF-8")); } else if (c > '~') { sb.append(URLEncoder.encode("" + c, "UTF-8")); } else { sb.append(c); } } encodedFilename = sb.toString(); } else { throw new IOException("Not supported browser"); } response.setHeader("Content-Disposition", dispositionPrefix + encodedFilename); if ("Opera".equals(browser)) { response.setContentType("application/octet-stream;charset=UTF-8"); } if(filename.contains("zip")){ response.setContentType("application/zip"); } } private static String getBrowser(HttpServletRequest request) { String header = request.getHeader("User-Agent"); if (header.indexOf("MSIE") > -1) { return "MSIE"; } else if (header.indexOf("Trident") > -1) { // IE11 문자열 깨짐 방지 return "Trident"; } else if (header.indexOf("Chrome") > -1) { return "Chrome"; } else if (header.indexOf("Opera") > -1) { return "Opera"; } return "Firefox"; } public static String LocalDateTimeToStringDate(LocalDateTime localDateTime) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); String formattedDate = localDateTime.toLocalDate().format(formatter); return formattedDate; } public static void listToExcelMergeHeaderForLoginHistory(List list, HttpServletResponse response, String[] headers, String[] headerNames, int[] headerWidths, String[] columnType, String sheetName, String excelFileName) throws IOException { if(ExcelMergeHeaderUtil.isNotEmpty(list)) { // 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다. XSSFWorkbook wb = new XSSFWorkbook(); Sheet sheet = wb.createSheet(sheetName); Row headerRow = sheet.createRow(headerNames.length); CellStyle cellStyle1 = wb.createCellStyle(); //쉼표들어간 숫자 양식 CellStyle cellStyle2 = wb.createCellStyle(); //숫자양식 CellStyle headerStyle = wb.createCellStyle(); //헤더 스타일 CellStyle borderStyle = wb.createCellStyle(); // 기본 검정 테두리 스타일 // 기본 검정 테두리 스타일 설정 borderStyle.setBorderTop(BorderStyle.THIN); borderStyle.setBorderBottom(BorderStyle.THIN); borderStyle.setBorderLeft(BorderStyle.THIN); borderStyle.setBorderRight(BorderStyle.THIN); // 글꼴 색상 흰색으로 설정 Font headerFont = wb.createFont(); headerFont.setColor(IndexedColors.WHITE.getIndex()); // 글씨 색상 흰색 headerStyle.setFont(headerFont); // 헤더 스타일에 적용 XSSFDataFormat format = wb.createDataFormat(); cellStyle1.setDataFormat(format.getFormat("#,##0")); cellStyle2.setDataFormat(format.getFormat("#")); headerStyle.setBorderTop(BorderStyle.THIN); headerStyle.setBorderBottom(BorderStyle.THIN); headerStyle.setBorderLeft(BorderStyle.THIN); headerStyle.setBorderRight(BorderStyle.THIN); headerStyle.setAlignment(HorizontalAlignment.CENTER); headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // headerStyle.setFillForegroundColor((short)3); headerStyle.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.getIndex()); // 바디 스타일 CellStyle bodyStyle = wb.createCellStyle(); bodyStyle.setAlignment(HorizontalAlignment.CENTER); // ---------- 헤더구성 ------------------------------------ Row hRow = null; // rows int rowCnt = 0; // 헤더 정보 구성 hRow = sheet.createRow(rowCnt++); for (int i = 0; i < headerNames.length; i++) { Cell cell = headerRow.createCell(i); cell = hRow.createCell(i); cell.setCellStyle(headerStyle); cell.setCellValue(headerNames[i]); sheet.setColumnWidth(i, (sheet.getColumnWidth(i)) + 1000); sheet.setColumnWidth(i, headerWidths[i]); } // ---------- 헤더구성 끝------------------------------------ for (int i = 0; i < list.size(); i++) { EgovMap rowData = list.get(i); Row row = sheet.createRow(i + 1); for (int j = 0; j < headers.length; j++) { Cell cell = row.createCell(j); Object value = rowData.get(headers[j]); // Money 타입 if ("Money".equalsIgnoreCase(columnType[j])) { if (value instanceof Number) { cell.setCellValue(((Number) value).doubleValue()); } else { cell.setCellValue(0); } cell.setCellStyle(cellStyle1); // Int 타입 } else if ("Int".equalsIgnoreCase(columnType[j])) { if (value instanceof Number) { cell.setCellValue(((Number) value).doubleValue()); } else { cell.setCellValue(0); } cell.setCellStyle(cellStyle2); // String 타입 } else { cell.setCellValue(value == null ? "" : String.valueOf(value)); } // 검정 테두리 적용 cell.setCellStyle(borderStyle); } } //엑셀이름 한글깨짐방지 String outputFileName = new String(excelFileName.getBytes("KSC5601"), "8859_1"); response.setHeader("Set-Cookie", "fileDownload=true; path=/"); response.setHeader("Content-Disposition", String.format("attachment; filename=\""+outputFileName+"_"+ExcelMergeHeaderUtil.getTimeStampString("yyyyMMdd_HHmm")+".xlsx\"")); wb.write(response.getOutputStream()); wb.close(); } else { createNoDataAlert(response); } } }