rosewiper 2024-08-29
알림톡 엑셀 불러오기 수정 1차 작업 중
@220b9852bd0200e896064206681666220620c0cc
src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
--- src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
+++ src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java
@@ -18,12 +18,22 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+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.openxml4j.opc.OPCPackage;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellStyle;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFCell;
 import org.apache.poi.xssf.usermodel.XSSFDataFormat;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.ModelMap;
@@ -31,15 +41,20 @@
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
 import org.springframework.web.servlet.ModelAndView;
 
 import egovframework.rte.fdl.idgnr.EgovIdGnrService;
 import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
 import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
 import itn.com.cmm.EgovMessageSource;
+import itn.com.cmm.JsonResult;
 import itn.com.cmm.LoginVO;
 import itn.com.cmm.service.EgovCmmUseService;
 import itn.com.cmm.util.MJUtil;
+import itn.com.cmm.util.StringUtil;
 import itn.com.utl.fcc.service.EgovStringUtil;
 import itn.let.kakao.kakaoComm.KakaoReturnVO;
 import itn.let.kakao.kakaoComm.KakaoSendUtil;
@@ -200,6 +215,233 @@
 		
 		return "web/kakao/msgdata/at/KakaoAlimtalkMsgDataView";
 	}
+	
+	
+	/*
+	 * 엑셀 파일 처리
+	 * 
+	 * */
+	@RequestMapping(value = "/web/mjon/alimtalk/sendAlimtalkExelFilePhoneNumAjax.do")
+	@ResponseBody
+	public Object sendAlimtalkExelFilePhoneNumAjax(final MultipartHttpServletRequest multiRequest) throws Exception {
+	
+		JsonResult jr = new JsonResult();
+		jr.setSuccess(false);
+		jr.setMessage("엑셀 파일만 업로드할 수 있습니다.");
+		
+		try {
+		
+			//final Map<String, MultipartFile> files = multiRequest.getFileMap();
+			List<MultipartFile> files = (List<MultipartFile>) multiRequest.getFiles("file0");
+			
+			// 파일명에 .이 있을경우 오류 => Ex) 테스트6.20.xlsx 
+			int fileNameSplitCnt = 0;
+			
+			if(!files.isEmpty()) {
+				fileNameSplitCnt = files.get(0).getOriginalFilename().split("[.]").length;
+				
+				if (files.get(0).getSize() > 0 
+						&& (files.get(0).getContentType().indexOf("spreadsheetml") > -1) 
+						|| files.get(0).getContentType().indexOf("ms-excel") > -1 
+						|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xlsx") > -1 
+						|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xls") > -1) {
+					
+					// 엑셀 파일 용량 3MB이상 시 10만건 이상으로 서버가 다운되는 증상 발생
+					long fileSize = multiRequest.getFile("file0").getSize();
+					
+					String Ext = files.get(0).getOriginalFilename().split("[.]")[1];
+					String errMessage = "";
+			        String cellValue  = "";
+			        String errPhoneLine = "";
+			        int errPhoneCnt = 0;
+			        
+					//String phoneRegExp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$";
+					String phoneRegExp = "^(050[2345678]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$";
+					
+					if(Ext.equals("xls")) {
+						
+						HSSFWorkbook workbook = new HSSFWorkbook(files.get(0).getInputStream());
+					    HSSFSheet sheet = workbook.getSheetAt(0);
+					    
+					    /*if(sheet.getLastRowNum() > 500) { //
+			            	errMessage = "500건 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
+			            	jr.setSuccess(false);
+			            	jr.setMessage(errMessage);
+			            	return jr;
+			            }*/
+						
+					    for(int i=2; i< sheet.getLastRowNum() + 2; i++){ //먼저 밸리데이션 체크(1줄은 생략)
+			            	HSSFRow row = sheet.getRow(i); //열읽기
+			            	if(null == row) { 
+			                    continue;
+			                }
+			            	
+			            	HashMap<String, String> jm = new HashMap<>();
+			            	// 행의 두번째 열(이름부터 받아오기) 
+			                HSSFCell cell = null;
+			                boolean errSts = true;
+			                for(int j = 0 ; j < 1; j++){ //행읽기(첫번째 컬럼만 필요)
+			                	
+			                	cellValue = "";
+			                	cell = row.getCell(j); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5
+			                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면 
+			                		if(j == 1) {
+				                		if (sheet.getLastRowNum() == i) {
+				                			continue;
+				                		}
+				                		
+				    	            	break;
+			                		}
+			                    	
+			                    }
+			                	if(null != cell){
+			                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
+			                			case  Cell.CELL_TYPE_NUMERIC:
+			                			cell.setCellType(Cell.CELL_TYPE_STRING);
+			                		}
+			                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+			                		
+			                		System.out.println("cellValue ::: "+cellValue);
+			                    }
+			                	
+			                }
+					    }
+					    
+					}else {//xlsx 확장자 처리
+						
+						OPCPackage opcPackage = OPCPackage.open(files.get(0).getInputStream());
+						XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);
+			            XSSFSheet sheet = workbook.getSheetAt(0); // 첫번째 시트 불러오기
+			            opcPackage.close();
+			            
+			            int totRowDataCnt = 0;
+			            for(int r=1; r<sheet.getPhysicalNumberOfRows(); r++) {
+			            	
+			            	XSSFRow tmpRow = sheet.getRow(r);
+			            	//System.out.println("=================r:"+r);
+			            	XSSFCell cell = null;
+			            	if(tmpRow.getCell(1) != null) {
+			            		
+			            		cell = tmpRow.getCell(1); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5
+				            	if(cell != null && !cell.toString().trim().equals("")) {
+				            		//System.out.println("value-" + r + ":" +cell.getStringCellValue()); 
+				            		totRowDataCnt++;
+				            		//System.out.println("tmpRowCnt:"+totRowDataCnt);
+				            	}
+			            		
+			            	}
+			            	
+			            }
+			            
+			            System.out.println("+++++++++++++++++ totRowDataCnt ::: "+totRowDataCnt);
+			            
+			            //if(sheet.getLastRowNum() > 20000) { //
+			            /*if(totRowDataCnt > 500) { //
+			            	errMessage = "500건 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
+			            	jr.setSuccess(false);
+			            	jr.setMessage(errMessage);
+			            	return jr;
+			            }*/
+			            
+			            List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
+			            
+			            for(int i=2; i< sheet.getLastRowNum() + 2; i++){ //먼저 밸리데이션 체크(1줄은 생략)
+			            	XSSFRow row = sheet.getRow(i); //열읽기
+			            	if(null == row) { 
+			                    continue;
+			                }
+			            	
+			            	HashMap<String, String> jm = new HashMap<>();
+			            	// 행의 두번째 열(이름부터 받아오기) 
+			                XSSFCell cell = null;
+			                boolean errSts = true;
+			                
+			                for(int j = 0 ; j < 1; j++){ //행읽기(첫번째 컬럼만 필요)
+			                	
+			                	cellValue = "";
+			                	cell = row.getCell(j); //이름/핸드폰/변환1/변환2/변환3/변환4/변환5
+			                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면 
+			                    	//System.out.println("Cell 데이터가 없습니다.");
+			                		if(j == 1) {
+				                		if (sheet.getLastRowNum() == i) {
+				                			continue;
+				                		}
+				                		
+				    	            	break;
+				                		
+			                		}
+			                    }
+			                	if(null != cell){
+			                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
+			                			case  Cell.CELL_TYPE_NUMERIC:
+			                			cell.setCellType(Cell.CELL_TYPE_STRING);
+			                		}
+			                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
+			                    }
+			                	
+			                	if(j == 0) {
+			                		
+			                		System.out.println("cellValue ::: "+cellValue);
+			                		
+			                		if(cellValue.matches(phoneRegExp) && errSts) {
+			                			jm.put("phone", cellValue);
+			                		}else {
+				    	            	errPhoneCnt++;
+				    	            	errPhoneLine += (i+1) + "행 ";
+				    	            	errSts = false;
+				    	            	break;
+			                		}
+			                		
+			                	}
+			                	
+			                }
+			                
+			                if(null != jm.get("phone") && errSts) {
+			                	json.add(jm);
+			                }
+			                
+			            }
+						
+			            int resultErrCnt = errPhoneCnt;
+			            
+			            jr.setData(json);
+						jr.setSuccess(true);
+						
+						if(resultErrCnt > 0) {
+							if (errPhoneCnt <= 10) {
+								if (StringUtils.isNotEmpty(errPhoneLine.trim())) {
+									errPhoneLine = "[" + errPhoneLine.trim() + "]";
+								}
+							}
+							else {
+								errPhoneLine = "";
+							}
+													
+							jr.setMessage("유효하지 않은 형식의 전화번호  "+ errPhoneCnt +"건" + errPhoneLine.trim() + " 있습니다.\n해당 건을 제외하고 문자 발송됩니다.");
+						}else {
+							jr.setMessage("");
+						}
+			            
+			            
+					}
+					
+					
+				}
+			}
+			
+			//jr.setMessage("엑셀 불러오기가 완료 되었습니다.");
+			//jr.setSuccess(true);
+			
+		} catch (Exception e) {
+			// TODO: handle exception
+			System.out.println("+++++++++++++++++ sendAlimtalkExelFilePhoneNumAjax Controller Error !!! "+e);
+			jr.setSuccess(false);
+			jr.setMessage("엑셀 데이터에 오류가 있습니다. 엑셀 데이터를 확인해 주세요.");
+			return jr;
+		}
+		
+		return jr;
+	}
 
 
 	// 카카오 템플릿 목록 조회
