From 804309bbd5a349ff78d48d5e196632fe7909efb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A0=EC=A7=80=EC=9D=B8?= Date: Fri, 20 Feb 2026 09:18:09 +0900 Subject: [PATCH] =?UTF-8?q?=EC=97=91=EC=85=80=EB=8B=A4=EC=9A=B4=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=EC=8B=9C=20progress=20bar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...nstructionProjectManagementController.java | 143 ++- .../java/geoinfo/util/ExcelJobManager.java | 81 ++ .../geoinfo/util/ExcelMergeHeaderUtil.java | 1100 +++++++++-------- .../construction-site-index.jsp | 106 +- .../WEB-INF/views/admins/frame/mainframe.jsp | 83 ++ 5 files changed, 978 insertions(+), 535 deletions(-) create mode 100644 src/main/java/geoinfo/util/ExcelJobManager.java diff --git a/src/main/java/geoinfo/admins/constructionProjectManagement/ConstructionProjectManagementController.java b/src/main/java/geoinfo/admins/constructionProjectManagement/ConstructionProjectManagementController.java index 0b04d1e..ddf2d9c 100644 --- a/src/main/java/geoinfo/admins/constructionProjectManagement/ConstructionProjectManagementController.java +++ b/src/main/java/geoinfo/admins/constructionProjectManagement/ConstructionProjectManagementController.java @@ -4,13 +4,13 @@ import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.security.SecureRandom; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.UUID; import javax.annotation.Resource; import javax.servlet.ServletOutputStream; @@ -22,6 +22,9 @@ import org.apache.poi.ss.usermodel.Sheet; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; @@ -41,6 +44,7 @@ import geoinfo.com.EgovExcel; import geoinfo.comm.util.ScriptUtil; import geoinfo.comm.util.strUtil; import geoinfo.session.UserInfo; +import geoinfo.util.ExcelJobManager; import geoinfo.util.ExcelMergeHeaderUtil; import geoinfo.util.MyUtil; @@ -889,57 +893,59 @@ public class ConstructionProjectManagementController { * @param response * @throws Exception */ - @RequestMapping(value = "admins/drilling/inquiry/excel.do") - public void downloadDrillingInquiryListExcel(HttpServletRequest request, HttpServletResponse response, HSSFWorkbook workbook, @RequestParam HashMap params) throws Exception { + @RequestMapping(method = RequestMethod.POST, value="/admins/drilling/inquiry/excel/start.do") + @ResponseBody + public Map downloadDrillingInquiryListExcel(HttpServletRequest request, @RequestParam HashMap params) throws Exception { - HashMap map = new HashMap(); + final String jobId = UUID.randomUUID().toString(); + final HttpServletRequest finalRequest = request; + final HashMap finalParams = params; + final DrillingInquiryService service = drillingInquiryService; + String excelFileName = "발주기관_건설현장_목록_" + ExcelMergeHeaderUtil.getTimeStampString("yyyyMMdd_HHmm") + ".xlsx"; - String[] headers = {"cid","constName","projectStateCodeName","constStartDate","constStateCodeName","inquiryDist" ,"masterCompanyDept","masterCompanyAdmin","masterCompanyTel","coinstCompanyDept","constCompanyAdmin","constCompanyTel"}; - String[][] headerNames = {{"연번", "사업명", "입력상태", "사업내용", "", "발주기관현황", "", "", "", "건설사현황", "", ""}, - {"", "", "", "사업기간", "사업단계", "발주처", "담당부서", "담당자", "담당자연락처", "건설사명", "담당자", "담당자연락처"}}; + ExcelJobManager.startJob(jobId, new ExcelJobManager.ExcelTask() { + public byte[] generate(ExcelJobManager.ProgressCallback callback) throws Exception { - final int[] headerWidths = {1325, 15900, 4240, 6360, 5830, 8830, 6890, 2915, 3710, 5035, 2915, 3710}; - String[] columnType = {"String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String"}; - String sheetName = "Sheet1"; + String[] headers = {"cid","constName","projectStateCodeName","constStartDate","constStateCodeName","inquiryDist" ,"masterCompanyDept","masterCompanyAdmin","masterCompanyTel","coinstCompanyDept","constCompanyAdmin","constCompanyTel"}; + String[][] headerNames = {{"연번", "사업명", "입력상태", "사업내용", "", "발주기관현황", "", "", "", "건설사현황", "", ""}, + {"", "", "", "사업기간", "사업단계", "발주처", "담당부서", "담당자", "담당자연락처", "건설사명", "담당자", "담당자연락처"}}; + + final int[] headerWidths = {1325, 15900, 4240, 6360, 5830, 8830, 6890, 2915, 3710, 5035, 2915, 3710}; + String[] columnType = {"String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String", "String"}; + String sheetName = "Sheet1"; + + JSONObject resultObj = drillingInquiryService.drillingInquiryList(finalRequest, finalParams); + List list = (List) resultObj.get("datas"); + Long totalCount = (Long) resultObj.get("count"); + + int idx = 0; + for (EgovMap rowData : list) { + String constStartDate = (String) rowData.get("constStartDate"); + String constEndDate = (String) rowData.get("constEndDate"); + rowData.put("constStartDate", constStartDate + " ~ " + constEndDate); + rowData.put("cid", (totalCount) - (idx++)); + + String inquiryDist = ""; + if (rowData.get("glName") != null) + inquiryDist += rowData.get("glName") + " "; + if (rowData.get("gmName") != null) + inquiryDist += rowData.get("gmName") + " "; + if (rowData.get("gsName") != null) + inquiryDist += rowData.get("gsName"); + + rowData.put("inquiryDist", inquiryDist); + } + + byte[] excelBytes = ExcelMergeHeaderUtil.listToExcelMergeHeaderByteArray(list, headers, headerNames, headerWidths, columnType, "Sheet1", callback); + + return excelBytes; + + } + }, excelFileName); - String excelFileName = "발주기관 건설현장 목록"; - -// int startIndex = 0; - Long totalCount = 0L; - // DB 조회 - JSONObject resultObj = drillingInquiryService.drillingInquiryList(request, params); - - // 여기에서 list 꺼내기 - List list = (List) resultObj.get("datas"); - totalCount = (Long) resultObj.get("count"); - - int idx = 0; - for (EgovMap rowData : list) { - // 공사기간 형식 처리: startDate ~ endDate - String constStartDate = (String) rowData.get("constStartDate"); - String constEndDate = (String) rowData.get("constEndDate"); - rowData.put("constStartDate", constStartDate + " ~ " + constEndDate); // 공사기간을 'startDate ~ endDate' 형식으로 변환 - rowData.put("cid", (totalCount) - (idx++)); - - String glName = ""; - String gmName = ""; - String gsName = ""; - String inquiryDist = ""; // 발주처 - if ((String)rowData.get("glName") != null) { - glName = (String)rowData.get("glName"); - inquiryDist = inquiryDist + glName + " "; - }if ((String)rowData.get("gmName") != null) { - gmName = (String)rowData.get("gmName"); - inquiryDist = inquiryDist + gmName + " "; - }if ((String)rowData.get("gsName") != null) { - gsName = (String)rowData.get("gsName"); - inquiryDist = inquiryDist + gsName; - } - rowData.put("inquiryDist", inquiryDist); - - } - - ExcelMergeHeaderUtil.listToExcelMergeHeader(list, response, headers, headerNames, headerWidths, columnType, sheetName, excelFileName); + Map result = new HashMap(); + result.put("jobId", jobId); + return result; } /** @@ -1112,5 +1118,46 @@ public class ConstructionProjectManagementController { ExcelMergeHeaderUtil.listToExcelMergeHeaderForLoginHistory(resultList, response, headers, headerNames, headerWidths, columnType, sheetName, excelFileName); } + + /** + * 엑셀 다운로드 로딩 표시(진행률 확인) + * @param jobId + * @return + */ + @RequestMapping(value="/admins/drilling/inquiry/excel/progress.do", method=RequestMethod.GET) + @ResponseBody + public Map getExcelProgress(@RequestParam String jobId) { + int progress = ExcelJobManager.getProgress(jobId); + Map result = new HashMap<>(); + result.put("progress", progress); + return result; + } + + /** + * 엑셀 다운로드 로딩 표시(다운로드 완료) + * @param jobId + * @param response + * @throws IOException + */ + @RequestMapping(value="/admins/drilling/inquiry/excel/download.do", method=RequestMethod.GET) + public void downloadExcel(@RequestParam String jobId, HttpServletResponse response) throws IOException { + byte[] data = ExcelJobManager.getResult(jobId); + if(data == null){ + response.sendError(404, "엑셀 파일을 찾을 수 없습니다."); + return; + } + // Job 단위로 저장된 파일명 사용 + String fileName = ExcelJobManager.getFileName(jobId); + fileName = java.net.URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"); + + response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); + response.setHeader("Content-Transfer-Encoding", "binary"); + response.setContentType("application/octet-stream"); + response.getOutputStream().write(data); + response.flushBuffer(); + + // 완료 후 캐시 제거 + ExcelJobManager.clear(jobId); + } } \ No newline at end of file diff --git a/src/main/java/geoinfo/util/ExcelJobManager.java b/src/main/java/geoinfo/util/ExcelJobManager.java new file mode 100644 index 0000000..7320d01 --- /dev/null +++ b/src/main/java/geoinfo/util/ExcelJobManager.java @@ -0,0 +1,81 @@ +package geoinfo.util; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.http.HttpServletRequest; + +import org.json.simple.JSONObject; + +import egovframework.rte.psl.dataaccess.util.EgovMap; +import geoinfo.admins.user.service.DrillingInquiryService; + +/** + * 엑셀 다운로드 로딩바 처리 유틸 + * @author JIYOO + */ +public class ExcelJobManager { + + private static class Job { + byte[] data; + String fileName; + int progress; + } + + private static Map jobMap = new ConcurrentHashMap(); + + public static void startJob(final String jobId, final ExcelTask excelTask, final String fileName) { + final Job job = new Job(); + job.progress = 0; + job.fileName = fileName; + jobMap.put(jobId, job); + + new Thread(new Runnable() { + @Override + public void run() { + try { + byte[] excelBytes = excelTask.generate(new ProgressCallback() { + @Override + public void update(int percent) { + job.progress = percent; + } + }); + job.data = excelBytes; + job.progress = 100; + } catch (Exception e) { + job.progress = -1; + e.printStackTrace(); + } + } + }).start(); + } + + public static int getProgress(String jobId) { + Job job = jobMap.get(jobId); + return job == null ? 0 : job.progress; + } + + public static byte[] getResult(String jobId) { + Job job = jobMap.get(jobId); + return job == null ? null : job.data; + } + + public static String getFileName(String jobId) { + Job job = jobMap.get(jobId); + return job == null ? "excel.xlsx" : job.fileName; + } + + public static void clear(String jobId) { + jobMap.remove(jobId); + } + + public static interface ProgressCallback { + void update(int percent); + } + + public static interface ExcelTask { + byte[] generate(ProgressCallback callback) throws Exception; + } +} diff --git a/src/main/java/geoinfo/util/ExcelMergeHeaderUtil.java b/src/main/java/geoinfo/util/ExcelMergeHeaderUtil.java index 670863d..f1f8121 100644 --- a/src/main/java/geoinfo/util/ExcelMergeHeaderUtil.java +++ b/src/main/java/geoinfo/util/ExcelMergeHeaderUtil.java @@ -1,6 +1,6 @@ package geoinfo.util; - +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.net.URLEncoder; @@ -30,491 +30,621 @@ 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); - } - - } + 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.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); + } + } + + for (int j = 0; j < headerNames.length; j++) { + Cell cell = headerRow.createCell(j); + cell.setCellValue(headerNames[j]); + cell.setCellStyle(headerStyle); + sheet.autoSizeColumn(j); + sheet.setColumnWidth(j, (sheet.getColumnWidth(j)) + 1000); + } + // 엑셀이름 한글깨짐방지 + 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); + } + + } + + public static void listToExcelMergeHeader(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; + + // 헤더 셀 병합 + // === 세로 병합 (단일 컬럼) === + 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); + } + + } + + /** + * 로딩바 표시를 위하여 응답을 return함 + * + * @param response + * @throws IOException + */ + // public static byte[] listToExcelMergeHeaderByteArray(List list, + // String[] headers, String[][] headerNames, int[] headerWidths, String[] + // columnType, String sheetName) throws IOException { + public static byte[] listToExcelMergeHeaderByteArray(List list, String[] headers, String[][] headerNames, + int[] headerWidths, String[] columnType, String sheetName, ExcelJobManager.ProgressCallback callback) + throws IOException { + + if (!ExcelMergeHeaderUtil.isNotEmpty(list)) { + return new byte[0]; + } + + XSSFWorkbook wb = new XSSFWorkbook(); + Sheet sheet = wb.createSheet(sheetName); + + CellStyle headerStyle = wb.createCellStyle(); + CellStyle borderStyle = wb.createCellStyle(); + CellStyle cellStyle1 = wb.createCellStyle(); + CellStyle cellStyle2 = 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); + headerStyle.cloneStyleFrom(borderStyle); + headerStyle.setAlignment(HorizontalAlignment.CENTER); + headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); + headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + headerStyle.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.getIndex()); + + XSSFDataFormat format = wb.createDataFormat(); + cellStyle1.setDataFormat(format.getFormat("#,##0")); + cellStyle2.setDataFormat(format.getFormat("#")); + + // ===== 헤더 병합 ===== + 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++) { + Row row = sheet.createRow(i); + for (int j = 0; j < headerNames[i].length; j++) { + Cell cell = row.createCell(j); + cell.setCellValue(headerNames[i][j]); + cell.setCellStyle(headerStyle); + 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); + Object value = rowData.get(headers[j]); + + if ("Money".equalsIgnoreCase(columnType[j])) { + cell.setCellValue(value instanceof Number ? ((Number) value).doubleValue() : 0); + cell.setCellStyle(cellStyle1); + } else if ("Int".equalsIgnoreCase(columnType[j])) { + cell.setCellValue(value instanceof Number ? ((Number) value).doubleValue() : 0); + cell.setCellStyle(cellStyle2); + } else { + cell.setCellValue(value == null ? "" : String.valueOf(value)); + } + + cell.setCellStyle(borderStyle); + // 진행률 계산 (중간중간 콜백 호출) + if (callback != null) { + int percent = (int) (((i + 1) / (double) list.size()) * 100); + callback.update(percent); + } + } + } + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + wb.write(bos); + wb.close(); + + return bos.toByteArray(); + } + + 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); + } + + } } diff --git a/src/main/webapp/WEB-INF/views/admins/constructionProjectManagement/construction-site-index.jsp b/src/main/webapp/WEB-INF/views/admins/constructionProjectManagement/construction-site-index.jsp index 26ba660..b09c82d 100644 --- a/src/main/webapp/WEB-INF/views/admins/constructionProjectManagement/construction-site-index.jsp +++ b/src/main/webapp/WEB-INF/views/admins/constructionProjectManagement/construction-site-index.jsp @@ -574,6 +574,7 @@ // 엑셀 다운로드 function clickExcelDownload(){ + /* const params = new URLSearchParams(); params.append("constTag", trim($('#const-tag').val())); @@ -595,6 +596,107 @@ // AJAX가 아닌 직접 다운로드 요청 window.location.href = "/admins/drilling/inquiry/excel.do?" + params.toString(); $('#excelDownload').val(""); + */ + + const params = new URLSearchParams(); + params.append("constTag", trim($('#const-tag').val())); + params.append("constName", trim($('#const-name').val())); + params.append("excelDownload", "Y"); + + parent[1].showLoadingBar(); + + fetch("/admins/drilling/inquiry/excel.do", { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded" + }, + body: params.toString() + }) + .then(response => { + if (!response.ok) throw new Error("다운로드 실패"); + + const disposition = response.headers.get("Content-Disposition"); + let fileName = "excel.xlsx"; + + if (disposition && disposition.includes("filename=")) { + fileName = disposition.split("filename=")[1].replace(/"/g, ""); + } + + return response.blob().then(blob => ({ blob, fileName })); + }) + .then(({ blob, fileName }) => { + + const url = window.URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = fileName; + document.body.appendChild(a); + a.click(); + a.remove(); + window.URL.revokeObjectURL(url); + }) + .catch(err => { + alert("엑셀 다운로드 중 오류 발생"); + console.error(err); + }) + .finally(() => { + $('#excelDownload').val(""); + parent.hideLoadingBar(); + }); + } + + let currentJobId = null; + + function startExcelDownload() { + + const params = new URLSearchParams(); + params.append("constTag", trim($('#const-tag').val())); + params.append("constName", trim($('#const-name').val())); + params.append("excelDownload", "Y"); + + + parent.showLoadingBar(); +// parent.document.getElementById("progressWrap").style.display = "block"; + + fetch("/admins/drilling/inquiry/excel/start.do", { + method: "POST", + headers: {"Content-Type":"application/x-www-form-urlencoded"}, + body: params.toString() + }) + .then(res => res.json()) + .then(data => { + currentJobId = data.jobId; + pollProgress(); + }); + + $('#excelDownload').val(""); + } + + function pollProgress() { + + fetch("/admins/drilling/inquiry/excel/progress.do?jobId=" + currentJobId) + .then(res => res.json()) + .then(data => { + + let percent = data.progress; + + if(percent < 0){ + alert("엑셀 생성 중 오류 발생"); + return; + } + + parent.document.getElementById("progressBar").style.width = percent + "%"; + parent.document.getElementById("progressText").innerText = percent + "%"; + + if(percent < 100){ + setTimeout(pollProgress, 500); + } else { + setTimeout(function(){ + window.location = "/admins/drilling/inquiry/excel/download.do?jobId=" + currentJobId; + parent.hideLoadingBar(); + }, 700); + } + }); } +
+
+
+
엑셀 파일 생성 중...
+
+
+
+
0%
+
+