src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp
--- src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp
+++ src/main/webapp/WEB-INF/jsp/web/kakao/msgdata/at/KakaoAlimtalkMsgDataView.jsp
@@ -1736,6 +1736,7 @@
 						<label for="" class="attachedFile_label">첨부파일</label>
 						<input type="text" id="excelNm01" value="" readonly>
 						<input type="file" id="excelFile01" accept=".xls, .xlsx" onchange="excelExport01(event); return false;" style="display:none"/>
+						<!-- <input type="file" id="excelFile01" accept=".xls, .xlsx" onchange="excelExport01(event); return false;" style="display:none"/> -->
 						<button type="button" class="btnType btnType6 c1">찾아보기</button>
 <!-- 						<p><span class="vMiddle">*</span> 첨부된 파일은 <span class="c_e40000">[추가]버튼을 클릭</span>하셔야 받는 사람에 등록됩니다.</p> -->
 						<p><span class="vMiddle">*</span> 첨부된 파일은 <span class="c_e40000">[추가]버튼을 클릭</span>하셔야 받는 사람에 등록됩니다.</p>
@@ -1743,6 +1744,7 @@
 				</div><!--// 엑셀파일 불러오기 -->
 				<div class="popup_btn_wrap2">
 					<button type="button" class="tooltip-close" data-focus="popup02-close"  data-focus-next="popup02" onclick="excelAdd()">추가</button>
+					<!-- <button type="button" class="tooltip-close" data-focus="popup02-close"  data-focus-next="popup02" onclick="excelAdd()">추가</button> -->
 					<button type="button" class="tooltip-close" data-focus="popup02-close"  data-focus-next="popup02">닫기</button>                      
 				</div>
 			</div>
src/main/webapp/js/kakao/at/alimtalkExcel.js
--- src/main/webapp/js/kakao/at/alimtalkExcel.js
+++ src/main/webapp/js/kakao/at/alimtalkExcel.js
@@ -48,6 +48,124 @@
 	}
 }
 
+/*
+ * 신규 엑셀 파일 불러오기
+ * 기존 json 처리가 아닌 POI 방식으로 처리하기 위함
+ * 
+ * */
+
+function excelExport00(){
+	
+	var data = new FormData(document.excelToolTipForm);
+	//data.append("file0", $('#excelFile01').prop('files')[0]);
+	
+	var fileValue = $("#excelFile01").val().split("\\");
+	var fileName = fileValue[fileValue.length-1];
+	
+	var fileExt = fileName.split('.').pop().toLowerCase();
+	
+	console.log("fileName ::: "+fileName);
+	console.log("fileExt ::: "+fileExt);
+
+	if(fileExt.length > 0){
+		if($.inArray(fileExt, ['xls','xlsx']) == -1) {
+
+			alert('xls, xlsx 파일만 업로드 할수 있습니다.');
+			return false;
+
+	   	}
+		
+	}
+	fn_viewDataInit02();
+	$('#excelNm01').val(fileName);
+	
+}
+
+function excelAdd1(){
+	
+	var data = new FormData(document.excelToolTipForm);
+	data.append("file0", $('#excelFile01').prop('files')[0]);
+	
+	var url = "/web/mjon/alimtalk/sendAlimtalkExelFilePhoneNumAjax.do";
+	
+	$.ajax({
+        type: "POST",
+        enctype: 'multipart/form-data',
+        url: url,
+        data: data,
+        dataType:'json',
+        async: true,
+        processData: false,
+        contentType: false,
+        cache: false,
+        //timeout: 600000,
+        success: function (returnData, status) {
+			if(status == 'success'){ // status 확인 필요한가. 석세스 안뜨면 에러 가지 않나
+				
+				if(returnData.success){
+					
+					var data = returnData.data;
+					var message = returnData.message;
+					
+					if(message != '' ){
+						alert(returnData.message);
+					}
+					
+					if(data != null){
+						
+						/*$.each(data, function(i, item){
+							
+							if(checkHpNum(item.phone)){
+							
+								excelAddr.push({phone: item.phone, name: item.name, rep1: item.replace1, rep2: item.replace2, rep3: item.replace3, rep4: item.replace4});
+								
+							} else{
+								
+								alert("엑셀 파일 데이터의 형식이 맞지 않는 부분이 있습니다.");
+				        		excelAddr = []; //엑셀 데이터 저장 변수 초기화
+				        		$("#excelFile").val(""); //첨부파일 input 초기화
+				        	    $("#excelNm").val("");  // 첨부파일 명 초기화
+				        	    fileName = "";
+				        		return;
+								
+							} 
+						 
+						});*/
+
+					}
+					
+				}else{
+					alert(returnData.message);
+//						alert("첨부파일 불러오는 중 오류가 발생하였습니다.");
+					excelAddr = []; //엑셀 데이터 저장 변수 초기화
+	        		$("#excelFile01").val(""); //첨부파일 input 초기화
+	        	    $("#excelNm01").val("");  // 첨부파일 명 초기화
+	        	    fileName = "";
+					return;
+					
+				}
+			} else if(status== 'fail'){
+				alert("첨부파일 불러오는 중 오류가 발생하였습니다.1");
+				console.log("status : fail ~");
+			}
+		},
+		error: function (e) { 
+        	alert("첨부파일 불러오는 중 오류가 발생하였습니다2."); 
+        	console.log("ERROR : ", e); 
+        },
+		beforeSend : function(xmlHttpRequest) {
+        	//로딩창 show
+        	$('.loading_layer').addClass('active');				
+		},	        	        
+        complete : function(xhr, textStatus) {
+        	//로딩창 hide
+        	$('.loading_layer').removeClass('active');
+		}
+    });
+	
+}
+
+
 /**
  * 엑셀 파일 불러오기
  */
Add a comment
List