이호영 이호영 2024-07-25
주소록 진행중
@cabf73ad986474eaab28b711cceaf642f9789c26
src/main/java/itn/let/mjo/addr/web/AddrController.java
--- src/main/java/itn/let/mjo/addr/web/AddrController.java
+++ src/main/java/itn/let/mjo/addr/web/AddrController.java
@@ -402,6 +402,14 @@
 		return "/web/addr/AddrListAjax";
 	}
 	
+	
+
+	@RequestMapping("/web/mjon/addr/addrListforExcelAjax.do")
+	public String AddrListforExcel(HttpServletRequest request, ModelMap model, 
+			@ModelAttribute("searchVO") AddrVO addrVO) throws Exception {
+			
+			return "/web/addr/addrListforExcel";
+	}
 	/**
 	 * 사용자 주소록 중복 리스트 Ajax
 	 * @param request
 
src/main/java/itn/let/mjo/addr/web/AddrRestController.java (added)
+++ src/main/java/itn/let/mjo/addr/web/AddrRestController.java
@@ -0,0 +1,117 @@
+package itn.let.mjo.addr.web;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
+import itn.com.cmm.EgovMessageSource;
+import itn.com.cmm.LoginVO;
+import itn.com.utl.fcc.service.EgovStringUtil;
+import itn.let.fax.admin.service.FaxStatVO;
+import itn.let.mail.service.StatusResponse;
+import itn.let.mjo.addr.service.AddrGroupService;
+import itn.let.mjo.addr.service.AddrGroupVO;
+import itn.let.mjo.addr.service.AddrService;
+import itn.let.mjo.addr.service.AddrVO;
+
+/**
+ * 주소록 관한 controller 클래스를 정의한다.
+ * @author ITN
+ * @since 2021.04.08
+ * @version 1.0
+ * @see
+ *
+ * <pre>
+ * << 개정이력(Modification Information) >>
+ *
+ *   수정일      수정자           수정내용
+ *  -------    --------    ---------------------------
+ *   2021.04.08  ITN          최초 생성
+ *
+ * </pre>
+ */
+@RestController
+public class AddrRestController {
+
+	
+	@Resource (name = "AddrService")
+	private AddrService addrService;
+	
+	@Resource (name = "AddrGroupService")
+	private AddrGroupService addrGroupService;
+	
+	/** EgovMessageSource */
+	@Resource(name="egovMessageSource")
+	EgovMessageSource egovMessageSource;
+	
+	
+	
+    /**
+     * 주소록 대량등록 저장
+     * @param searchVO
+     * @param model
+     * @return	"/web/mjon/addr/addrMassInsertByTempAjax.do"
+     * @throws Exception
+     */
+	@RequestMapping(value= {"/web/mjon/addr/addrMassInsertByTempAjax_advc.do"})
+	public ResponseEntity<StatusResponse> addrMassInsertByTempAjax(@RequestBody List<AddrVO> addrListVO,
+			RedirectAttributes redirectAttributes, 
+			ModelMap model) throws Exception{
+		
+		
+		System.out.println("??");
+		System.out.println("?? " + addrListVO.get(0).toString());
+		
+		return ResponseEntity.ok().body(new StatusResponse(HttpStatus.OK, "", LocalDateTime.now()));
+	} 
+	
+	/* 바이트 자르기
+	UTF-8일 경우
+	subStringBytes("블라블라블라라", 10, 3);
+	EUC-KR일 경우
+	subStringBytes("블라블라블라라", 10, 2);
+	*/
+	public String subStringBytes(String str, int byteLength, int sizePerLetter) {
+		  int retLength = 0;
+		  int tempSize = 0;
+		  int asc;
+		  if (str == null || "".equals(str) || "null".equals(str)) {
+		    str = "";
+		  }
+		 
+		  int length = str.length();
+		 
+		  for (int i = 1; i <= length; i++) {
+		    asc = (int) str.charAt(i - 1);
+		    if (asc > 127) {
+		      if (byteLength >= tempSize + sizePerLetter) {
+		        tempSize += sizePerLetter;
+		        retLength++;
+		      }
+		    } else {
+		      if (byteLength > tempSize) {
+		        tempSize++;
+		        retLength++;
+		      }
+		    }
+		  }
+		 
+	  return str.substring(0, retLength);
+	}
+
+
+	
+}(No newline at end of file)
src/main/webapp/WEB-INF/jsp/web/addr/AddrList.jsp
--- src/main/webapp/WEB-INF/jsp/web/addr/AddrList.jsp
+++ src/main/webapp/WEB-INF/jsp/web/addr/AddrList.jsp
@@ -6,37 +6,29 @@
 
 <script type="text/javascript" src="<c:url value='/publish/js/content.js'/>"></script>
 <script type="text/javascript" src="https://oss.sheetjs.com/sheetjs/xlsx.full.min.js"></script>
+<script type="text/javascript" src="<c:url value='/js/web/addr/init.js'/>"></script>
+<script type="text/javascript" src="<c:url value='/js/web/addr/event.js'/>"></script>
+<script type="text/javascript" src="<c:url value='/js/web/addr/utils.js'/>"></script>
+
 
 <script type="text/javascript">
-var tableErrorData = [];
-var tableErrorCheckData = [];
-var addrMassDupliSaveList = null;
-
-var gArrRestartIndex = 0;	//배열 재시작카운드
-var gNameList = [];		//치환문자 이름
-var gPhoneList = [];	//받는사람
-var gInfo1List = [];		//치환문자1
-var gInfo2List = [];		//치환문자2
-var gInfo3List = [];		//치환문자3
-var gInfo4List = [];		//치환문자4
-var gMemoList = [];			//메모
 
 $(document).ready(function(){
 	listAddrGrp();
 	addrLoadAjax();
 	
 	// 주소록 대량등록
-	addrMassTab(1);	
+// 	addrMassTab(1);	
 	
 	// 중복 휴대폰번호 버튼 노출여부
-	$("#btnAddrMassDupli").hide();
-	$("#btnAddrMassSaveDupli").hide();
 }); 
 
+// 메인 화면 좌측메뉴 최신화
 function listAddrGrp(){
 	var sendData = $(document.searchAddrGrpForm).serializeArray() ;
 	$("#adr1_left").load("/web/addr/selectAddrGroupListAjax.do", sendData ,function(response, status, xhr){});
 }
+
 
 function addrGroupLoadAjax(){
 	$("#addrRegistSelect").load("/web/addr/selectAddrGroupAjax.do", function(response, status, xhr){});
@@ -188,296 +180,29 @@
 //#############################################################################################
 //Tabulator
 //#############################################################################################
-var tableR = null; //우측 주소록 불러오기 Tabulator 변수
-
-/* 파일등록 */
-var _fileIdx = 0;
-var _fileForm2 = new Array();
-var fileExt = ""; // 첨부파일 확장자
-var excelAddr = []; //엑셀 불러오기에서 내용 저장하는 배열 변수
 
 $(document).ready(function(){
-	//Tabulator AJAX Data Loading
-	tableR = new Tabulator(".callList_box", {
-		height:"255px",
-		width:"100%",
-	    layout:"fitColumns",
-	    //data:tabledata,
-	    //autoColumns:true,
-	    headerHozAlign:"center",
-	    validationMode:"highlight",
-	    clipboard:false,
-	    clipboardCopySelector:"table",
-	    clipboardPasteAction:"insert", // insert, update, replace
-	    placeholder:"복사(Ctrl+C)한 내용을 여기에 붙여넣기(Ctrl+V) 해주세요.", //fit columns to width of table (optional)
-	 	columns:[ //Define Table Columns
-	 		{formatter:"rowSelection", titleFormatter:"rowSelection",clipboard:false, hozAlign:"center", headerSort:false, cellClick:function(e, cell){
-	 	        cell.getRow().toggleSelect();
-		 		}
-		 	}, 
-		 	{title:"이름", hozAlign:"center", field:"name", editor:"input", width:140, validator:["maxLength:12", "string"]},
-		 	{title:"휴대폰", hozAlign:"center", field:"phone", editor:"input", width:145, validator:["required","minLength:10", "maxLength:13"]},
-		 	{title:"[*1*]", hozAlign:"center", field:"info1", editor:"input", width:100, validator:["maxLength:100", "string"]},
-		 	{title:"[*2*]", hozAlign:"center", field:"info2", editor:"input", width:100, validator:["maxLength:100", "string"]},
-		 	{title:"[*3*]", hozAlign:"center", field:"info3", editor:"input", width:100, validator:["maxLength:100", "string"]},
-		 	{title:"[*4*]", hozAlign:"center", field:"info4", editor:"input", width:100, validator:["maxLength:100", "string"]},
-		 	{title:"메모", hozAlign:"center", field:"memo", editor:"input", width:119, validator:["maxLength:100", "string"]}
-	 	],
-	 	validationFailed:function(cell, value, parameters){ // 유효성 체크 함수 
-	        var valid = cell.isValid();
-	 		if(!valid){
-	 			alert("양식에 맞지 않는 정보가 입력되었습니다.");
-	 			
-	 			//해당 셀 데이터 삭제
-	 			cell.setValue("");
-	 		}
-	 		return value % parameters.phone;
-	    },
-	});
+	
+
 
 	//받는 사람 리스트 영역에 클립보드 데이터 가져와보기 
-	$('.callList_box').on('paste', function (e) {
-		var element = e.originalEvent.clipboardData.getData('text'); // 클립보드에 복사한 데이터 가져오기
-		var elmSplit= [];
-		elmSplit = element.split("\n");
-		var elmLen = elmSplit.length;
-		if(elmLen < 0){
-			alert("붙여넣을 연락처를 복사해주세요.");
-			return false;
-		}else{
-			if (elmLen > 20001) {
-				alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
-				return false;
-			}			
-			
-			tableErrorData.length = 0;	// 오류 번호 배열 초기화
+	// 붙여넣기 기능
+	
+	
 
-			var splitData = [];
-			var realPhone = [];
-			for(var i=0; i < elmLen; i++){
-				var splitStr = elmSplit[i];
-				var tabData = splitStr.split("\t"); //탭 구분으로 데이터 분할
-				var comData = splitStr.split(","); //콤마 구분으로 데이터 분할
-				if(tabData.length >= 2){
-					splitData = tabData;
-				}else{
-					splitData = comData;
-				}
-				
-				if(splitData.length == 0){// 데이터가 없는경우
-					alert("탭으로 구분하여 데이터를 복사해 주세요.");
-				  	return false;
-				}else if(splitData.length == 1){// 데이터가 탭으로 구분이 없는 경우
-					for(var j=0; j < splitData.length; j++){
-						if(checkHpNum(splitData[j].trim())){//핸드폰 양식이 맞는지 확인
-							//배열 끝에 데이터 추가해 주기
-							realPhone.push({name: "", phone: removeDash(splitData[j].trim())});
-						}
-						else {
-							if (splitData[j].trim() != '' && splitData[j].trim() != null && splitData[j].trim() != undefined) {
-								tableErrorData.push(splitData[j].trim());
-							}							
-						}
-					}
-				}else{//데이터가 탭으로 구분되어 이름, 연락처로 구분된 경우
-					var name;	//이름
-					var phone;	//핸드폰번호					
-					var info1;
-					var info2;
-					var info3;
-					var info4;
-					var memo;	//메모
-					var isPhoneValid = false;
-					for(var j=0; j < splitData.length; j++){
-						if(j == 0){
-							name = splitData[j].trim();
-						}
-						if(j == 1){
-							if(checkHpNum(splitData[j].trim())){//핸드폰 양식이 맞는지 확인
-								phone = removeDash(splitData[j].trim());
-								isPhoneValid = true;
-							}
-							else {
-								if (splitData[j].trim() != '' && splitData[j].trim() != null && splitData[j].trim() != undefined) {
-									tableErrorData.push(splitData[j].trim());
-								}
-							}
-						}
-						
-						if(j == 2){
-							info1 = splitData[j].trim();
-						}
-						if(j == 3){
-							info2 = splitData[j].trim();
-						}
-						if(j == 4){
-							info3 = splitData[j].trim();
-						}
-						if(j == 5){
-							info4 = splitData[j].trim();
-						}						
-						
-						if(j == 6){	//메모
-							memo = splitData[j].trim();
-						}
-					}
-					
-					if (isPhoneValid == true) {
-						//배열 끝에 데이터 추가해 주기
-						realPhone.push({name: name, phone: phone, info1 : info1, info2 : info2, info3 : info3, info4 : info4, memo : memo });
-					}
-				}//else end
-			}
-			
-			var recTableData = tableR.getRows();		 // 받는사람 리스트의 전체 목록을 저장
-			var tableData = [];
-			
-			//기존 받는사람 리스트를 배열에 미리 담아둔다.
-			if(recTableData.length > 0){
-				for(var j=0; j < recTableData.length; j++){
-					tableData.push({name: recTableData[j].getData().name, phone: removeDash(recTableData[j].getData().phone.trim()), info1: recTableData[j].getData().info1, info2: recTableData[j].getData().info2, info3: recTableData[j].getData().info3, info4: recTableData[j].getData().info4, memo: recTableData[j].getData().memo});
-				}
-			}
-			
-			if(realPhone.length > 0){
-				for(var j=0; j < realPhone.length; j++){
-					tableData.push({name: realPhone[j].name, phone: removeDash(realPhone[j].phone.trim()), info1: realPhone[j].info1, info2: realPhone[j].info2, info3: realPhone[j].info3, info4: realPhone[j].info4, memo: realPhone[j].memo});
-				}
-			}
-			
-			//tableData.push(realPhone);
-				
-			//중복 연락처 1개만 남기고 삭제하기
-			var removeDuplPhone = dupliPhoneData(tableData);
-			  
-			//수신자 리스트에 전화번호 추가해주기
-			//tableR.addData(removeDuplPhone);
-			tableR.setData(removeDuplPhone);
-			
-			totRows = tableR.getRows().length; 
-			updateTotCnt(totRows); //전체 데이터 갯수 구하기
-			
-			if (tableErrorData.length > 0) {
-				alert("올바르지 않은 휴대폰 번호가 "+ tableErrorData.length +" 건 있습니다.");
-				//for(var x=0; x < tableErrorData.length; x++){
-				//	alert(tableErrorData[x]);
-				//}
-			}
-		}
-	});
-
-	//tableR.setData(tabledata);
-
-	//받는사람 번호 버튼 클릭시 Tabulator에 데이터 넣어주기
-	$('.addCallToF').click(function(){ 
-		var recTableData = tableR.getRows();		 // 받는사람 리스트의 전체 목록을 저장
-		var tableData = [];
-
-		//빈 Row 한줄을 상단에 먼저 추가해준다.
-		tableData.push({phone: ""});
-		
-		//기존 받는사람 리스트를 배열에 미리 담아둔다.
-		if(recTableData.length > 0){
-			for(var j=0; j < recTableData.length; j++){
-				tableData.push({name: recTableData[j].getData().name, phone: removeDash(recTableData[j].getData().phone.trim()), info1: recTableData[j].getData().info1, info2: recTableData[j].getData().info2, info3: recTableData[j].getData().info3, info4: recTableData[j].getData().info4, memo: recTableData[j].getData().memo});
-			}
-		}
-		
-		//연락처 추가해 주기
-		//addPhoneInfo(tabledata);
-		
-		tableR.setData(tableData);
-		
-		//전체 데이터 갯수 구하기
-	    totRows = tableR.getRows().length;
-	    updateTotCnt(totRows);
-	});
+// 	// 필드 선택 이벤트 핸들러
+// 	$("#column-selector").on("change", function() {
+// 		let selectedField = $(this).val();
+// 		let newValue = prompt("새 값을 입력하세요:");
+// 		if (newValue !== null) {
+// 			updateTableField(selectedField, newValue);
+// 		}
+// 	});
 
 
-	//받는사람 전체삭제 버튼 처리
-	$('.all_del').click(function(){
-		var data = tableR.getRows();	
-		if(data == null || data == ""){
-			alert("받는사람을 추가해 주세요.");
-			return false;
-		}else{
-			tableR.clearData();
-			$("#rowTotCnt").text(0); //총건수 수정
-			$("#rowDupCnt").text(0); //중복건수 수정
-			dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
-		}
-		
-	});
 
 
-	// 받는사람 선택삭제 버튼 처리해주기
-	$('.select_del').click(function(){
-		$("#rowDupCnt").text(0); //중복건수 수정
-		dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
-		
-		if(tableR == null || tableR == ""){
-			alert("받는사람을 추가해 주세요.");
-			return false;
-		}
-		
-		var selectedData = tableR.getSelectedRows();
-		
-		if(selectedData == "" || selectedData == null){
-			alert("받는 사람을 선택해 주세요.");
-			return false;
-		}else{ // 선택한 Row 데이터 삭제하기
-			for(var i=0; i < selectedData.length; i++){
-				selectedData[i].delete();
-			}
-		}
-		
-		totRows = tableR.getRows().length;
-	    
-		updateTotCnt(totRows);
-	});
-
-	//받는사람 오류번호 삭제 처리해주기
-	$('.chkVali_del').click(function(){
-		//기존 연락처 모두 불러오기
-	    var data = tableR.getRows();
-	    var tableData = [];
-	    var totLen = tableR.getRows().length;
-	    var errCnt = 0;
-	    
-	    if(totLen > 0){
-	    	if(confirm("올바르지 않은 연락처 정보를 삭제 하시겠습니까?")){
-	    		for(var i=0; i < totLen; i++){
-	            	var phone = data[i].getData().phone;
-	            	var valiCheck = checkHpNum(phone);
-	            	if(valiCheck){
-	            		tableData.push({name: data[i].getData().name.trim(), phone: data[i].getData().phone.trim(), info1:data[i].getData().info1, info2:data[i].getData().info2, info3:data[i].getData().info3, info4:data[i].getData().info4, memo:data[i].getData().memo});
-	            	}else{
-	            		errCnt++;
-	            	}
-	            }
-	            
-	            var removeDuplData = dupliPhoneData(tableData);
-	        	
-	            tableR.setData(removeDuplData);
-	            
-	            //총 받는사람 수 계산
-	            totRows = tableR.getRows().length;
-	            updateTotCnt(totRows);
-	            
-	          	if(errCnt > 0){
-	          		alert(errCnt + " 건의 연락처를 삭제하였습니다.");
-	          		return false;
-	          	}else{
-	          		alert("오류가 있는 연락처가 없습니다.");
-	          	}
-	    	}
-	    }else{
-	    	alert("연락처 정보를 입력해 주세요.");
-	    	return false;
-	    }
-	});
-
-
+	
 	// 오류검사 항목 중복제거
 	function SetTableErrorDupliCheck(sVal) {
 		var isDuplicate = false;
@@ -525,325 +250,11 @@
 		}
 	}	
 	
-	$('.check_validity').click(function(){
-		tableErrorCheckData.length = 0;	// 오류 번호 배열 초기화
-		
-		var data = tableR.getRows();
-		var invalid = tableR.getInvalidCells();		//오류 데이터 체크
-		var dataLen = tableR.getRows().length;		//연락처 데이터 갯수
-		var totLen = invalid.length;				//오류 데이터 갯수
-		var errMsg = "";							//최종 alert에 표시할 메시지 저장 변수
-		
-		if(dataLen > 0) { //연락처 정보가 있으면 수행
-			if(totLen > 0) { //내용에 오류가 있으면 수행
-				//오류 데이터 값 저장
-				for(var i=0; i < totLen; i++) {
-					var cellValue = invalid[i].getValue();
-					SetTableErrorDupliCheck(cellValue);
-				}
-				
-				for(var i=0; i < dataLen; i++){
-					// 휴대폰번호 체크
-		        	var phone = data[i].getData().phone;
-		        	var valiCheck = checkHpNum(phone);
-		        	if(!valiCheck){
-		        		SetTableErrorDupliCheck(phone);
-		        	}
-				}
-			}
-			else {
-				for(var i=0; i < dataLen; i++){
-					// 휴대폰번호 체크
-		        	var phone = data[i].getData().phone;
-		        	var valiCheck = checkHpNum(phone);
-		        	if(!valiCheck){
-		        		SetTableErrorDupliCheck(phone);
-		        	}
-				}				
-			}
-		}
-		else {
-			alert("연락처를 입력해 주세요.");
-			return false;
-		}
-		
-		if (tableErrorCheckData.length > 0) {
-			for (var i = 0; i < tableErrorCheckData.length; i++)
-			{
-				errMsg += tableErrorCheckData[i];
-				if ((tableErrorCheckData.length - 1) > i) {
-					errMsg += ", ";
-				}
-			}			
-    		alert(errMsg + "의 내용에 오류가 있습니다.");			
-		}
-		else {
-			alert("오류 데이터가 없습니다.");			
-		}
-		
-		return false;		
-	});
 	
 
-	$('.addExcelDw').click(function(){
-		var data = tableR.getRows();
-		if(data.length > 0){
-			tableR.download("xlsx", "recieveAddr.xlsx", {sheetName:"recieveAddr"});
-		}else{
-			alert("입력된 연락처 정보가 없습니다.");
-			return false;
-		}
-	});
-
-	//받는사람 중복 삭제
-	$('.duple_del').click(function(){
-		//기존 연락처 모두 불러오기
-	    var data = tableR.getRows();
-	    var tableData = [];
-	    var dpCnt = 0;
-	    var totLen = tableR.getRows().length;
-	    
-	    for(var i=0; i < totLen; i++){
-	    	tableData.push({name: data[i].getData().name.trim(), phone: data[i].getData().phone.trim()});
-	    }
-	    
-	    var removeDuplData = dupliPhoneData(tableData);
-	    tableR.setData(removeDuplData);
-	    
-	    //총 받는사람 수 계산
-	    totRows = tableR.getRows().length;
-	    updateTotCnt(totRows);
-	});	
-	
 	
 });
 
-
-//전체 데이터 갯수 구하는 함수
-function updateTotCnt(data){
-	var rowTotCnt = data;
-	$("#rowTotCnt").text(rowTotCnt);
-}
-
-function addPhoneInfo(data){
-	if(data == null){
-		alert("연락처 정보가 없습니다.");
-		return;
-	}else{
-		var idx = 0;
-		var newData = data;//중복 연락처는 하나만 남기고 모두 제거
-		
-		var recTableData = tableR.getRows();		 // 받는사람 리스트의 전체 목록을 저장
-		var tableData = [];
-		
-		//기존 받는사람 리스트를 배열에 미리 담아둔다.
-		if(recTableData.length > 0){
-			for(var j=0; j < recTableData.length; j++){
-				tableData.push({name: recTableData[j].getData().name, phone: removeDash(recTableData[j].getData().phone.trim()), info1: recTableData[j].getData().info1, info2: recTableData[j].getData().info2, info3: recTableData[j].getData().info3, info4: recTableData[j].getData().info4, memo: recTableData[j].getData().memo});
-			}
-		}
-		
-		//받는사람 리스트를 담아둔 배열에 신규 추가 데이터를 추가해 준다.
-		for(var i=0; i < newData.length; i++){
-			tableData.push({name: newData[i].name.trim(), phone: removeDash(newData[i].phone.trim()), info1: newData[i].info1, info2: newData[i].info2, info3: newData[i].info3, info4: newData[i].info4, memo: newData[i].memo});
-		}
-		
-		var temp = tableData.length;
-		
-		//기존 수신 리스트를 지워준 후 신규 전체 리스트를 추가해준다.
-		tableR.clearData(); //기존 받는사람 목록을 삭제.
-		tableR.addData(dupliPhoneData(tableData)); // 받는사람 목록에 주소 정보 입력하기
-		_fileForm2 = []; //form file data 초기화
-		_fileIdx = 0;	//form file idx 초기화
-		
-		totRows = tableR.getRows().length; 
-		updateTotCnt(totRows); //전체 데이터 갯수 구하기
-	}
-}
-
-/* 파일사이즈 가져오기 */
-function getStrFileSize(filesize){
-	var sizeStr="";
-	var sizeKB = filesize/1024;
-	if(parseInt(sizeKB) > 1024){
-	    var sizeMB = sizeKB/1024;
-	    sizeStr = sizeMB.toFixed(2)+" MB";
-	}else{
-	    sizeStr = sizeKB.toFixed(2)+" KB";
-	}
-	return sizeStr;
-}
-
-//#############################################################################################
-//파일업로드 드래그앤 드롭
-//#############################################################################################
-var objDragAndDrop = $(".upload_area");
-$(document).on("dragenter",".upload_area",function(e){
-  e.stopPropagation();
-  e.preventDefault();
-  //$(this).css('border', '2px solid #0B85A1');
-});
-$(document).on("dragover",".upload_area",function(e){
-  e.stopPropagation();
-  e.preventDefault();
-});
-$(document).on("drop",".upload_area",function(e){
-  //$(this).css('border', '2px dotted #0B85A1');
-  e.preventDefault();
-  var files = e.originalEvent.dataTransfer.files;
-  handleFileUpload(files,objDragAndDrop);  //파일업로드
-});
-
-$(document).on('dragenter', function (e){
-  e.stopPropagation();
-  e.preventDefault();
-});
-$(document).on('dragover', function (e){
-e.stopPropagation();
-e.preventDefault();
-//objDragAndDrop.css('border', '2px dotted #0B85A1');
-});
-$(document).on('drop', function (e){
-  e.stopPropagation();
-  e.preventDefault();
-});
-//파일 드래그앤드롭 종료
-
-function handleFileUpload(files,obj)  //업로드 function
-{
-	_fileForm2 = []; //form file data 초기화
-	
-	var limitsize = 50*1024*1024;  //파일 제한 체크(50개, 50MB)
-	var limitcount = 1;//$("input[name=limitcount]").val()*1 ;
-	var fileNece = true; //첨부파일필수
- 
- 
-	if($('#fileNece').length > 0){
-		if('N'==$('#fileNece').val()){
-			fileNece = false;  
-		}
- 	}
- 
-	//엑셀 및 TXT 파일만 업로드 할수 있도록 체크하기
-	var fileNm = files[0].name;
-	fileExt = fileNm.split('.').pop().toLowerCase();
-
-	// IE11 대응
-	if (fileExt != "") { 
-		if($.inArray(fileExt, ['txt','xls','xlsx']) == -1) {
-			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
-			return;
-		}
-		
-		for (var i = 0; i < files.length; i++)
-		{
-		    var fd = new FormData();
-		    fd.append('file', files[i]);
-		    var tmpObj = new Object();
-		    tmpObj.name = "file_" + _fileIdx;
-		    tmpObj.fileObj = files[i];
-		     
-		    _fileForm2.push(tmpObj);
-		    sendFileToServer(fd, obj, files[i], _fileIdx);
-		    _fileIdx++;
-		     
-		    var totalfileSize = 0;
-		    $('.totalfileCount').text($('.item_file_size').length) ;
-		    $('.item_file_size').each(function(){
-		    	totalfileSize += $(this).val()*1 ;
-		    });
-		    $('.totalfileSize').text(getStrFileSize(totalfileSize)) ; 
-		}
-	}
-}
-
-//드래그앤 드롭 엑셀 및 텍스트 파일 서버 전송 함수
-function sendFileToServer(formData, obj , fileObj, _fileIdx)
-{
-	var msg;
-	msg = "해당 첨부파일을  수정하시겠습니까?";
-	var data = new FormData(document.msgForm);
-	_fileForm2.forEach(function(obj, idx) {
-		if (obj) data.append("file0", obj.fileObj);
-	});
-	
-	var url = "";
-	
-	// IE11 대응
-	if (fileExt != "") {
-		if(fileExt == "xls" || fileExt == "xlsx"){
-			url = "/web/mjon/addr/sendExelFilePhoneNumAjax.do";
-		}else if(fileExt == "txt"){
-			url = "/web/mjon/addr/sendTxtFilePhoneNumAjax.do";
-		}else{
-			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
-			return;
-		}
-		
-		//엑셀 데이터 변수에 자료가 있으면 지워준다.
-	   	if(excelAddr.length > 0){
-	    	excelAddr = [];
-	    }
-		
-		$.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 == "20000") {
-							alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
-						}
-						else {
-							if(data != null){
-								var arr = []; // 넘어온 데이터를 받은 배열 변수
-								$.each(data, function(i, item){
-									arr.push({name: item.name, phone: item.phone, info1: item.info1, info2: item.info2, info3: item.info3, info4: item.info4, memo: item.memo});
-								});
-		
-								addPhoneInfo(arr); // 연락처를 처리해줄 함수 호출
-							}
-							
-							//메세지가 있는 경우 알려주기
-							if(message != '' && message != null) {
-								alert(returnData.message);
-							}							
-						}
-
-					}else{
-						alert(returnData.message);
-					}
-				} else if(status== 'fail'){
-					alert("저장에 실패하였습니다. !!");
-				}
-			},
-	      	error: function (e) { 
-	      		alert("저장에 실패하였습니다."); 
-	      		console.log("ERROR : ", e); 
-	      	},
-			beforeSend : function(xmlHttpRequest) {
-	        	//로딩창 show
-	        	$('.loading_layer').addClass('active');				
-			},	        	        
-	        complete : function(xhr, textStatus) {
-	        	//로딩창 hide
-	        	$('.loading_layer').removeClass('active');
-			}	      			
-	  	});
-	}
-	
-}
 
 
 //#############################################################################################
@@ -910,33 +321,40 @@
 
 //저장
 function SetAddrMassSave(){
-	gArrRestartIndex = 0;	//배열 재시작카운드
-	gNameList = [];		//치환문자 이름
-	gPhoneList = [];	//받는사람
-	gInfo1List = [];		//치환문자1
-	gInfo2List = [];		//치환문자2
-	gInfo3List = [];		//치환문자3
-	gInfo4List = [];		//치환문자4
-	gMemoList = [];			//메모
+// 	gArrRestartIndex = 0;	//배열 재시작카운드
+// 	gNameList = [];		//치환문자 이름
+// 	gPhoneList = [];	//받는사람
+// 	gInfo1List = [];		//치환문자1
+// 	gInfo2List = [];		//치환문자2
+// 	gInfo3List = [];		//치환문자3
+// 	gInfo4List = [];		//치환문자4
+// 	gMemoList = [];			//메모
 	
-	var selectedData = tableR.getRows();
-	if (selectedData == "" || selectedData == null) {
+	var $objTabul = fn_utils_getTabulator();
+
+	if($objTabul.getData().length < 1){
 		alert("한 개 이상의 연락처를 입력하세요");
 		return false;
 	}
-	else if (selectedData.length > 20000) {
-		alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
-		return false;
-	}
+// 	else if (selectedData.length > 20000) {
+// 		alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
+// 		return false;
+// 	}
 	
 	var selectMassVal = $("#addrGrpIdInfo option:selected").val();
 	
 	var loginVO = '${LoginVO}';
-	if(loginVO == "" || loginVO == null){
+// 	if(loginVO == "" || loginVO == null){
+	if(fn_utils_isEmpty(loginVO)){
 		alert("로그인 후 이용이 가능합니다.");
 		return false;
 	}
-	else if ($("#addrGrpIdInfo option:selected").val() == "NEW" && ($("#addrGrpNm").val() == "" || $("#addrGrpNm").val() == null || $("#addrGrpNm").val() == undefined)) {
+	else if ($("#addrGrpIdInfo option:selected").val() == "NEW" 
+				&& ($("#addrGrpNm").val() == "" 
+						|| $("#addrGrpNm").val() == null 
+						|| $("#addrGrpNm").val() == undefined)
+						) 
+	{
 		alert("저장할 그룹을 선택하거나 새 그룹명을 입력해주세요.");
 		return false;		
 	}
@@ -952,15 +370,40 @@
 	
 	var commaSelectedData = numberWithCommas(selectedData.length);
 	var confirmMsg = "저장하시겠습니까?\n이름 20byte, [*1*]~[*4*] 40byte, 메모 250byte 초과 글자는 절사됩니다.";
-	if (selectedData.length >= 10000) {
-		confirmMsg = "저장하시겠습니까?\n이름 20byte, [*1*]~[*4*] 40byte, 메모 250byte 초과 글자는 절사됩니다.\n1만건 이상 등록시 약 30초정도 소요됩니다.\n잠시만 기다려주세요.";
-	}
+// 	if (selectedData.length >= 10000) {
+// 		confirmMsg = "저장하시겠습니까?\n이름 20byte, [*1*]~[*4*] 40byte, 메모 250byte 초과 글자는 절사됩니다.\n1만건 이상 등록시 약 30초정도 소요됩니다.\n잠시만 기다려주세요.";
+// 	}
 	if (confirm(confirmMsg)) {	
 		//로딩창 show
 		$('.loading_layer').addClass('active');				
 
-		setTimeout(setSenderList, 1000);
+		setTimeout(setSenderList_advc, 1000);
 	}
+}
+
+function setSenderList_advc(){
+
+	var $objTabul = fn_utils_getTabulator();
+	var dataToSend = $objTabul.getData();
+	
+		$.ajax({
+		    type: "POST",
+		    url: "/web/mjon/addr/addrMassInsertByTempAjax_advc.do",
+		    data: JSON.stringify(dataToSend),
+		    dataType: 'json',
+		    contentType: 'application/json',
+		    async: true,
+		    success: function (data) {
+		    	console.log('data : ', data);
+// 		        alert(data.object.message);
+// 		        if (data.object.result == 'success') {
+// 		            location.reload();
+// 		        } 
+		    },
+		    error: function (e) { 
+		        alert("ERROR : " + JSON.stringify(e)); 
+		    }
+		});
 }
 
 function setSenderList() {
@@ -1058,7 +501,7 @@
 		//console.log("gPhoneList.length : " + gPhoneList.length);
 		//console.log("selectedData.length : " + selectedData.length);
 		
-		SetAddrMassSave_Step2();		
+		SetAddrMassSave_Step2();
 	}	
 }
 
@@ -1079,18 +522,18 @@
 	url = "/web/mjon/addr/addrMassInsertByTempAjax.do";
 	
 	$.ajax({
-        type: "POST",
-        url: url,
-        data: data,
-        dataType:'json',
-        async: true,
-        processData: false,
-        contentType: false,
-        cache: false,
-        success: function (returnData) {
-        	//로딩창 hide
-        	$('.loading_layer').removeClass('active');			
-        	
+		type: "POST",
+		url: url,
+		data: data,
+		dataType:'json',
+		async: true,
+		processData: false,
+		contentType: false,
+		cache: false,
+		success: function (returnData) {
+			//로딩창 hide
+			$('.loading_layer').removeClass('active');			
+			
 			if (returnData.isSuccess) { 
 				alert("저장에 성공했습니다.\n저장 : " + returnData.resultCnt + "건, 중복 : " + returnData.dupliCnt + "건, 휴대폰번호 오류 : " + returnData.errPhoneCnt + "건");
 
@@ -1121,22 +564,22 @@
 				alert("오류 알림 : " + returnData.msg);
 			}
 		},
-        error: function (e) { 
-        	//로딩창 hide
-        	$('.loading_layer').removeClass('active');			
-        	
-        	alert("저장에 실패하였습니다."); 
-        	alert("ERROR : " + JSON.stringify(e)); 
-        },
+		error: function (e) { 
+			//로딩창 hide
+			$('.loading_layer').removeClass('active');			
+			
+			alert("저장에 실패하였습니다."); 
+			alert("ERROR : " + JSON.stringify(e)); 
+		},
 		beforeSend : function(xmlHttpRequest) {
-        	//로딩창 show
-        	$('.loading_layer').addClass('active');				
+			//로딩창 show
+			$('.loading_layer').addClass('active');				
 		},	        	        
-        complete : function(xhr, textStatus) {
-        	//로딩창 hide
-        	$('.loading_layer').removeClass('active');
+		complete : function(xhr, textStatus) {
+			//로딩창 hide
+			$('.loading_layer').removeClass('active');
 		}	        
-    });
+	});
 }
 
 //주소록그룹 콤보박스 유지
@@ -1162,33 +605,34 @@
 	}
 }
 
-
+// 주소 대량등록 버튼 클릭 
+// AddrListAjax.jsp에서 호출
 $(document).on('click', '#btnAddrMassRegCall', function() {
 	getAddrGroupList();
 });
 
 // 주소록 그룹정보 불러오기
 function getAddrGroupList() {
-    $.ajax({
-        type : "POST",
-        async : false,
-        url : "/web/mjon/addr/addrGroupListAjax.do",
-        data : {},
-        dataType:'json',
-        success : function(data) {
+	$.ajax({
+		type : "POST",
+		async : false,
+		url : "/web/mjon/addr/addrGroupListAjax.do",
+		data : {},
+		dataType:'json',
+		success : function(data) {
 			//alert(JSON.stringify(data.addrGroupList));
 
 			// Show Html
 			getAddrGroupListShow(data.addrGroupList);
-        },
-        error : function(xhr, status, error) {
-            alert(error);
-            return false;
-        }
-    });	    	
+		},
+		error : function(xhr, status, error) {
+			alert(error);
+			return false;
+		}
+	});	    	
 }
 	
-// Show Html
+// 그룹데이터 노출
 function getAddrGroupListShow(jsonList) {
 	var sHtml = "";
 	sHtml += "<option value='NEW'>그룹추가</option>";
@@ -1197,7 +641,7 @@
 	for (var j = 0; j < jsonList.length; j++) {
 		sHtml += "	<option value='" + $.trim(jsonList[j].addrGrpId) + "' />" + $.trim(jsonList[j].addrGrpNm) + "</option>";
 	}
-	    	
+			
 	$("#addrGrpIdInfo").html(sHtml);
 }
 
@@ -1211,116 +655,15 @@
 //파일 불러오기
 //#############################################################################################
 
-//엑섹불러오기 버튼 클릭시 파일 첨부 실행
-$(document).on('click', '.c3', function() {
-	$("#excelFile").click();
-});
-
-//seetJs 엑셀 파일 불러오기
-function excelExport(event){
-	var data = new FormData(document.excelForm);
-	data.append("file0", $('#excelFile').prop('files')[0]);
-	
-	var fileValue = $("#excelFile").val().split("\\");
-	var fileName = fileValue[fileValue.length-1];
-	
-	var fileExt = fileName.split('.').pop().toLowerCase();
-
-	// IE11 대응
-	if (fileExt != "") {
-		if($.inArray(fileExt, ['txt','xls','xlsx']) == -1) {
-			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
-			return false;
-		}
-		
-		var url = "";
-		
-		if(fileExt == "xls" || fileExt == "xlsx"){
-			url = "/web/mjon/addr/sendExelFilePhoneNumAjax.do";
-		}else if(fileExt == "txt"){
-			url = "/web/mjon/addr/sendTxtFilePhoneNumAjax.do";
-		}else{
-			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
-			return;
-		}
-		
-		//엑셀 데이터 변수에 자료가 있으면 지워준다.
-	   	if(excelAddr.length > 0){
-	    	excelAddr = [];
-	    }
-		
-		$.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 == "20000") {
-							alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
-						}
-						else {						
-							if(data != null){
-								var arr = []; // 넘어온 데이터를 받은 배열 변수
-								$.each(data, function(i, item){
-									arr.push({name: item.name, phone: item.phone, info1: item.info1, info2: item.info2, info3: item.info3, info4: item.info4, memo: item.memo});
-								});
-		
-								addPhoneInfo(arr); // 연락처를 처리해줄 함수 호출
-								
-								//메세지가 있는 경우 알려주기
-								if(message != '' && message != null) {
-									alert(returnData.message);
-								}							
-							}
-						}
-					}else{
-						alert(returnData.message);
-					}
-				} else if(status== 'fail'){
-					alert("저장에 실패하였습니다. !!");
-				}
-			},
-	        error: function (e) {
-	        	alert("저장에 실패하였습니다."); 
-	        	console.log("ERROR : ", e); 
-	        }
-			,
-			beforeSend : function(xmlHttpRequest) {
-	        	//로딩창 show
-	        	$('.loading_layer').addClass('active');				
-			},	        	        
-	        complete : function(xhr, textStatus) {
-	        	//로딩창 hide
-	        	$('.loading_layer').removeClass('active');
-			}	      			
-	    });
-		
-		$("#excelFile").val("");
-	    $("#excelNm").val(fileName); 
-	}
-	
-}
-
 //체크박스 전체선택/해제
 $(document).on("click", "#chkAll", function(e) {
-    var isChecked = $(this).is(":checked");
-    $("input[name=addrCheck]:checkbox").prop("checked", isChecked);
+	var isChecked = $(this).is(":checked");
+	$("input[name=addrCheck]:checkbox").prop("checked", isChecked);
 });
 
 $(document).on("click", "#duplicationChkAll", function(e) {
-    var isChecked = $(this).is(":checked");
-    $("input[name=addrCheck]:checkbox").prop("checked", isChecked);
+	var isChecked = $(this).is(":checked");
+	$("input[name=addrCheck]:checkbox").prop("checked", isChecked);
 });	
 
 //팝업 텍스트 더보기 클릭 시 펼쳐지고 숨겨짐
@@ -1344,31 +687,6 @@
 	window.open("about:blank", 'infoPop', 'width=790, height=430, top=100, left=100, fullscreen=no, menubar=no, status=no, toolbar=no, titlebar=yes, location=no, scrollbars=1');
 	document.popForm.target = "infoPop";
 	document.popForm.submit();
-}
-
-// 주소록 대량등록
-function addrMassTab(tabIdx) {
-	if (tabIdx == 2) {
-		// 붙여넣기
-		$(".upload_area").hide();
-		$(".excel_btn2").hide();
-		$(".req_area").show();
-	}
-	else {
-		$(".upload_area").show();
-		$(".excel_btn2").show();
-		$(".req_area").hide();
-	}
-}
-
-
-function linkPage2(pageNo){
-	var searchForm = document.searchAddrDupliForm;
-	searchForm.pageIndex.value = pageNo;
-	searchForm.pageUnit.value = 10;
-	
-	var sendData = $(document.searchAddrDupliForm).serializeArray();
-	$("#duplication_layer").load("/web/mjon/addr/selectAddrDupliAjax.do", sendData, function(response, status, xhr){});
 }
 
 // 중복 연락처
@@ -1423,6 +741,14 @@
 	$("#addrMassSaveDupli_layer").html(sHtml);
 }
 
+
+// function fn_tabToggle('1')
+function fn_tabToggle(tabNum){
+	var tabId = '#tab'+tabNum;
+	$('.tab_c').hide();
+	$(tabId).show();
+}
+
 </script>
 
 <div class="loading_layer">
@@ -1431,147 +757,58 @@
 		<div class="text">Loading</div>
 	</div>
 </div>
+
+<div id="adrPopup_tab1">
+
 <!-- 수신거부 대량등록  data-tooltip:adr_popup01 -->
-<form id="addrMassForm" name="addrMassForm" method="post">
-	<input type="hidden" id="phoneList" name="phoneList" value=""/>
-	<input type="hidden" id="nameList" name="nameList" value=""/>
-	<input type="hidden" id="info1List" name="info1List" value=""/>
-	<input type="hidden" id="info2List" name="info2List" value=""/>
-	<input type="hidden" id="info3List" name="info3List" value=""/>
-	<input type="hidden" id="info4List" name="info4List" value=""/>
-	<input type="hidden" id="memoList" name="memoList" value=""/>
-	<input type="hidden" id="addrGrpId" name="addrGrpId" value=""/>
-	<div class="tooltip-wrap" id="addrMassLoad">
-		<div class="popup-com adr_layer adr_popup01" tabindex="0" data-tooltip-con="adr_popup01" data-focus="adr_popup01" data-focus-prev="adr_popup01-close" style="width: 1000px;">
-			<div class="popup_heading">
-	               <p>주소록 대량등록</p>
-	               <button type="button" class="tooltip-close" data-focus="adr_popup01-close" onclick="setAddrMassClose();"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
-	           </div>
-	           <div class="layer_in" style="padding: 25px 30px;">
-	               <div class="list_tab_wrap2">
-	                   <!-- tab button -->
-	                   <ul class="list_tab"> 
-	                       <li class="tab active"><button type="button" onclick="popupTab(this,'1'); addrMassTab('1');">엑셀입력</button></li>
-	                       <li class="tab"><button type="button" onclick="popupTab(this,'2'); addrMassTab('2');">붙여넣기</button></li>
-	                   </ul><!--// tab button -->
-	               </div>
-	               <!-- 엑셀입력 -->
-	               <div class="popCont current pop_more_cont" id="popCont_1">
-	                   <div class="titBox">
-							<p>- 엑셀(EXCEL) 파일로 주소록을 한 번에 최대 2만건까지 등록하여 간편하게 발송 및 관리하실 수 있습니다.</p>
-							<p>- 반드시 샘플파일을 다운로드하여 작성방법을 확인하신 후 정해진 양식에 맞추어 주소록을 작성하셔야 합니다.</p>
-							<p>  &nbsp;&nbsp;※ 주소록 관리 메뉴에서 다운로드 받으신 엑셀 파일 또한 업로드 양식에 맞추어 작성하셔야 하며, </p>
-							<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;주소록에 이미 등록된 휴대폰 번호는 업데이트 되지 않으므로 기존 주소록에서 해당 휴대폰 번호를 삭제한 후 재등록해 주시기 바랍니다.</p>
-							<p>- 쉼표(,), 구분선(|), 역슬래시(\, ₩), 작은따옴표('), 큰따옴표(") 등 발송불가 특수문자는 저장되지 않습니다.</p>
-							<p>- 휴대폰 번호는 필수입력 항목입니다.</p>
-							<p>- 전화번호 형태는 010-1234-5678 또는 01012345678 모두 가능합니다. 단, 공백은 허용되지 않습니다.</p>
-							<p>- 엑셀 파일에 비밀번호 설정, 제한된 보기, 수식 등이 설정되어 있는 경우 업로드가 불가합니다.</p>
-							<p>- 이름 20byte, [*1*]~[*4*] 40byte, 메모 250byte까지 입력 가능합니다.</p>
-							<p>- 첨부가능 파일 : xlsx, xls(최대용량 3MB)</p>
-							<p>- ‘오류 검사’를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.</p>
-							<p>- 주소록 등록이 어려우신 경우에는 주소록 입력대행 메뉴를 이용하시면 됩니다.</p>
-	                       <button type="button" class="excel_btn" onclick="location.href='/download/addr/주소록_대량등록.xlsx'"><i class="downroad"></i>샘플파일 다운로드</button>
-	                   </div>
-	                   <div class="pop_more_wrap">
-	                   		<button type="button" class="pop_more" onclick="popMore(this);">더보기<i></i></button>
-	                   </div>
-	                </div><!--// 엑셀입력 -->
-	                
-	                <!-- 붙여넣기 -->
-	                <div class="popCont pop_more_cont" id="popCont_2">
-	                    <div class="titBox">
-	                        <p>- 텍스트(txt) 파일로 작성된 주소록을 등록하실 수 있습니다.</p>
-	                        <p>- 반드시 샘플파일을 다운로드하여 작성방법을 확인하신 후 정해진 양식에 맞추어 주소록을 붙여 넣으셔야 합니다.</p>
-	                        <p>- 입력 내용은 (Tab) 또는 (,) 구분하여 입력하여야 합니다.</p>
-	                        <p>- 한 줄(열)에 주소 한 건만 입력 가능합니다.</p>
-	                        <p>- 전화번호 형태는 010-1234-5678 또는 01012345678 모두 가능합니다. 단, 공백은 허용되지 않습니다.</p>
-	                        <p>&nbsp;&nbsp;(예) 홍길동,010-1234-5678 또는 홍길동,01012345678</p>
-	                        <p>- 한번에 많은 양의 데이터를 입력하시려면 ‘주소록 복사(Ctrl+c) + 붙여넣기(Ctrl+v)’ 또는 ‘엑셀입력’을 이용하세요.</p>
-	                        <p>- 주소록 등록이 어려우신 경우에는 주소록 입력대행 메뉴를 이용하시면 됩니다.</p>
-	                        <button type="button" class="txt_btn" onclick="location.href='/download/addr/주소록_대량등록.zip'"><i></i>TXT샘플 다운로드</button>                        
-	                    </div>
-	                    <div class="pop_more_wrap">
-	                   		<button type="button" class="pop_more" onclick="popMore(this);">더보기<i></i></button>
-	                   </div>
-	                </div><!--// 붙여넣기 -->                
-	
-					<!-- 공통 -->
-					<div>
-		                <table class="layer_tType1">
-		                    <caption>엑셀입력 표</caption>
-		                    <colgroup>
-		                        <col style="width: 95px">
-		                        <col style="width: auto">
-		                    </colgroup>
-		                    <tbody>
-		                        <tr>
-		                            <th>그룹 선택</th>
-		                            <td>
-		                                <label for="" class="label">그룹 선택</label>
-		                                <select id="addrGrpIdInfo" name="addrGrpIdInfo">
-		                                </select>
-	                                    <label for="" class="label">그룹명 입력</label>
-	                                    <input type="text" id="addrGrpNm" name="addrGrpNm" placeholder="새 그룹명을 입력해주세요." onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명을 입력해주세요.'"class="inputLight" style="width: 300px;">
-	
-		                                <input type="file" id="excelFile" accept=".xls, .xlsx, .txt" onchange="excelExport(event); return false;" style="display:none"/>
-		                                <button type="button" class="excel_btn2 btnType c3"><i class="uproad"></i>엑셀, TXT파일 업로드</button>
-		                            </td>
-		                        </tr>
-		                    </tbody>
-		                </table>
-	                </div>
-					<div class="file_add upload_area">
-						<p><img src="/publish/images/content/file_add.png" alt="파일 붙여넣기">마우스로 엑셀, TXT파일을 여기에 끌어다 놓으세요</p>
-					</div>
-					<div class="excel_middle2">
-						<p>
-							총 <span class="c_e40000 fwBold" id="rowTotCnt">0</span>건 / 중복 <span class="c_002c9a fwBold" id="rowDupCnt">0</span>건
-							&nbsp; 
-							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" onclick="GetAddrMassDupli()" id="btnAddrMassDupli">중복번호</button>
-							&nbsp;
-							<button type="button" class="btnType btnType6" data-tooltip="addrMassSaveDupli_layer" onclick="GetAddrMassSaveDupli()" id="btnAddrMassSaveDupli">중복번호</button>
-						</p>
-						<button type="button" class="btnType btnType6 addCallToF">번호추가</button>
-					</div>
-					<div class="drag_drop_wrap callList_box">
-						<img src="/publish/images/content/excel.jpg" style="width: 100%;">
-					</div>
-					<div class="excel_middle">
-						<div class="select_btnWrap clearfix">
-							<div>
-								<button type="button" class="all_del"><i class="remove_img"></i>전체삭제</button>
-								<button type="button" class="select_del"><i class="remove_img"></i>선택삭제</button>
-								<button type="button" class="chkVali_del"><i class="remove_img"></i>오류번호삭제</button>
-								<button type="button" class="check_validity">오류 검사 <i></i></button>
-								<div class="error_hover_cont send_hover_cont addr_hover_cont">
-									<p>휴대폰 번호 입력 시 해당 휴대폰 번호에 대한 형식이 어긋나거나 휴대폰 번호에 오류가 있는지 등을 검사하는 기능</p>
-									<span>(예시) 010-1234-0001(O) / 010-123-0001(X)</span>
-								</div>
-							</div>
-	
+	<form id="addrMassForm" name="addrMassForm" method="post">
+		<input type="hidden" id="phoneList" name="phoneList" value=""/>
+		<input type="hidden" id="nameList" name="nameList" value=""/>
+		<input type="hidden" id="info1List" name="info1List" value=""/>
+		<input type="hidden" id="info2List" name="info2List" value=""/>
+		<input type="hidden" id="info3List" name="info3List" value=""/>
+		<input type="hidden" id="info4List" name="info4List" value=""/>
+		<input type="hidden" id="memoList" name="memoList" value=""/>
+		<input type="hidden" id="addrGrpId" name="addrGrpId" value=""/>
+		<div class="tooltip-wrap" id="addrMassLoad">
+			<div class="popup-com adr_layer adr_popup01" tabindex="0" data-tooltip-con="adr_popup01" data-focus="adr_popup01" data-focus-prev="adr_popup01-close" style="width: 1000px;">
+				<div class="popup_heading">
+					   <p>주소록 대량등록</p>
+					   <button type="button" class="tooltip-close" data-focus="adr_popup01-close" onclick="setAddrMassClose();"><img src="/publish/images/content/layerPopup_close.png" alt="팝업 닫기"></button>
+				   </div>
+				   <div class="layer_in" style="padding: 25px 30px;">
+					   <div class="list_tab_wrap2">
+						   <!-- tab button -->
+						   <ul class="list_tab" id="tbTabl"> 
+							   <li class="tab active" data-tabul="tableExcel"><button type="button" onclick="popupTab(this,'1'); fn_tabToggle('1');">엑셀입력</button></li>
+							   <li class="tab" data-tabul="tableClip"><button type="button" onclick="popupTab(this,'2'); fn_tabToggle('2');">붙여넣기</button></li>
+							   <li class="tab" data-tabul="tableSelf"><button type="button" onclick="popupTab(this,'3'); fn_tabToggle('3');">붙여넣기</button></li>
+						   </ul><!--// tab button -->
+					   </div>
+					   
+					   
+						<div id="tab1" class="tab_c">
+					  		<%@include file="/WEB-INF/jsp/web/addr/include/addrListforExcel.jsp" %>
 						</div>
-					</div><!--// 공통 -->     
-	
-					<!-- 붙여놓기 설명 -->
-	                <div class="req_area">
-	                  	<div class="text_box">
-	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br>
-							- 휴대폰 번호는 필수입력 항목입니다.<br>
-							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br>
-							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br>
-							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.
+						<div id="tab2" class="tab_c" style="display: none;">
+					  		<%@include file="/WEB-INF/jsp/web/addr/include/addrListforClipboard.jsp" %>
 						</div>
-	                </div>
-	
-	
-	           </div>
-	           <div class="popup_btn_wrap2" style="margin: 0 auto 30px auto;">
-	               <button type="button" id="btnAddrMassReg">등록</button>
-	               <button type="button" id="btnAddrMassClose" class="tooltip-close" data-focus="adr_popup01-close"  data-focus-next="popup02">닫기</button>                      
-	           </div>
+<!-- 						<div id="tab3" class="tab_c" style="display: none;"> -->
+						<div id="tab3" class="tab_c" style="display: none;">
+					  		<%@include file="/WEB-INF/jsp/web/addr/include/addrListforSelf.jsp" %>
+						</div>
+						   
+					   <div class="popup_btn_wrap2" style="margin: 0 auto 30px auto;">
+						   <button type="button" id="btnAddrMassReg">등록</button>
+						   <button type="button" id="btnAddrMassClose" class="tooltip-close" data-focus="adr_popup01-close"  data-focus-next="popup02">닫기</button>                      
+					   </div>
+				   	
+				</div>
+			</div>
 		</div>
-	</div>
-</form>
+	</form>
+
+</div>
 <!--// 주소록 대량등록 팝업 -->
 
 <div class="inner">
@@ -1589,7 +826,7 @@
 		<div class="adr_cont current" id="tab5_1">
 			<div class="heading">
 				<h2>주소록 관리</h2>
-	        	<button type="button" class="button info" onclick="infoPop('selectAddrList');">사용안내</button>
+				<button type="button" class="button info" onclick="infoPop('selectAddrList');">사용안내</button>
 			</div>
 			<%--<div class="titBox">
 				<p>- 연락처를 그룹별로 분류하여 간편하고 편리하게 관리할 수 있습니다(최대 100,000개까지 등록 가능)</p>
@@ -1614,6 +851,11 @@
 	</div><!--// 주소록 관리 - 주소록 관리 -->
 </div><!--// send top -->
 
+
+
+<!--===================================================================  -->
+
+
 <form name="popForm" id="popForm" method="post">
 	<input type="hidden" name="pageType" id="pageType" value=""/> 
 </form>
src/main/webapp/WEB-INF/jsp/web/addr/AddrList_advcBack_20240723.jsp (Renamed from src/main/webapp/WEB-INF/jsp/web/addr/AddrList_advcBackup_20240717.jsp)
--- src/main/webapp/WEB-INF/jsp/web/addr/AddrList_advcBackup_20240717.jsp
+++ src/main/webapp/WEB-INF/jsp/web/addr/AddrList_advcBack_20240723.jsp
@@ -203,7 +203,9 @@
 		width:"100%",
 	    layout:"fitColumns",
 	    //data:tabledata,
-	    //autoColumns:true,
+// 	    autoColumns:true,
+	    autoColumns:false,
+	    
 	    headerHozAlign:"center",
 	    validationMode:"highlight",
 	    clipboard:false,
@@ -215,13 +217,20 @@
 	 	        cell.getRow().toggleSelect();
 		 		}
 		 	}, 
-		 	{title:"이름", hozAlign:"center", field:"name", editor:"input", width:140, validator:["maxLength:12", "string"]},
+		 	{title:"A", hozAlign:"center", headerHozAlign: "center", field:"A", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"B", hozAlign:"center", headerHozAlign: "center", field:"B", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"C", hozAlign:"center", headerHozAlign: "center", field:"C", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"D", hozAlign:"center", headerHozAlign: "center", field:"D", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"E", hozAlign:"center", headerHozAlign: "center", field:"E", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"F", hozAlign:"center", headerHozAlign: "center", field:"F", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"G", hozAlign:"center", headerHozAlign: "center", field:"G", editor:"input", width:125, validator:["maxLength:100", "string"]}
+/* 		 	{title:"이름", hozAlign:"center", field:"name", editor:"input", width:140, validator:["maxLength:12", "string"]},
 		 	{title:"휴대폰", hozAlign:"center", field:"phone", editor:"input", width:145, validator:["required","minLength:10", "maxLength:13"]},
 		 	{title:"[*1*]", hozAlign:"center", field:"info1", editor:"input", width:100, validator:["maxLength:100", "string"]},
 		 	{title:"[*2*]", hozAlign:"center", field:"info2", editor:"input", width:100, validator:["maxLength:100", "string"]},
 		 	{title:"[*3*]", hozAlign:"center", field:"info3", editor:"input", width:100, validator:["maxLength:100", "string"]},
 		 	{title:"[*4*]", hozAlign:"center", field:"info4", editor:"input", width:100, validator:["maxLength:100", "string"]},
-		 	{title:"메모", hozAlign:"center", field:"memo", editor:"input", width:119, validator:["maxLength:100", "string"]}
+		 	{title:"메모", hozAlign:"center", field:"memo", editor:"input", width:119, validator:["maxLength:100", "string"]} */
 	 	],
 	 	validationFailed:function(cell, value, parameters){ // 유효성 체크 함수 
 	        var valid = cell.isValid();
@@ -235,138 +244,139 @@
 	    },
 	});
 
+	 $(".field-selector").on("change", function() {
+		 
+
+		    var selectedFields = [];
+		    var isDuplicate = false;
+		    $(".field-selector").each(function() {
+		        var selectedField = $(this).val();
+		        if (selectedField) {
+		            if (selectedFields.includes(selectedField)) {
+		                alert("중복된 필드를 선택할 수 없습니다.");
+		                $(this).val(""); // 중복 필드를 선택한 경우 빈 값으로 초기화
+		                isDuplicate = true;
+		                return false; // 반복문 종료
+		            }
+		            selectedFields.push(selectedField);
+		        }
+		    });
+		    console.log('!! : ', $(this).val() == 'phone');
+	        updateTableFields();
+	        
+	        if($(this).val() == 'phone'){
+	        	fn_phoneDupl();
+	        }
+    });
+    // 파일 선택 버튼 클릭 이벤트
+    $("#file-load-trigger").on("click", function() {
+        $("#excelFile").click();
+    });
+
+    // 파일 입력 이벤트
+    $("#excelFile").on("change", function(event) {
+    	excelFileChange(event.target.files[0]);
+    });
+    
+
+	
 	//받는 사람 리스트 영역에 클립보드 데이터 가져와보기 
+	// 붙여넣기 기능
 	$('.callList_box').on('paste', function (e) {
 		var element = e.originalEvent.clipboardData.getData('text'); // 클립보드에 복사한 데이터 가져오기
 		var elmSplit= [];
 		elmSplit = element.split("\n");
 		var elmLen = elmSplit.length;
+		console.log('elmSplit : ', elmSplit);
 		if(elmLen < 0){
 			alert("붙여넣을 연락처를 복사해주세요.");
 			return false;
-		}else{
-			if (elmLen > 20001) {
-				alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
-				return false;
-			}			
-			
-			tableErrorData.length = 0;	// 오류 번호 배열 초기화
+		}
+		if (elmLen > 20001) {
+			alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
+			return false;
+		}			
+		
+		tableErrorData.length = 0;	// 오류 번호 배열 초기화
 
-			var splitData = [];
-			var realPhone = [];
-			for(var i=0; i < elmLen; i++){
-				var splitStr = elmSplit[i];
-				var tabData = splitStr.split("\t"); //탭 구분으로 데이터 분할
-				var comData = splitStr.split(","); //콤마 구분으로 데이터 분할
-				if(tabData.length >= 2){
-					splitData = tabData;
-				}else{
-					splitData = comData;
-				}
+		var splitData = [];
+		var realPhone = [];
+		
+		for(var i=0; i < elmLen; i++){
+			var splitStr = elmSplit[i];
+			var tabData = splitStr.split("\t"); //탭 구분으로 데이터 분할
+			var comData = splitStr.split(","); //콤마 구분으로 데이터 분할
+			if(tabData.length >= 2){
+				splitData = tabData;
+			}else{
+				splitData = comData;
+			}
 				
-				if(splitData.length == 0){// 데이터가 없는경우
-					alert("탭으로 구분하여 데이터를 복사해 주세요.");
-				  	return false;
-				}else if(splitData.length == 1){// 데이터가 탭으로 구분이 없는 경우
-					for(var j=0; j < splitData.length; j++){
-						if(checkHpNum(splitData[j].trim())){//핸드폰 양식이 맞는지 확인
-							//배열 끝에 데이터 추가해 주기
-							realPhone.push({name: "", phone: removeDash(splitData[j].trim())});
-						}
-						else {
-							if (splitData[j].trim() != '' && splitData[j].trim() != null && splitData[j].trim() != undefined) {
-								tableErrorData.push(splitData[j].trim());
-							}							
-						}
-					}
-				}else{//데이터가 탭으로 구분되어 이름, 연락처로 구분된 경우
-					var name;	//이름
-					var phone;	//핸드폰번호					
-					var info1;
-					var info2;
-					var info3;
-					var info4;
-					var memo;	//메모
-					var isPhoneValid = false;
-					for(var j=0; j < splitData.length; j++){
-						if(j == 0){
-							name = splitData[j].trim();
-						}
-						if(j == 1){
-							if(checkHpNum(splitData[j].trim())){//핸드폰 양식이 맞는지 확인
-								phone = removeDash(splitData[j].trim());
-								isPhoneValid = true;
-							}
-							else {
-								if (splitData[j].trim() != '' && splitData[j].trim() != null && splitData[j].trim() != undefined) {
-									tableErrorData.push(splitData[j].trim());
-								}
-							}
-						}
-						
-						if(j == 2){
-							info1 = splitData[j].trim();
-						}
-						if(j == 3){
-							info2 = splitData[j].trim();
-						}
-						if(j == 4){
-							info3 = splitData[j].trim();
-						}
-						if(j == 5){
-							info4 = splitData[j].trim();
-						}						
-						
-						if(j == 6){	//메모
-							memo = splitData[j].trim();
-						}
-					}
-					
-					if (isPhoneValid == true) {
-						//배열 끝에 데이터 추가해 주기
-						realPhone.push({name: name, phone: phone, info1 : info1, info2 : info2, info3 : info3, info4 : info4, memo : memo });
-					}
-				}//else end
+			if(splitData.length == 0){// 데이터가 없는경우
+				alert("탭으로 구분하여 데이터를 복사해 주세요.");
+			  	return false;
 			}
 			
-			var recTableData = tableR.getRows();		 // 받는사람 리스트의 전체 목록을 저장
-			var tableData = [];
 			
-			//기존 받는사람 리스트를 배열에 미리 담아둔다.
-			if(recTableData.length > 0){
-				for(var j=0; j < recTableData.length; j++){
-					tableData.push({name: recTableData[j].getData().name, phone: removeDash(recTableData[j].getData().phone.trim()), info1: recTableData[j].getData().info1, info2: recTableData[j].getData().info2, info3: recTableData[j].getData().info3, info4: recTableData[j].getData().info4, memo: recTableData[j].getData().memo});
-				}
-			}
-			
-			if(realPhone.length > 0){
-				for(var j=0; j < realPhone.length; j++){
-					tableData.push({name: realPhone[j].name, phone: removeDash(realPhone[j].phone.trim()), info1: realPhone[j].info1, info2: realPhone[j].info2, info3: realPhone[j].info3, info4: realPhone[j].info4, memo: realPhone[j].memo});
-				}
-			}
-			
-			//tableData.push(realPhone);
+			if(splitData.length == 1){
+				realPhone.push({A: splitData[0].trim()});
+			}else{
 				
-			//중복 연락처 1개만 남기고 삭제하기
-			var removeDuplPhone = dupliPhoneData(tableData);
-			  
-			//수신자 리스트에 전화번호 추가해주기
-			//tableR.addData(removeDuplPhone);
-			tableR.setData(removeDuplPhone);
+				let keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
+				let data = {};
+
+				splitData.forEach((item, index) => {
+				    data[keys[index]] = item.trim();
+				});
+
+				realPhone.push(data);
+			}//else end
+		}
+		console.log('realPhone : ', realPhone);
+		var recTableData = tableR.getRows();		 // 받는사람 리스트의 전체 목록을 저장
+		var tableData = [];
+		
+		//기존 받는사람 리스트를 배열에 미리 담아둔다.
+		if (recTableData.length > 0) {
+		    recTableData.forEach(item => {
+		        tableData.push(createDataObject(item.getData()));
+		    });
+		}
 			
-			totRows = tableR.getRows().length; 
-			updateTotCnt(totRows); //전체 데이터 갯수 구하기
+		if (realPhone.length > 0) {
+		    realPhone.forEach(item => {
+		        tableData.push(createDataObject(item));
+		    });
+		}
 			
-			if (tableErrorData.length > 0) {
-				alert("올바르지 않은 휴대폰 번호가 "+ tableErrorData.length +" 건 있습니다.");
-				//for(var x=0; x < tableErrorData.length; x++){
-				//	alert(tableErrorData[x]);
-				//}
-			}
+		//tableData.push(realPhone);
+			
+		//중복 연락처 1개만 남기고 삭제하기
+		// 20240719 개선작업은 폰위치가 따로없어 중복제거를 못함
+// 			var removeDuplPhone = dupliPhoneData(tableData);
+		var removeDuplPhone = tableData;
+		  
+		//수신자 리스트에 전화번호 추가해주기
+		//tableR.addData(removeDuplPhone);
+		tableR.setData(removeDuplPhone);
+		
+		totRows = tableR.getRows().length; 
+		updateTotCnt(totRows); //전체 데이터 갯수 구하기
+		
+		if (tableErrorData.length > 0) {
+			alert("데이터를 확인해 주세요.");
+			// 	alert("올바르지 않은 휴대폰 번호가 "+ tableErrorData.length +" 건 있습니다.");
+			//for(var x=0; x < tableErrorData.length; x++){
+			//	alert(tableErrorData[x]);
+			//}
 		}
 	});
 
+	
 	//tableR.setData(tabledata);
+	
+	
+	
 
 	//받는사람 번호 버튼 클릭시 Tabulator에 데이터 넣어주기
 	$('.addCallToF').click(function(){ 
@@ -447,6 +457,8 @@
 	    if(totLen > 0){
 	    	if(confirm("올바르지 않은 연락처 정보를 삭제 하시겠습니까?")){
 	    		for(var i=0; i < totLen; i++){
+
+	    			
 	            	var phone = data[i].getData().phone;
 	            	var valiCheck = checkHpNum(phone);
 	            	if(valiCheck){
@@ -476,8 +488,84 @@
 	    	return false;
 	    }
 	});
+	
+
+    // 필드 선택 이벤트 핸들러
+    $("#column-selector").on("change", function() {
+        let selectedField = $(this).val();
+        let newValue = prompt("새 값을 입력하세요:");
+        if (newValue !== null) {
+            updateTableField(selectedField, newValue);
+        }
+    });
+
+    function updateTableFields() {
+    	var currentData = tableR.getData();
+    	var columns = [
+    		{formatter: "rowSelection", titleFormatter: "rowSelection", clipboard: false, hozAlign: "center", headerHozAlign: "center", headerSort: false, cellClick: function(e, cell) {
+    			cell.getRow().toggleSelect();
+    		}}
+    	];
+
+    	var fieldMapping = [];
+    	$(".field-selector").each(function(index) {
+    		var selectedField = $(this).val();
+    		//  ASCII 문자 코드 사용 - 65=A, 66=B ...
+    		var field = String.fromCharCode(65 + index);
+    		if (selectedField) {
+    			columns.push({title: field, field: selectedField, hozAlign: "center", headerHozAlign: "center", editor: "input", width: 125, validator: ["maxLength:100", "string"]});
+    			fieldMapping.push(selectedField);
+    		} else {
+    			columns.push({title: field, field: field, hozAlign: "center", headerHozAlign: "center", editor: "input", width: 125, validator: ["maxLength:100", "string"]});
+    			fieldMapping.push(field);
+    		}
+    	});
+
+    	var updatedData = currentData.map(row => {
+    		var newRow = {};
+    		fieldMapping.forEach((field, index) => {
+    			newRow[field] = row[Object.keys(row)[index]] || "";
+    		});
+    		return newRow;
+    	});
+
+    	tableR.setColumns(columns);
+    	tableR.setData(updatedData);
+    }
 
 
+
+
+    function fn_phoneDupl(){
+    	
+    	var phoneFields = tableR.getData().map(row => row.phone);
+
+//     	if (phoneFields.length === 0) {
+//     		alert("타이틀을 선택해 주세요");
+//     		return;
+//     	}
+
+    	var uniquePhones = new Set();
+    	var duplicatePhones = [];
+
+    	phoneFields.forEach(phone => {
+    		if (uniquePhones.has(phone)) {
+    			duplicatePhones.push(phone);
+    		} else {
+    			uniquePhones.add(phone);
+    		}
+    	});
+
+    	$('#rowDupCnt').text(duplicatePhones.length);
+    	if (duplicatePhones.length > 0) {
+    		alert("중복된 phone 필드 값이 있습니다: " + duplicatePhones.join(", "));
+    	} else {
+    		alert("중복된 phone 필드 값이 없습니다.");
+    	}
+    }
+    
+    
+    
 	// 오류검사 항목 중복제거
 	function SetTableErrorDupliCheck(sVal) {
 		var isDuplicate = false;
@@ -626,33 +714,43 @@
 }
 
 function addPhoneInfo(data){
+	console.log('data : ', data);
 	if(data == null){
 		alert("연락처 정보가 없습니다.");
 		return;
 	}else{
 		var idx = 0;
-		var newData = data;//중복 연락처는 하나만 남기고 모두 제거
+		var newData = data;
 		
 		var recTableData = tableR.getRows();		 // 받는사람 리스트의 전체 목록을 저장
 		var tableData = [];
 		
 		//기존 받는사람 리스트를 배열에 미리 담아둔다.
 		if(recTableData.length > 0){
-			for(var j=0; j < recTableData.length; j++){
-				tableData.push({name: recTableData[j].getData().name, phone: removeDash(recTableData[j].getData().phone.trim()), info1: recTableData[j].getData().info1, info2: recTableData[j].getData().info2, info3: recTableData[j].getData().info3, info4: recTableData[j].getData().info4, memo: recTableData[j].getData().memo});
-			}
+// 			for(var j=0; j < recTableData.length; j++){
+// 				tableData.push({name: recTableData[j].getData().name, phone: removeDash(recTableData[j].getData().phone.trim()), info1: recTableData[j].getData().info1, info2: recTableData[j].getData().info2, info3: recTableData[j].getData().info3, info4: recTableData[j].getData().info4, memo: recTableData[j].getData().memo});
+// 			}
+
+		    recTableData.forEach(item => {
+		        tableData.push(createDataObject(item.getData()));
+		    });
+
 		}
 		
 		//받는사람 리스트를 담아둔 배열에 신규 추가 데이터를 추가해 준다.
-		for(var i=0; i < newData.length; i++){
-			tableData.push({name: newData[i].name.trim(), phone: removeDash(newData[i].phone.trim()), info1: newData[i].info1, info2: newData[i].info2, info3: newData[i].info3, info4: newData[i].info4, memo: newData[i].memo});
-		}
+// 		for(var i=0; i < newData.length; i++){
+// 			tableData.push({name: newData[i].name.trim(), phone: removeDash(newData[i].phone.trim()), info1: newData[i].info1, info2: newData[i].info2, info3: newData[i].info3, info4: newData[i].info4, memo: newData[i].memo});
+// 		}
+		newData.forEach(item => {
+	        tableData.push(createDataObject(item));
+	    });
 		
 		var temp = tableData.length;
 		
 		//기존 수신 리스트를 지워준 후 신규 전체 리스트를 추가해준다.
 		tableR.clearData(); //기존 받는사람 목록을 삭제.
-		tableR.addData(dupliPhoneData(tableData)); // 받는사람 목록에 주소 정보 입력하기
+// 		tableR.addData(dupliPhoneData(tableData)); // 받는사람 목록에 주소 정보 입력하기
+		tableR.addData(tableData); // 받는사람 목록에 주소 정보 입력하기
 		_fileForm2 = []; //form file data 초기화
 		_fileIdx = 0;	//form file idx 초기화
 		
@@ -661,18 +759,30 @@
 	}
 }
 
-/* 파일사이즈 가져오기 */
-function getStrFileSize(filesize){
-	var sizeStr="";
-	var sizeKB = filesize/1024;
-	if(parseInt(sizeKB) > 1024){
-	    var sizeMB = sizeKB/1024;
-	    sizeStr = sizeMB.toFixed(2)+" MB";
-	}else{
-	    sizeStr = sizeKB.toFixed(2)+" KB";
-	}
-	return sizeStr;
+// 데이터 객체를 생성하는 함수
+function createDataObject(data) {
+    return {
+        A: data.A,
+        B: data.B,
+        C: data.C,
+        D: data.D,
+        E: data.E,
+        F: data.F,
+        G: data.G
+    };
 }
+/* 파일사이즈 가져오기 */
+// function getStrFileSize(filesize){
+// 	var sizeStr="";
+// 	var sizeKB = filesize/1024;
+// 	if(parseInt(sizeKB) > 1024){
+// 	    var sizeMB = sizeKB/1024;
+// 	    sizeStr = sizeMB.toFixed(2)+" MB";
+// 	}else{
+// 	    sizeStr = sizeKB.toFixed(2)+" KB";
+// 	}
+// 	return sizeStr;
+// }
 
 //#############################################################################################
 //파일업로드 드래그앤 드롭
@@ -691,7 +801,8 @@
   //$(this).css('border', '2px dotted #0B85A1');
   e.preventDefault();
   var files = e.originalEvent.dataTransfer.files;
-  handleFileUpload(files,objDragAndDrop);  //파일업로드
+//   handleFileUpload(files,objDragAndDrop);  //파일업로드
+  excelFileChange(files[0]);
 });
 
 $(document).on('dragenter', function (e){
@@ -709,141 +820,197 @@
 });
 //파일 드래그앤드롭 종료
 
-function handleFileUpload(files,obj)  //업로드 function
-{
-	_fileForm2 = []; //form file data 초기화
-	
-	var limitsize = 50*1024*1024;  //파일 제한 체크(50개, 50MB)
-	var limitcount = 1;//$("input[name=limitcount]").val()*1 ;
-	var fileNece = true; //첨부파일필수
- 
- 
-	if($('#fileNece').length > 0){
-		if('N'==$('#fileNece').val()){
-			fileNece = false;  
-		}
- 	}
- 
-	//엑셀 및 TXT 파일만 업로드 할수 있도록 체크하기
-	var fileNm = files[0].name;
-	fileExt = fileNm.split('.').pop().toLowerCase();
 
-	// IE11 대응
-	if (fileExt != "") { 
-		if($.inArray(fileExt, ['txt','xls','xlsx']) == -1) {
-			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
-			return;
-		}
+    function excelFileChange(file){
+
+//         var file = event.target.files[0];
+        if (file) {
+            var reader = new FileReader();
+            reader.onload = function(e) {
+                var data = new Uint8Array(e.target.result);
+                var workbook = XLSX.read(data, {type: 'array'});
+                var firstSheet = workbook.Sheets[workbook.SheetNames[0]];
+                var jsonData = XLSX.utils.sheet_to_json(firstSheet, {header: 1});
+                processExcelData(jsonData);
+            };
+            reader.readAsArrayBuffer(file);
+        }
+    }
+
+    // 엑셀 데이터 처리 함수
+    function processExcelData(data) {
+    	console.log('>>???');
+        var keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
+        var tableData = [];
+
+        // 3번째 행부터 입력 
+        // 1,2행은 예시와 타이틀이라 입력안함
+        data.slice(2).forEach(row => {
+            var rowData = {};
+            keys.forEach((key, index) => {
+                rowData[key] = row[index] ? row[index].trim() : ""; // 각 컬럼에 대해 기본값을 설정
+            });
+            tableData.push(rowData);
+        });
+
+
+        tableR.setColumns([ // 열 정의를 다시 설정
+            {formatter: "rowSelection", titleFormatter: "rowSelection", clipboard: false, hozAlign: "center", headerHozAlign: "center", headerSort: false, cellClick: function(e, cell) {
+                cell.getRow().toggleSelect();
+            }},
+            {title: "A", hozAlign: "center", headerHozAlign: "center", field: "A", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "B", hozAlign: "center", headerHozAlign: "center", field: "B", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "C", hozAlign: "center", headerHozAlign: "center", field: "C", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "D", hozAlign: "center", headerHozAlign: "center", field: "D", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "E", hozAlign: "center", headerHozAlign: "center", field: "E", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "F", hozAlign: "center", headerHozAlign: "center", field: "F", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "G", hozAlign: "center", headerHozAlign: "center", field: "G", editor: "input", width: 125, validator: ["maxLength:100", "string"]}
+        ]);
+        
+        tableR.setData(tableData).then(() => {
+            // rowTotCnt 업데이트
+            document.getElementById("rowTotCnt").innerText = tableData.length;
+        });
+    }
+
+
+    
+    
+// function handleFileUpload(files,obj)  //업로드 function
+// {
+// 	_fileForm2 = []; //form file data 초기화
+	
+// 	var limitsize = 50*1024*1024;  //파일 제한 체크(50개, 50MB)
+// 	var limitcount = 1;//$("input[name=limitcount]").val()*1 ;
+// 	var fileNece = true; //첨부파일필수
+ 
+ 
+// 	if($('#fileNece').length > 0){
+// 		if('N'==$('#fileNece').val()){
+// 			fileNece = false;  
+// 		}
+//  	}
+ 
+// 	//엑셀 및 TXT 파일만 업로드 할수 있도록 체크하기
+// 	var fileNm = files[0].name;
+// 	fileExt = fileNm.split('.').pop().toLowerCase();
+
+// 	// IE11 대응
+// 	if (fileExt != "") { 
+// 		if($.inArray(fileExt, ['txt','xls','xlsx']) == -1) {
+// 			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
+// 			return;
+// 		}
 		
-		for (var i = 0; i < files.length; i++)
-		{
-		    var fd = new FormData();
-		    fd.append('file', files[i]);
-		    var tmpObj = new Object();
-		    tmpObj.name = "file_" + _fileIdx;
-		    tmpObj.fileObj = files[i];
+// 		for (var i = 0; i < files.length; i++)
+// 		{
+// 		    var fd = new FormData();
+// 		    fd.append('file', files[i]);
+// 		    var tmpObj = new Object();
+// 		    tmpObj.name = "file_" + _fileIdx;
+// 		    tmpObj.fileObj = files[i];
 		     
-		    _fileForm2.push(tmpObj);
-		    sendFileToServer(fd, obj, files[i], _fileIdx);
-		    _fileIdx++;
+// 		    _fileForm2.push(tmpObj);
+// 		    sendFileToServer(fd, obj, files[i], _fileIdx);
+// 		    _fileIdx++;
 		     
-		    var totalfileSize = 0;
-		    $('.totalfileCount').text($('.item_file_size').length) ;
-		    $('.item_file_size').each(function(){
-		    	totalfileSize += $(this).val()*1 ;
-		    });
-		    $('.totalfileSize').text(getStrFileSize(totalfileSize)) ; 
-		}
-	}
-}
+// 		    var totalfileSize = 0;
+// 		    $('.totalfileCount').text($('.item_file_size').length) ;
+// 		    $('.item_file_size').each(function(){
+// 		    	totalfileSize += $(this).val()*1 ;
+// 		    });
+// 		    $('.totalfileSize').text(getStrFileSize(totalfileSize)) ; 
+// 		}
+// 	}
+// }
 
 //드래그앤 드롭 엑셀 및 텍스트 파일 서버 전송 함수
-function sendFileToServer(formData, obj , fileObj, _fileIdx)
-{
-	var msg;
-	msg = "해당 첨부파일을  수정하시겠습니까?";
-	var data = new FormData(document.msgForm);
-	_fileForm2.forEach(function(obj, idx) {
-		if (obj) data.append("file0", obj.fileObj);
-	});
+// function sendFileToServer(formData, obj , fileObj, _fileIdx)
+// {
+// 	var msg;
+// 	msg = "해당 첨부파일을  수정하시겠습니까?";
+// 	var data = new FormData(document.msgForm);
+// 	_fileForm2.forEach(function(obj, idx) {
+// 		if (obj) data.append("file0", obj.fileObj);
+// 	});
 	
-	var url = "";
+// 	var url = "";
 	
-	// IE11 대응
-	if (fileExt != "") {
-		if(fileExt == "xls" || fileExt == "xlsx"){
-			url = "/web/mjon/addr/sendExelFilePhoneNumAjax.do";
-		}else if(fileExt == "txt"){
-			url = "/web/mjon/addr/sendTxtFilePhoneNumAjax.do";
-		}else{
-			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
-			return;
-		}
+// 	// IE11 대응
+// 	if (fileExt != "") {
+// 		if(fileExt == "xls" || fileExt == "xlsx"){
+// 			url = "/web/mjon/addr/sendExelFilePhoneNumAjax.do";
+// 		}else if(fileExt == "txt"){
+// 			url = "/web/mjon/addr/sendTxtFilePhoneNumAjax.do";
+// 		}else{
+// 			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
+// 			return;
+// 		}
 		
-		//엑셀 데이터 변수에 자료가 있으면 지워준다.
-	   	if(excelAddr.length > 0){
-	    	excelAddr = [];
-	    }
+// 		//엑셀 데이터 변수에 자료가 있으면 지워준다.
+// 	   	if(excelAddr.length > 0){
+// 	    	excelAddr = [];
+// 	    }
 		
-		$.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;
+// 		$.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 == "20000") {
-							alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
-						}
-						else {
-							if(data != null){
-								var arr = []; // 넘어온 데이터를 받은 배열 변수
-								$.each(data, function(i, item){
-									arr.push({name: item.name, phone: item.phone, info1: item.info1, info2: item.info2, info3: item.info3, info4: item.info4, memo: item.memo});
-								});
+// 						if (message == "20000") {
+// 							alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
+// 						}
+// 						else {
+// 							if(data != null){
+// 								var arr = []; // 넘어온 데이터를 받은 배열 변수
+// 								$.each(data, function(i, item){
+// 									arr.push({name: item.name, phone: item.phone, info1: item.info1, info2: item.info2, info3: item.info3, info4: item.info4, memo: item.memo});
+// 								});
 		
-								addPhoneInfo(arr); // 연락처를 처리해줄 함수 호출
-							}
+// 								addPhoneInfo(arr); // 연락처를 처리해줄 함수 호출
+// 							}
 							
-							//메세지가 있는 경우 알려주기
-							if(message != '' && message != null) {
-								alert(returnData.message);
-							}							
-						}
+// 							//메세지가 있는 경우 알려주기
+// 							if(message != '' && message != null) {
+// 								alert(returnData.message);
+// 							}							
+// 						}
 
-					}else{
-						alert(returnData.message);
-					}
-				} else if(status== 'fail'){
-					alert("저장에 실패하였습니다. !!");
-				}
-			},
-	      	error: function (e) { 
-	      		alert("저장에 실패하였습니다."); 
-	      		console.log("ERROR : ", e); 
-	      	},
-			beforeSend : function(xmlHttpRequest) {
-	        	//로딩창 show
-	        	$('.loading_layer').addClass('active');				
-			},	        	        
-	        complete : function(xhr, textStatus) {
-	        	//로딩창 hide
-	        	$('.loading_layer').removeClass('active');
-			}	      			
-	  	});
-	}
+// 					}else{
+// 						alert(returnData.message);
+// 					}
+// 				} else if(status== 'fail'){
+// 					alert("저장에 실패하였습니다. !!");
+// 				}
+// 			},
+// 	      	error: function (e) { 
+// 	      		alert("저장에 실패하였습니다."); 
+// 	      		console.log("ERROR : ", e); 
+// 	      	},
+// 			beforeSend : function(xmlHttpRequest) {
+// 	        	//로딩창 show
+// 	        	$('.loading_layer').addClass('active');				
+// 			},	        	        
+// 	        complete : function(xhr, textStatus) {
+// 	        	//로딩창 hide
+// 	        	$('.loading_layer').removeClass('active');
+// 			}	      			
+// 	  	});
+// 	}
 	
-}
+// }
 
 
 //#############################################################################################
@@ -949,7 +1116,8 @@
 			return false;			
 		}
 	}	
-	
+	console.log('selectedData : ', selectedData);
+	console.log('selectedData.length : ', selectedData.length);
 	var commaSelectedData = numberWithCommas(selectedData.length);
 	var confirmMsg = "저장하시겠습니까?\n이름 20byte, [*1*]~[*4*] 40byte, 메모 250byte 초과 글자는 절사됩니다.";
 	if (selectedData.length >= 10000) {
@@ -1217,100 +1385,105 @@
 });
 
 //seetJs 엑셀 파일 불러오기
-function excelExport(event){
-	var data = new FormData(document.excelForm);
-	data.append("file0", $('#excelFile').prop('files')[0]);
+// function excelExport(event){
+// 	var data = new FormData(document.excelForm);
+// 	data.append("file0", $('#excelFile').prop('files')[0]);
 	
-	var fileValue = $("#excelFile").val().split("\\");
-	var fileName = fileValue[fileValue.length-1];
+// 	var fileValue = $("#excelFile").val().split("\\");
+// 	var fileName = fileValue[fileValue.length-1];
 	
-	var fileExt = fileName.split('.').pop().toLowerCase();
+// 	var fileExt = fileName.split('.').pop().toLowerCase();
 
-	// IE11 대응
-	if (fileExt != "") {
-		if($.inArray(fileExt, ['txt','xls','xlsx']) == -1) {
-			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
-			return false;
-		}
+// 	// IE11 대응
+// 	if (fileExt != "") {
+// 		if($.inArray(fileExt, ['txt','xls','xlsx']) == -1) {
+// 			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
+// 			return false;
+// 		}
 		
-		var url = "";
+// 		var url = "";
 		
-		if(fileExt == "xls" || fileExt == "xlsx"){
-			url = "/web/mjon/addr/sendExelFilePhoneNumAjax.do";
-		}else if(fileExt == "txt"){
-			url = "/web/mjon/addr/sendTxtFilePhoneNumAjax.do";
-		}else{
-			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
-			return;
-		}
+// 		if(fileExt == "xls" || fileExt == "xlsx"){
+// 			url = "/web/mjon/addr/sendExelFilePhoneNumAjax.do";
+// 		}else if(fileExt == "txt"){
+// 			url = "/web/mjon/addr/sendTxtFilePhoneNumAjax.do";
+// 		}else{
+// 			alert('txt, xls, xlsx 파일만 업로드 할수 있습니다.');
+// 			return;
+// 		}
 		
-		//엑셀 데이터 변수에 자료가 있으면 지워준다.
-	   	if(excelAddr.length > 0){
-	    	excelAddr = [];
-	    }
+// 		//엑셀 데이터 변수에 자료가 있으면 지워준다.
+// 	   	if(excelAddr.length > 0){
+// 	    	excelAddr = [];
+// 	    }
 		
-		$.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;
+// 		$.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 == "20000") {
-							alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
-						}
-						else {						
-							if(data != null){
-								var arr = []; // 넘어온 데이터를 받은 배열 변수
-								$.each(data, function(i, item){
-									arr.push({name: item.name, phone: item.phone, info1: item.info1, info2: item.info2, info3: item.info3, info4: item.info4, memo: item.memo});
-								});
+// 						if (message == "20000") {
+// 							alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
+// 						}
+// 						else {						
+// 							if(data != null){
+// 								var arr = []; // 넘어온 데이터를 받은 배열 변수
+// // 								$.each(data, function(i, item){
+// // 									arr.push({name: item.name, phone: item.phone, info1: item.info1, info2: item.info2, info3: item.info3, info4: item.info4, memo: item.memo});
+// // 								});
+
+// 								data.forEach(item => {
+// 									arr.push(createDataObject(item));
+// 							    });
+// 								console.log('arr : ', arr);
 		
-								addPhoneInfo(arr); // 연락처를 처리해줄 함수 호출
+// 								addPhoneInfo(arr); // 연락처를 처리해줄 함수 호출
 								
-								//메세지가 있는 경우 알려주기
-								if(message != '' && message != null) {
-									alert(returnData.message);
-								}							
-							}
-						}
-					}else{
-						alert(returnData.message);
-					}
-				} else if(status== 'fail'){
-					alert("저장에 실패하였습니다. !!");
-				}
-			},
-	        error: function (e) {
-	        	alert("저장에 실패하였습니다."); 
-	        	console.log("ERROR : ", e); 
-	        }
-			,
-			beforeSend : function(xmlHttpRequest) {
-	        	//로딩창 show
-	        	$('.loading_layer').addClass('active');				
-			},	        	        
-	        complete : function(xhr, textStatus) {
-	        	//로딩창 hide
-	        	$('.loading_layer').removeClass('active');
-			}	      			
-	    });
+// 								//메세지가 있는 경우 알려주기
+// 								if(message != '' && message != null) {
+// 									alert(returnData.message);
+// 								}							
+// 							}
+// 						}
+// 					}else{
+// 						alert(returnData.message);
+// 					}
+// 				} else if(status== 'fail'){
+// 					alert("저장에 실패하였습니다. !!");
+// 				}
+// 			},
+// 	        error: function (e) {
+// 	        	alert("저장에 실패하였습니다."); 
+// 	        	console.log("ERROR : ", e); 
+// 	        }
+// 			,
+// 			beforeSend : function(xmlHttpRequest) {
+// 	        	//로딩창 show
+// 	        	$('.loading_layer').addClass('active');				
+// 			},	        	        
+// 	        complete : function(xhr, textStatus) {
+// 	        	//로딩창 hide
+// 	        	$('.loading_layer').removeClass('active');
+// 			}	      			
+// 	    });
 		
-		$("#excelFile").val("");
-	    $("#excelNm").val(fileName); 
-	}
+// 		$("#excelFile").val("");
+// 	    $("#excelNm").val(fileName); 
+// 	}
 	
-}
+// }
 
 //체크박스 전체선택/해제
 $(document).on("click", "#chkAll", function(e) {
@@ -1513,7 +1686,9 @@
 	                                    <label for="" class="label">그룹명 입력</label>
 	                                    <input type="text" id="addrGrpNm" name="addrGrpNm" placeholder="새 그룹명을 입력해주세요." onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명을 입력해주세요.'"class="inputLight" style="width: 300px;">
 	
-		                                <input type="file" id="excelFile" accept=".xls, .xlsx, .txt" onchange="excelExport(event); return false;" style="display:none"/>
+<!-- 		                                <input type="file" id="excelFile" accept=".xls, .xlsx, .txt" onchange="excelExport(event); return false;" style="display:none"/> -->
+		                                <input type="file" id="excelFile" accept=".xls, .xlsx, .txt" style="display:none"/>
+		                                  <button type="button" id="file-load-trigger">Choose File</button>
 		                                <button type="button" class="excel_btn2 btnType c3"><i class="uproad"></i>엑셀, TXT파일 업로드</button>
 		                            </td>
 		                        </tr>
@@ -1533,6 +1708,108 @@
 						</p>
 						<button type="button" class="btnType btnType6 addCallToF">번호추가</button>
 					</div>
+					
+					
+					
+
+                    <div class="adr_excel" style="margin-top: 13px;">
+                        <!-- thead -->
+                        <div class="adr_hd select_adr_hd">
+                            <div></div>
+                            <div style="width: 125px;">
+                            	<label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="name">이름</option>
+									<option value="phone">휴대폰</option>
+									<option value="info1">[*1*]</option>
+									<option value="info2">[*2*]</option>
+									<option value="info3">[*3*]</option>
+									<option value="info4">[*4*]</option>
+									<option value="memo">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="name">이름</option>
+									<option value="phone">휴대폰</option>
+									<option value="info1">[*1*]</option>
+									<option value="info2">[*2*]</option>
+									<option value="info3">[*3*]</option>
+									<option value="info4">[*4*]</option>
+									<option value="memo">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="name">이름</option>
+									<option value="phone">휴대폰</option>
+									<option value="info1">[*1*]</option>
+									<option value="info2">[*2*]</option>
+									<option value="info3">[*3*]</option>
+									<option value="info4">[*4*]</option>
+									<option value="memo">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="name">이름</option>
+									<option value="phone">휴대폰</option>
+									<option value="info1">[*1*]</option>
+									<option value="info2">[*2*]</option>
+									<option value="info3">[*3*]</option>
+									<option value="info4">[*4*]</option>
+									<option value="memo">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="name">이름</option>
+									<option value="phone">휴대폰</option>
+									<option value="info1">[*1*]</option>
+									<option value="info2">[*2*]</option>
+									<option value="info3">[*3*]</option>
+									<option value="info4">[*4*]</option>
+									<option value="memo">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="name">이름</option>
+									<option value="phone">휴대폰</option>
+									<option value="info1">[*1*]</option>
+									<option value="info2">[*2*]</option>
+									<option value="info3">[*3*]</option>
+									<option value="info4">[*4*]</option>
+									<option value="memo">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="name">이름</option>
+									<option value="phone">휴대폰</option>
+									<option value="info1">[*1*]</option>
+									<option value="info2">[*2*]</option>
+									<option value="info3">[*3*]</option>
+									<option value="info4">[*4*]</option>
+									<option value="memo">메모</option>
+								</select>
+                            </div>
+                        </div>
+                     </div>					
+					
 					<div class="drag_drop_wrap callList_box">
 						<img src="/publish/images/content/excel.jpg" style="width: 100%;">
 					</div>
 
src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforClipboard.jsp (added)
+++ src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforClipboard.jsp
@@ -0,0 +1,668 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+
+<script type="text/javascript" src="<c:url value='/publish/js/content.js'/>"></script>
+
+<script type="text/javascript">
+$(document).ready(function(){
+	
+	// 중복 휴대폰번호 버튼 노출여부
+// 	$("#btnAddrMassDupli").hide();
+// 	$("#btnAddrMassSaveDupli").hide();
+}); 
+
+
+
+
+function addrGroupLoadAjax(){
+	$("#addrRegistSelect").load("/web/addr/selectAddrGroupAjax.do", function(response, status, xhr){});
+	$("#funcAddrGroupSelect").load("/web/addr/selectAddrGroupAjax.do", function(response, status, xhr){});
+}
+
+
+function insertAddrGroupAjax() {
+	var form = document.addrGrpInsertForm;
+	if(form.addrGrpNm.value == "") {
+		alert("주소록 그룹명을 입력해주세요.");
+		return;
+	}
+	if(!confirm("주소록 그룹을 추가하시겠습니까?")) {
+		return;
+	}
+	var data = new FormData(form);
+	
+	$.ajax({
+		cache : false,
+		url : "<c:url value='/web/addr/insertAddrGroupAjax.do' />", 
+		type : 'POST', 
+		data : data,
+		dataType:'json',
+		processData: false,
+		contentType: false,
+		success : function(returnData, status){
+			if(status == "success") {
+				if("fail"==returnData.result){
+					alert(returnData.message);
+					return;
+				} else if("dupl"==returnData.result) {
+					alert("중복된 그룹명입니다.");
+					return;
+				}
+				alert("등록되었습니다.");
+				listAddrGrp();
+				addrGroupLoadAjax();
+				
+			}else{ alert("ERROR!");return;} 
+		},
+		error: function (e) { alert("저장에 실패하였습니다."); console.log("ERROR : ", e); }
+	});
+	
+}
+
+function insertAddrAjax() {
+	var selectVal = $("#addrRegistSelect option:selected").val();
+	//alert(selectVal);
+	
+	var form = document.addrInsertForm;
+	/*
+	//필수값 아니어서 뺐음
+	if(form.addrNm.value == "") {
+		alert("주소록 이름을 입력하세요");
+		return;
+	}
+	*/
+	if(form.addrPhoneNo.value == "") {
+		alert("주소록 번호를 입력하세요");
+		return;
+	}
+	//if(!confirm("주소록을 추가하시겠습니까?")) {
+	//	return;
+	//}
+	
+	if(!checkHpNum(form.addrPhoneNo.value)){//휴대폰 유효성 검사
+		if(!checkNorPhoneNum(form.addrPhoneNo.value)){//일반전화 유효성 검사
+			
+			alert("잘못된 휴대폰번호 또는 일반전화 번호 입니다.");
+			return false;
+			
+		}
+		
+	}
+	
+	var data = new FormData(form);
+
+	$.ajax({
+		cache : false,
+		url : "<c:url value='/web/mjon/addr/insertAddrAjax.do' />", 
+		type : 'POST', 
+		data : data,
+		dataType:'json',
+		processData: false,
+		contentType: false,
+		success : function(returnData, status){
+			if(status == "success") {
+				if("fail"==returnData.result){
+					alert(returnData.message);
+					return;
+				} else if("dupl"==returnData.result){
+					alert("해당 그룹에 중복된 번호가 있습니다.");
+					return;
+				}
+				//alert("저장 되었습니다.");
+				
+				listAddrGrp();
+				addrGroupLoadAjax();
+				addrLoadAjax();
+				
+				// 주소록그룹 콤보박스 유지
+				setTimeout(setSelectSetting, 500, selectVal);			
+				
+			}else{ alert("ERROR!");return;} 
+		},
+		error: function (e) { alert("저장에 실패하였습니다."); console.log("ERROR : ", e); }
+	});
+	
+}
+
+// 주소록그룹 콤보박스 유지
+function setSelectSetting(selectVal) {
+	$("#addrRegistSelect").val(selectVal).prop("selected", true);	
+}
+	
+function linkPage(pageNo){
+	if ($('#searchKeywordAddr').val() != "" && $('#searchKeywordAddr').val() != null && $('#searchKeywordAddr').val() != undefined) {
+		// 문자전송 검색용
+		$("#msgStartKeyword").val("");
+	}
+
+	var searchForm = document.searchAddrForm;
+	searchForm.pageIndex.value = pageNo;
+	searchForm.pageUnit.value = $('#pageUnit').val();
+	searchForm.searchCondition.value = $('#searchConditionAddr').val();
+	searchForm.searchKeyword.value = $('#searchKeywordAddr').val();
+	searchForm.startKeyword.value = $("#msgStartKeyword").val();
+	
+	var sendData = $(document.searchAddrForm).serializeArray();
+	$("#adr1_right").load("/web/mjon/addr/selectAddrAjax.do", sendData, function(response, status, xhr){tableAllChk();});
+	addrGroupLoadAjax();
+}
+
+
+
+//#############################################################################################
+//Tabulator
+//#############################################################################################
+
+$(document).ready(function(){
+	//Tabulator AJAX Data Loading
+
+    // 파일 선택 버튼 클릭 이벤트
+    $("#file-load-trigger").on("click", function() {
+        $("#excelFile").click();
+    });
+
+    // 파일 입력 이벤트
+    $("#excelFile").on("change", function(event) {
+    	excelFileChange(event.target.files[0]);
+    });
+    
+
+
+	//받는사람 전체삭제 버튼 처리
+	$('.all_del').click(function(){
+		var data = $tableClip.getRows();	
+		if(data == null || data == ""){
+			alert("받는사람을 추가해 주세요.");
+			return false;
+		}else{
+			$tableClip.clearData();
+			$("#rowTotCnt").text(0); //총건수 수정
+			$("#rowDupCnt").text(0); //중복건수 수정
+			dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
+		}
+		
+	});
+
+
+	// 받는사람 선택삭제 버튼 처리해주기
+	$('.select_del').click(function(){
+		$("#rowDupCnt").text(0); //중복건수 수정
+		dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
+		
+		if($tableClip == null || $tableClip == ""){
+			alert("받는사람을 추가해 주세요.");
+			return false;
+		}
+		
+		var selectedData = $tableClip.getSelectedRows();
+		
+		if(selectedData == "" || selectedData == null){
+			alert("받는 사람을 선택해 주세요.");
+			return false;
+		}else{ // 선택한 Row 데이터 삭제하기
+			for(var i=0; i < selectedData.length; i++){
+				selectedData[i].delete();
+			}
+		}
+		
+		totRows = $tableClip.getRows().length;
+	    
+		updateTotCnt(totRows);
+	});
+
+	//받는사람 오류번호 삭제 처리해주기
+	$('.chkVali_del').click(function(){
+		//기존 연락처 모두 불러오기
+	    var data = $tableClip.getRows();
+	    var tableData = [];
+	    var totLen = $tableClip.getRows().length;
+	    var errCnt = 0;
+	    
+	    if(totLen > 0){
+	    	if(confirm("올바르지 않은 연락처 정보를 삭제 하시겠습니까?")){
+	    		for(var i=0; i < totLen; i++){
+
+	    			
+	            	var phone = data[i].getData().phone;
+	            	var valiCheck = checkHpNum(phone);
+	            	if(valiCheck){
+	            		tableData.push({name: data[i].getData().name.trim(), phone: data[i].getData().phone.trim(), info1:data[i].getData().info1, info2:data[i].getData().info2, info3:data[i].getData().info3, info4:data[i].getData().info4, memo:data[i].getData().memo});
+	            	}else{
+	            		errCnt++;
+	            	}
+	            }
+	            
+	            var removeDuplData = dupliPhoneData(tableData);
+	        	
+	            $tableClip.setData(removeDuplData);
+	            
+	            //총 받는사람 수 계산
+	            totRows = $tableClip.getRows().length;
+	            updateTotCnt(totRows);
+	            
+	          	if(errCnt > 0){
+	          		alert(errCnt + " 건의 연락처를 삭제하였습니다.");
+	          		return false;
+	          	}else{
+	          		alert("오류가 있는 연락처가 없습니다.");
+	          	}
+	    	}
+	    }else{
+	    	alert("연락처 정보를 입력해 주세요.");
+	    	return false;
+	    }
+	});
+	
+
+
+    
+    
+	// 오류검사 항목 중복제거
+	function SetTableErrorDupliCheck(sVal) {
+		var isDuplicate = false;
+		if (tableErrorCheckData.length == 0) {
+			tableErrorCheckData.push(sVal);
+		}
+		else {
+			for (var i = 0; i < tableErrorCheckData.length; i++)
+			{
+				if (tableErrorCheckData[i] == sVal) {
+					isDuplicate = true;
+				}
+			}
+			
+			if (isDuplicate) {
+				return;
+			}
+			else {
+				tableErrorCheckData.push(sVal);
+			}
+		}
+	}	
+	
+	
+	// 오류검사 항목 중복제거
+	function SetTableErrorDupliCheck(sVal) {
+		var isDuplicate = false;
+		if (tableErrorCheckData.length == 0) {
+			tableErrorCheckData.push(sVal);
+		}
+		else {
+			for (var i = 0; i < tableErrorCheckData.length; i++)
+			{
+				if (tableErrorCheckData[i] == sVal) {
+					isDuplicate = true;
+				}
+			}
+			
+			if (isDuplicate) {
+				return;
+			}
+			else {
+				tableErrorCheckData.push(sVal);
+			}
+		}
+	}	
+	
+	$('.check_validity').click(function(){
+		tableErrorCheckData.length = 0;	// 오류 번호 배열 초기화
+		
+		var data = $tableClip.getRows();
+		var invalid = $tableClip.getInvalidCells();		//오류 데이터 체크
+		var dataLen = $tableClip.getRows().length;		//연락처 데이터 갯수
+		var totLen = invalid.length;				//오류 데이터 갯수
+		var errMsg = "";							//최종 alert에 표시할 메시지 저장 변수
+		
+		if(dataLen > 0) { //연락처 정보가 있으면 수행
+			if(totLen > 0) { //내용에 오류가 있으면 수행
+				//오류 데이터 값 저장
+				for(var i=0; i < totLen; i++) {
+					var cellValue = invalid[i].getValue();
+					SetTableErrorDupliCheck(cellValue);
+				}
+				
+				for(var i=0; i < dataLen; i++){
+					// 휴대폰번호 체크
+		        	var phone = data[i].getData().phone;
+		        	var valiCheck = checkHpNum(phone);
+		        	if(!valiCheck){
+		        		SetTableErrorDupliCheck(phone);
+		        	}
+				}
+			}
+			else {
+				for(var i=0; i < dataLen; i++){
+					// 휴대폰번호 체크
+		        	var phone = data[i].getData().phone;
+		        	var valiCheck = checkHpNum(phone);
+		        	if(!valiCheck){
+		        		SetTableErrorDupliCheck(phone);
+		        	}
+				}				
+			}
+		}
+		else {
+			alert("연락처를 입력해 주세요.");
+			return false;
+		}
+		
+		if (tableErrorCheckData.length > 0) {
+			for (var i = 0; i < tableErrorCheckData.length; i++)
+			{
+				errMsg += tableErrorCheckData[i];
+				if ((tableErrorCheckData.length - 1) > i) {
+					errMsg += ", ";
+				}
+			}			
+    		alert(errMsg + "의 내용에 오류가 있습니다.");			
+		}
+		else {
+			alert("오류 데이터가 없습니다.");			
+		}
+		
+		return false;		
+	});
+	
+
+
+	//받는사람 중복 삭제
+	$('.duple_del').click(function(){
+		//기존 연락처 모두 불러오기
+	    var data = $tableClip.getRows();
+	    var tableData = [];
+	    var dpCnt = 0;
+	    var totLen = $tableClip.getRows().length;
+	    
+	    for(var i=0; i < totLen; i++){
+	    	tableData.push({name: data[i].getData().name.trim(), phone: data[i].getData().phone.trim()});
+	    }
+	    
+	    var removeDuplData = dupliPhoneData(tableData);
+	    $tableClip.setData(removeDuplData);
+	    
+	    //총 받는사람 수 계산
+	    totRows = $tableClip.getRows().length;
+	    updateTotCnt(totRows);
+	});	
+	
+	
+});
+
+
+// Show Html
+function getAddrGroupListShow(jsonList) {
+	var sHtml = "";
+	sHtml += "<option value='NEW'>그룹추가</option>";
+	sHtml += "<option value='0'>그룹미지정</option>";
+	sHtml += "<option value='bookmark'>자주보내는 번호</option>";
+	for (var j = 0; j < jsonList.length; j++) {
+		sHtml += "	<option value='" + $.trim(jsonList[j].addrGrpId) + "' />" + $.trim(jsonList[j].addrGrpNm) + "</option>";
+	}
+	    	
+	$("#addrGrpIdInfo").html(sHtml);
+}
+
+$(document).on('change', '#addrGrpIdInfo', function() {
+	if ($("#addrGrpIdInfo option:selected").val() != "NEW") {
+		$("#addrGrpNm").val(""); //	새그룹명 Clear;
+	}
+});
+
+//#############################################################################################
+//파일 불러오기
+//#############################################################################################
+
+
+//체크박스 전체선택/해제
+$(document).on("click", "#chkAll", function(e) {
+    var isChecked = $(this).is(":checked");
+    $("input[name=addrCheck]:checkbox").prop("checked", isChecked);
+});
+
+$(document).on("click", "#duplicationChkAll", function(e) {
+    var isChecked = $(this).is(":checked");
+    $("input[name=addrCheck]:checkbox").prop("checked", isChecked);
+});	
+
+
+
+// 중복 연락처
+function GetAddrMassDupli() {
+	var sHtml = "";
+	sHtml += "<div class='' style='overflow-x:auto; height:350px;'>";
+	sHtml += "<table class='tType4'>";
+	sHtml += "		<colgroup>";
+	sHtml += "			<col style='width:auto' />";
+	sHtml += "		</colgroup>";
+	sHtml += "		<thead>";
+	sHtml += "			<tr>";
+	sHtml += "				<th>중복 휴대폰번호 (" + numberWithCommas(dupliPhoneDataRealList.length) + "개)</th>";
+	sHtml += "			</tr>";
+	sHtml += "		</thead>";
+	sHtml += "		<tbody>";
+	for (var i = 0; i < dupliPhoneDataRealList.length; i++) {
+		sHtml += "		<tr>";
+		sHtml += "			<td>" + dupliPhoneDataRealList[i] + "</td>";
+		sHtml += "		</tr>";
+	}
+	sHtml += "		</tbody>";
+	sHtml += "	</table>";
+	sHtml += "	</div>";
+	
+	$("#addrMassDupli_layer").html(sHtml);
+}
+
+//중복 연락처 => 저장시
+function GetAddrMassSaveDupli() {
+	var sHtml = "";
+	sHtml += "<div class='' style='overflow-x:auto; height:350px;'>";
+	sHtml += "<table class='tType4'>";
+	sHtml += "		<colgroup>";
+	sHtml += "			<col style='width:auto' />";
+	sHtml += "		</colgroup>";
+	sHtml += "		<thead>";
+	sHtml += "			<tr>";
+// 	sHtml += "				<th>중복 휴대폰번호 (" + numberWithCommas(addrMassDupliSaveList.length) + "개)</th>";
+	sHtml += "				<th>중복 휴대폰번호 (10개)</th>";
+	sHtml += "			</tr>";
+	sHtml += "		</thead>";
+	sHtml += "		<tbody>";
+	for (var i = 0; i < addrMassDupliSaveList.length; i++) {
+		sHtml += "		<tr>";
+		sHtml += "			<td>" + addrMassDupliSaveList[i].addrPhoneNo + "</td>";
+		sHtml += "		</tr>";
+	}
+	sHtml += "		</tbody>";
+	sHtml += "	</table>";
+	sHtml += "	</div>";
+	
+	$("#addrMassSaveDupli_layer").html(sHtml);
+}
+
+</script>
+	             
+	                <!-- 붙여넣기 -->
+	                <div class="popCont pop_more_cont" id="popCont_2">
+	                    <div class="titBox">
+	                        <p>- 텍스트(txt) 파일로 작성된 주소록을 등록하실 수 있습니다.</p>
+	                        <p>- 반드시 샘플파일을 다운로드하여 작성방법을 확인하신 후 정해진 양식에 맞추어 주소록을 붙여 넣으셔야 합니다.</p>
+	                        <p>- 입력 내용은 (Tab) 또는 (,) 구분하여 입력하여야 합니다.</p>
+	                        <p>- 한 줄(열)에 주소 한 건만 입력 가능합니다.</p>
+	                        <p>- 전화번호 형태는 010-1234-5678 또는 01012345678 모두 가능합니다. 단, 공백은 허용되지 않습니다.</p>
+	                        <p>&nbsp;&nbsp;(예) 홍길동,010-1234-5678 또는 홍길동,01012345678</p>
+	                        <p>- 한번에 많은 양의 데이터를 입력하시려면 ‘주소록 복사(Ctrl+c) + 붙여넣기(Ctrl+v)’ 또는 ‘엑셀입력’을 이용하세요.</p>
+	                        <p>- 주소록 등록이 어려우신 경우에는 주소록 입력대행 메뉴를 이용하시면 됩니다.</p>
+	                        <button type="button" class="txt_btn" onclick="location.href='/download/addr/주소록_대량등록.zip'"><i></i>TXT샘플 다운로드</button>                        
+	                    </div>
+	                    <div class="pop_more_wrap">
+	                   		<button type="button" class="pop_more" onclick="popMore(this);">더보기<i></i></button>
+	                   </div>
+	                </div><!--// 붙여넣기 -->                
+	
+					<!-- 공통 -->
+					<div>
+		                <table class="layer_tType1">
+		                    <caption>엑셀입력 표</caption>
+		                    <colgroup>
+		                        <col style="width: 95px">
+		                        <col style="width: auto">
+		                    </colgroup>
+		                    <tbody>
+		                        <tr>
+		                            <th>그룹 선택</th>
+		                            <td>
+		                                <label for="" class="label">그룹 선택</label>
+		                                <select id="addrGrpIdInfo" name="addrGrpIdInfo">
+		                                </select>
+	                                    <label for="" class="label">그룹명 입력</label>
+	                                    <input type="text" id="addrGrpNm" name="addrGrpNm" placeholder="새 그룹명을 입력해주세요." onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명을 입력해주세요.'"class="inputLight" style="width: 300px;">
+	
+		                            </td>
+		                        </tr>
+		                    </tbody>
+		                </table>
+	                </div>
+					<div class="excel_middle2">
+						<p>
+							총 <span class="c_e40000 fwBold" id="rowTotCnt">0</span>건 / 중복 <span class="c_002c9a fwBold" id="rowDupCnt">0</span>건
+<!-- 							&nbsp;  -->
+<!-- 							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" onclick="GetAddrMassDupli()" id="btnAddrMassDupli">중복번호</button> -->
+<!-- 							&nbsp; -->
+<!-- 							<button type="button" class="btnType btnType6" data-tooltip="addrMassSaveDupli_layer" onclick="GetAddrMassSaveDupli()" id="btnAddrMassSaveDupli">중복번호</button> -->
+						</p>
+<!-- 						<button type="button" class="btnType btnType6 addCallToF">번호추가</button> -->
+					</div>
+					
+					
+					
+
+                    <div class="adr_excel" style="margin-top: 13px;">
+                        <!-- thead -->
+                        <div class="adr_hd select_adr_hd" data-group="tableClip">
+                            <div></div>
+                            <div style="width: 125px;">
+                            	<label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                        </div>
+                     </div>					
+					
+					<div class="drag_drop_wrap callList_box" id="tabulator_clip">
+						<img src="/publish/images/content/excel.jpg" style="width: 100%;">
+					</div>
+					<div class="excel_middle">
+						<div class="select_btnWrap clearfix">
+							<div>
+								<button type="button" class="all_del"><i class="remove_img"></i>전체삭제</button>
+								<button type="button" class="select_del"><i class="remove_img"></i>선택삭제</button>
+								<button type="button" class="chkVali_del"><i class="remove_img"></i>오류번호삭제</button>
+								<button type="button" class="check_validity">오류 검사 <i></i></button>
+								<div class="error_hover_cont send_hover_cont addr_hover_cont">
+									<p>휴대폰 번호 입력 시 해당 휴대폰 번호에 대한 형식이 어긋나거나 휴대폰 번호에 오류가 있는지 등을 검사하는 기능</p>
+									<span>(예시) 010-1234-0001(O) / 010-123-0001(X)</span>
+								</div>
+							</div>
+	
+						</div>
+					</div><!--// 공통 -->     
+	
+					<!-- 붙여놓기 설명 -->
+	                <div class="req_area">
+	                  	<div class="text_box">
+	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br>
+							- 휴대폰 번호는 필수입력 항목입니다.<br>
+							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br>
+							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br>
+							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.
+						</div>
+	                </div>
 
src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforExcel.jsp (added)
+++ src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforExcel.jsp
@@ -0,0 +1,955 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+
+<script type="text/javascript" src="<c:url value='/publish/js/content.js'/>"></script>
+
+<script type="text/javascript">
+
+$(document).ready(function(){
+	
+	// 중복 휴대폰번호 버튼 노출여부
+// 	$("#btnAddrMassDupli").hide();
+// 	$("#btnAddrMassSaveDupli").hide();
+}); 
+
+
+function addrGroupLoadAjax(){
+	$("#addrRegistSelect").load("/web/addr/selectAddrGroupAjax.do", function(response, status, xhr){});
+	$("#funcAddrGroupSelect").load("/web/addr/selectAddrGroupAjax.do", function(response, status, xhr){});
+}
+
+
+function insertAddrGroupAjax() {
+	var form = document.addrGrpInsertForm;
+	if(form.addrGrpNm.value == "") {
+		alert("주소록 그룹명을 입력해주세요.");
+		return;
+	}
+	if(!confirm("주소록 그룹을 추가하시겠습니까?")) {
+		return;
+	}
+	var data = new FormData(form);
+	
+	$.ajax({
+		cache : false,
+		url : "<c:url value='/web/addr/insertAddrGroupAjax.do' />", 
+		type : 'POST', 
+		data : data,
+		dataType:'json',
+		processData: false,
+		contentType: false,
+		success : function(returnData, status){
+			if(status == "success") {
+				if("fail"==returnData.result){
+					alert(returnData.message);
+					return;
+				} else if("dupl"==returnData.result) {
+					alert("중복된 그룹명입니다.");
+					return;
+				}
+				alert("등록되었습니다.");
+				listAddrGrp();
+				addrGroupLoadAjax();
+				
+			}else{ alert("ERROR!");return;} 
+		},
+		error: function (e) { alert("저장에 실패하였습니다."); console.log("ERROR : ", e); }
+	});
+	
+}
+
+function insertAddrAjax() {
+	var selectVal = $("#addrRegistSelect option:selected").val();
+	//alert(selectVal);
+	
+	var form = document.addrInsertForm;
+	/*
+	//필수값 아니어서 뺐음
+	if(form.addrNm.value == "") {
+		alert("주소록 이름을 입력하세요");
+		return;
+	}
+	*/
+	if(form.addrPhoneNo.value == "") {
+		alert("주소록 번호를 입력하세요");
+		return;
+	}
+	//if(!confirm("주소록을 추가하시겠습니까?")) {
+	//	return;
+	//}
+	
+	if(!checkHpNum(form.addrPhoneNo.value)){//휴대폰 유효성 검사
+		if(!checkNorPhoneNum(form.addrPhoneNo.value)){//일반전화 유효성 검사
+			
+			alert("잘못된 휴대폰번호 또는 일반전화 번호 입니다.");
+			return false;
+			
+		}
+		
+	}
+	
+	var data = new FormData(form);
+
+	$.ajax({
+		cache : false,
+		url : "<c:url value='/web/mjon/addr/insertAddrAjax.do' />", 
+		type : 'POST', 
+		data : data,
+		dataType:'json',
+		processData: false,
+		contentType: false,
+		success : function(returnData, status){
+			if(status == "success") {
+				if("fail"==returnData.result){
+					alert(returnData.message);
+					return;
+				} else if("dupl"==returnData.result){
+					alert("해당 그룹에 중복된 번호가 있습니다.");
+					return;
+				}
+				//alert("저장 되었습니다.");
+				
+				listAddrGrp();
+				addrGroupLoadAjax();
+				addrLoadAjax();
+				
+				// 주소록그룹 콤보박스 유지
+				setTimeout(setSelectSetting, 500, selectVal);			
+				
+			}else{ alert("ERROR!");return;} 
+		},
+		error: function (e) { alert("저장에 실패하였습니다."); console.log("ERROR : ", e); }
+	});
+	
+}
+
+// 주소록그룹 콤보박스 유지
+function setSelectSetting(selectVal) {
+	$("#addrRegistSelect").val(selectVal).prop("selected", true);	
+}
+	
+
+
+
+//#############################################################################################
+//Tabulator
+//#############################################################################################
+
+$(document).ready(function(){
+    // 파일 선택 버튼 클릭 이벤트
+    $("#file-load-trigger").on("click", function() {
+        $("#excelFile").click();
+    });
+
+    // 파일 입력 이벤트
+    $("#excelFile").on("change", function(event) {
+    	excelFileChange(event.target.files[0]);
+    });
+    
+
+	
+	//받는 사람 리스트 영역에 클립보드 데이터 가져와보기 
+	// 붙여넣기 기능
+	/* $('.callList_box').on('paste', function (e) {
+		var element = e.originalEvent.clipboardData.getData('text'); // 클립보드에 복사한 데이터 가져오기
+		var elmSplit= [];
+		elmSplit = element.split("\n");
+		var elmLen = elmSplit.length;
+		console.log('elmSplit : ', elmSplit);
+		if(elmLen < 0){
+			alert("붙여넣을 연락처를 복사해주세요.");
+			return false;
+		}
+		if (elmLen > 20001) {
+			alert("2만줄 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.");
+			return false;
+		}			
+		
+		tableErrorData.length = 0;	// 오류 번호 배열 초기화
+
+		var splitData = [];
+		var realPhone = [];
+		
+		for(var i=0; i < elmLen; i++){
+			var splitStr = elmSplit[i];
+			var tabData = splitStr.split("\t"); //탭 구분으로 데이터 분할
+			var comData = splitStr.split(","); //콤마 구분으로 데이터 분할
+			if(tabData.length >= 2){
+				splitData = tabData;
+			}else{
+				splitData = comData;
+			}
+				
+			if(splitData.length == 0){// 데이터가 없는경우
+				alert("탭으로 구분하여 데이터를 복사해 주세요.");
+			  	return false;
+			}
+			
+			
+			if(splitData.length == 1){
+				realPhone.push({A: splitData[0].trim()});
+			}else{
+				
+				let keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
+				let data = {};
+
+				splitData.forEach((item, index) => {
+				    data[keys[index]] = item.trim();
+				});
+
+				realPhone.push(data);
+			}//else end
+		}
+		console.log('realPhone : ', realPhone);
+		var recTableData = $tableExcel.getRows();		 // 받는사람 리스트의 전체 목록을 저장
+		var tableData = [];
+		
+		//기존 받는사람 리스트를 배열에 미리 담아둔다.
+		if (recTableData.length > 0) {
+		    recTableData.forEach(item => {
+		        tableData.push(createDataObject(item.getData()));
+		    });
+		}
+			
+		if (realPhone.length > 0) {
+		    realPhone.forEach(item => {
+		        tableData.push(createDataObject(item));
+		    });
+		}
+			
+		//tableData.push(realPhone);
+			
+		//중복 연락처 1개만 남기고 삭제하기
+		// 20240719 개선작업은 폰위치가 따로없어 중복제거를 못함
+// 			var removeDuplPhone = dupliPhoneData(tableData);
+		var removeDuplPhone = tableData;
+		  
+		//수신자 리스트에 전화번호 추가해주기
+		//$tableExcel.addData(removeDuplPhone);
+		$tableExcel.setData(removeDuplPhone);
+		
+		totRows = $tableExcel.getRows().length; 
+		updateTotCnt(totRows); //전체 데이터 갯수 구하기
+		
+		if (tableErrorData.length > 0) {
+			alert("데이터를 확인해 주세요.");
+			// 	alert("올바르지 않은 휴대폰 번호가 "+ tableErrorData.length +" 건 있습니다.");
+			//for(var x=0; x < tableErrorData.length; x++){
+			//	alert(tableErrorData[x]);
+			//}
+		}
+	});
+ */
+	
+	//$tableExcel.setData(tabledata);
+	
+	
+
+
+	//받는사람 전체삭제 버튼 처리
+	$('.all_del').click(function(){
+		var data = $tableExcel.getRows();	
+		if(data == null || data == ""){
+			alert("받는사람을 추가해 주세요.");
+			return false;
+		}else{
+			$tableExcel.clearData();
+			$("#rowTotCnt").text(0); //총건수 수정
+			$("#rowDupCnt").text(0); //중복건수 수정
+			dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
+		}
+		
+	});
+
+
+	// 받는사람 선택삭제 버튼 처리해주기
+	$('.select_del').click(function(){
+		$("#rowDupCnt").text(0); //중복건수 수정
+		dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
+		
+		if($tableExcel == null || $tableExcel == ""){
+			alert("받는사람을 추가해 주세요.");
+			return false;
+		}
+		
+		var selectedData = $tableExcel.getSelectedRows();
+		
+		if(selectedData == "" || selectedData == null){
+			alert("받는 사람을 선택해 주세요.");
+			return false;
+		}else{ // 선택한 Row 데이터 삭제하기
+			for(var i=0; i < selectedData.length; i++){
+				selectedData[i].delete();
+			}
+		}
+		
+		totRows = $tableExcel.getRows().length;
+	    
+		updateTotCnt(totRows);
+	});
+
+	//받는사람 오류번호 삭제 처리해주기
+	$('.chkVali_del').click(function(){
+		//기존 연락처 모두 불러오기
+	    var data = $tableExcel.getRows();
+	    var tableData = [];
+	    var totLen = $tableExcel.getRows().length;
+	    var errCnt = 0;
+	    
+	    if(totLen > 0){
+	    	if(confirm("올바르지 않은 연락처 정보를 삭제 하시겠습니까?")){
+	    		for(var i=0; i < totLen; i++){
+
+	    			
+	            	var phone = data[i].getData().phone;
+	            	var valiCheck = checkHpNum(phone);
+	            	if(valiCheck){
+	            		tableData.push({name: data[i].getData().name.trim(), phone: data[i].getData().phone.trim(), info1:data[i].getData().info1, info2:data[i].getData().info2, info3:data[i].getData().info3, info4:data[i].getData().info4, memo:data[i].getData().memo});
+	            	}else{
+	            		errCnt++;
+	            	}
+	            }
+	            
+	            var removeDuplData = dupliPhoneData(tableData);
+	        	
+	            $tableExcel.setData(removeDuplData);
+	            
+	            //총 받는사람 수 계산
+	            totRows = $tableExcel.getRows().length;
+	            updateTotCnt(totRows);
+	            
+	          	if(errCnt > 0){
+	          		alert(errCnt + " 건의 연락처를 삭제하였습니다.");
+	          		return false;
+	          	}else{
+	          		alert("오류가 있는 연락처가 없습니다.");
+	          	}
+	    	}
+	    }else{
+	    	alert("연락처 정보를 입력해 주세요.");
+	    	return false;
+	    }
+	});
+	
+
+    // 필드 선택 이벤트 핸들러
+    $("#column-selector").on("change", function() {
+        let selectedField = $(this).val();
+        let newValue = prompt("새 값을 입력하세요:");
+        if (newValue !== null) {
+            updateTableField(selectedField, newValue);
+        }
+    });
+
+
+
+
+    
+    
+    
+	// 오류검사 항목 중복제거
+	function SetTableErrorDupliCheck(sVal) {
+		var isDuplicate = false;
+		if (tableErrorCheckData.length == 0) {
+			tableErrorCheckData.push(sVal);
+		}
+		else {
+			for (var i = 0; i < tableErrorCheckData.length; i++)
+			{
+				if (tableErrorCheckData[i] == sVal) {
+					isDuplicate = true;
+				}
+			}
+			
+			if (isDuplicate) {
+				return;
+			}
+			else {
+				tableErrorCheckData.push(sVal);
+			}
+		}
+	}	
+	
+	
+	// 오류검사 항목 중복제거
+	function SetTableErrorDupliCheck(sVal) {
+		var isDuplicate = false;
+		if (tableErrorCheckData.length == 0) {
+			tableErrorCheckData.push(sVal);
+		}
+		else {
+			for (var i = 0; i < tableErrorCheckData.length; i++)
+			{
+				if (tableErrorCheckData[i] == sVal) {
+					isDuplicate = true;
+				}
+			}
+			
+			if (isDuplicate) {
+				return;
+			}
+			else {
+				tableErrorCheckData.push(sVal);
+			}
+		}
+	}	
+	
+	$('.check_validity').click(function(){
+		tableErrorCheckData.length = 0;	// 오류 번호 배열 초기화
+		
+		var data = $tableExcel.getRows();
+		var invalid = $tableExcel.getInvalidCells();		//오류 데이터 체크
+		var dataLen = $tableExcel.getRows().length;		//연락처 데이터 갯수
+		var totLen = invalid.length;				//오류 데이터 갯수
+		var errMsg = "";							//최종 alert에 표시할 메시지 저장 변수
+		
+		if(dataLen > 0) { //연락처 정보가 있으면 수행
+			if(totLen > 0) { //내용에 오류가 있으면 수행
+				//오류 데이터 값 저장
+				for(var i=0; i < totLen; i++) {
+					var cellValue = invalid[i].getValue();
+					SetTableErrorDupliCheck(cellValue);
+				}
+				
+				for(var i=0; i < dataLen; i++){
+					// 휴대폰번호 체크
+		        	var phone = data[i].getData().phone;
+		        	var valiCheck = checkHpNum(phone);
+		        	if(!valiCheck){
+		        		SetTableErrorDupliCheck(phone);
+		        	}
+				}
+			}
+			else {
+				for(var i=0; i < dataLen; i++){
+					// 휴대폰번호 체크
+		        	var phone = data[i].getData().phone;
+		        	var valiCheck = checkHpNum(phone);
+		        	if(!valiCheck){
+		        		SetTableErrorDupliCheck(phone);
+		        	}
+				}				
+			}
+		}
+		else {
+			alert("연락처를 입력해 주세요.");
+			return false;
+		}
+		
+		if (tableErrorCheckData.length > 0) {
+			for (var i = 0; i < tableErrorCheckData.length; i++)
+			{
+				errMsg += tableErrorCheckData[i];
+				if ((tableErrorCheckData.length - 1) > i) {
+					errMsg += ", ";
+				}
+			}			
+    		alert(errMsg + "의 내용에 오류가 있습니다.");			
+		}
+		else {
+			alert("오류 데이터가 없습니다.");			
+		}
+		
+		return false;		
+	});
+	
+
+
+	//받는사람 중복 삭제
+	$('.duple_del').click(function(){
+		//기존 연락처 모두 불러오기
+	    var data = $tableExcel.getRows();
+	    var tableData = [];
+	    var dpCnt = 0;
+	    var totLen = $tableExcel.getRows().length;
+	    
+	    for(var i=0; i < totLen; i++){
+	    	tableData.push({name: data[i].getData().name.trim(), phone: data[i].getData().phone.trim()});
+	    }
+	    
+	    var removeDuplData = dupliPhoneData(tableData);
+	    $tableExcel.setData(removeDuplData);
+	    
+	    //총 받는사람 수 계산
+	    totRows = $tableExcel.getRows().length;
+	    updateTotCnt(totRows);
+	});	
+	
+	
+});
+
+
+
+// 데이터 객체를 생성하는 함수
+function createDataObject(data) {
+    return {
+        A: data.A,
+        B: data.B,
+        C: data.C,
+        D: data.D,
+        E: data.E,
+        F: data.F,
+        G: data.G
+    };
+}
+
+//#############################################################################################
+//파일업로드 드래그앤 드롭
+//#############################################################################################
+var objDragAndDrop = $(".upload_area");
+$(document).on("dragenter",".upload_area",function(e){
+  e.stopPropagation();
+  e.preventDefault();
+  //$(this).css('border', '2px solid #0B85A1');
+});
+$(document).on("dragover",".upload_area",function(e){
+  e.stopPropagation();
+  e.preventDefault();
+});
+$(document).on("drop",".upload_area",function(e){
+  //$(this).css('border', '2px dotted #0B85A1');
+  e.preventDefault();
+  var files = e.originalEvent.dataTransfer.files;
+//   handleFileUpload(files,objDragAndDrop);  //파일업로드
+  excelFileChange(files[0]);
+});
+
+$(document).on('dragenter', function (e){
+  e.stopPropagation();
+  e.preventDefault();
+});
+$(document).on('dragover', function (e){
+e.stopPropagation();
+e.preventDefault();
+//objDragAndDrop.css('border', '2px dotted #0B85A1');
+});
+$(document).on('drop', function (e){
+  e.stopPropagation();
+  e.preventDefault();
+});
+//파일 드래그앤드롭 종료
+
+
+    function excelFileChange(file){
+
+//         var file = event.target.files[0];
+        if (file) {
+            var reader = new FileReader();
+            reader.onload = function(e) {
+                var data = new Uint8Array(e.target.result);
+                var workbook = XLSX.read(data, {type: 'array'});
+                var firstSheet = workbook.Sheets[workbook.SheetNames[0]];
+                var jsonData = XLSX.utils.sheet_to_json(firstSheet, {header: 1});
+                processExcelData(jsonData);
+            };
+            reader.readAsArrayBuffer(file);
+        }
+    }
+
+    // 엑셀 데이터 처리 함수
+    function processExcelData(data) {
+        var keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
+        var tableData = [];
+
+        // 3번째 행부터 입력 
+        // 1,2행은 예시와 타이틀이라 입력안함
+        data.slice(2).forEach(row => {
+            var rowData = {};
+            keys.forEach((key, index) => {
+                rowData[key] = row[index] ? row[index].trim() : ""; // 각 컬럼에 대해 기본값을 설정
+            });
+            tableData.push(rowData);
+        });
+
+
+        $tableExcel.setColumns([ // 열 정의를 다시 설정
+            {formatter: "rowSelection", titleFormatter: "rowSelection", clipboard: false, hozAlign: "center", headerHozAlign: "center", headerSort: false, cellClick: function(e, cell) {
+                cell.getRow().toggleSelect();
+            }},
+            {title: "A", hozAlign: "center", headerHozAlign: "center", field: "A", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "B", hozAlign: "center", headerHozAlign: "center", field: "B", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "C", hozAlign: "center", headerHozAlign: "center", field: "C", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "D", hozAlign: "center", headerHozAlign: "center", field: "D", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "E", hozAlign: "center", headerHozAlign: "center", field: "E", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "F", hozAlign: "center", headerHozAlign: "center", field: "F", editor: "input", width: 125, validator: ["maxLength:100", "string"]},
+            {title: "G", hozAlign: "center", headerHozAlign: "center", field: "G", editor: "input", width: 125, validator: ["maxLength:100", "string"]}
+        ]);
+        
+        $tableExcel.setData(tableData).then(() => {
+            // rowTotCnt 업데이트
+            document.getElementById("rowTotCnt").innerText = tableData.length;
+        });
+        
+    }
+
+    
+
+//#############################################################################################
+//등록
+//#############################################################################################
+
+
+
+// 주소록 그룹 중복체크
+function getAddrGroupDuplCheckAjax() {
+	var isReturn = true;
+	
+	$.ajax({
+		url : "<c:url value='/web/addr/getAddrGroupDuplCheckAjax.do' />", 
+		type : 'POST', 
+		data : {"addrGrpNm" : $("#addrGrpNm").val()},
+		dataType:'json',
+		async: false,			// 동기
+		success : function(data, status){
+			if(data.isSuccess == true) {
+				if(data.isDupl == true) {
+					//alert("중복된 그룹명입니다.");
+					isReturn = false;
+				}
+			} 
+			else {
+				//alert("Message : " + msg);
+			}			
+		},
+		error: function (e) {
+			//alert("주소록 중복체크에 실패했습니다.");
+		}
+	});
+	
+	return isReturn;	
+}
+
+//주소록그룹 콤보박스 유지
+function setSelectMassSetting(selectMassVal) {
+	$("#addrGrpIdInfo").val(selectMassVal).prop("selected", true);	
+}
+
+//데이터 비우기
+function SetClear() {
+	$("#addrGrpNm").val(""); //	새그룹명 Clear;
+	// 주소록 그룹정보 불러오기
+	getAddrGroupList();	
+	
+	var data = $tableExcel.getRows();	
+	if (data == null || data == "") {
+	}
+	else {
+		$tableExcel.clearData();
+		$("#rowTotCnt").text(0); //총건수 수정
+		$("#rowDupCnt").text(0); //중복건수 수정
+		dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
+	}
+}
+
+// 주소록 그룹정보 불러오기
+function getAddrGroupList() {
+    $.ajax({
+        type : "POST",
+        async : false,
+        url : "/web/mjon/addr/addrGroupListAjax.do",
+        data : {},
+        dataType:'json',
+        success : function(data) {
+			//alert(JSON.stringify(data.addrGroupList));
+
+			// Show Html
+			getAddrGroupListShow(data.addrGroupList);
+        },
+        error : function(xhr, status, error) {
+            alert(error);
+            return false;
+        }
+    });	    	
+}
+	
+// Show Html
+function getAddrGroupListShow(jsonList) {
+	var sHtml = "";
+	sHtml += "<option value='NEW'>그룹추가</option>";
+	sHtml += "<option value='0'>그룹미지정</option>";
+	sHtml += "<option value='bookmark'>자주보내는 번호</option>";
+	for (var j = 0; j < jsonList.length; j++) {
+		sHtml += "	<option value='" + $.trim(jsonList[j].addrGrpId) + "' />" + $.trim(jsonList[j].addrGrpNm) + "</option>";
+	}
+	    	
+	$("#addrGrpIdInfo").html(sHtml);
+}
+
+$(document).on('change', '#addrGrpIdInfo', function() {
+	if ($("#addrGrpIdInfo option:selected").val() != "NEW") {
+		$("#addrGrpNm").val(""); //	새그룹명 Clear;
+	}
+});
+
+//#############################################################################################
+//파일 불러오기
+//#############################################################################################
+
+//엑섹불러오기 버튼 클릭시 파일 첨부 실행
+$(document).on('click', '.c3', function() {
+	$("#excelFile").click();
+});
+
+//체크박스 전체선택/해제
+$(document).on("click", "#chkAll", function(e) {
+    var isChecked = $(this).is(":checked");
+    $("input[name=addrCheck]:checkbox").prop("checked", isChecked);
+});
+
+$(document).on("click", "#duplicationChkAll", function(e) {
+    var isChecked = $(this).is(":checked");
+    $("input[name=addrCheck]:checkbox").prop("checked", isChecked);
+});	
+
+
+
+// 중복 연락처
+function GetAddrMassDupli() {
+	var sHtml = "";
+	sHtml += "<div class='' style='overflow-x:auto; height:350px;'>";
+	sHtml += "<table class='tType4'>";
+	sHtml += "		<colgroup>";
+	sHtml += "			<col style='width:auto' />";
+	sHtml += "		</colgroup>";
+	sHtml += "		<thead>";
+	sHtml += "			<tr>";
+	sHtml += "				<th>중복 휴대폰번호 (" + numberWithCommas(dupliPhoneDataRealList.length) + "개)</th>";
+	sHtml += "			</tr>";
+	sHtml += "		</thead>";
+	sHtml += "		<tbody>";
+	for (var i = 0; i < dupliPhoneDataRealList.length; i++) {
+		sHtml += "		<tr>";
+		sHtml += "			<td>" + dupliPhoneDataRealList[i] + "</td>";
+		sHtml += "		</tr>";
+	}
+	sHtml += "		</tbody>";
+	sHtml += "	</table>";
+	sHtml += "	</div>";
+	
+	$("#addrMassDupli_layer").html(sHtml);
+}
+
+//중복 연락처 => 저장시
+function GetAddrMassSaveDupli() {
+	var sHtml = "";
+	sHtml += "<div class='' style='overflow-x:auto; height:350px;'>";
+	sHtml += "<table class='tType4'>";
+	sHtml += "		<colgroup>";
+	sHtml += "			<col style='width:auto' />";
+	sHtml += "		</colgroup>";
+	sHtml += "		<thead>";
+	sHtml += "			<tr>";
+// 	sHtml += "				<th>중복 휴대폰번호 (" + numberWithCommas(addrMassDupliSaveList.length) + "개)</th>";
+	sHtml += "				<th>중복 휴대폰번호 (10개)</th>";
+	sHtml += "			</tr>";
+	sHtml += "		</thead>";
+	sHtml += "		<tbody>";
+	for (var i = 0; i < addrMassDupliSaveList.length; i++) {
+		sHtml += "		<tr>";
+		sHtml += "			<td>" + addrMassDupliSaveList[i].addrPhoneNo + "</td>";
+		sHtml += "		</tr>";
+	}
+	sHtml += "		</tbody>";
+	sHtml += "	</table>";
+	sHtml += "	</div>";
+	
+	$("#addrMassSaveDupli_layer").html(sHtml);
+}
+
+</script>
+	               <!-- 엑셀입력 -->
+	               <div class="popCont current pop_more_cont" id="popCont_1">
+	                   <div class="titBox">
+							<p>- 엑셀(EXCEL) 파일로 주소록을 한 번에 최대 2만건까지 등록하여 간편하게 발송 및 관리하실 수 있습니다.</p>
+							<p>- 반드시 샘플파일을 다운로드하여 작성방법을 확인하신 후 정해진 양식에 맞추어 주소록을 작성하셔야 합니다.</p>
+							<p>  &nbsp;&nbsp;※ 주소록 관리 메뉴에서 다운로드 받으신 엑셀 파일 또한 업로드 양식에 맞추어 작성하셔야 하며, </p>
+							<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;주소록에 이미 등록된 휴대폰 번호는 업데이트 되지 않으므로 기존 주소록에서 해당 휴대폰 번호를 삭제한 후 재등록해 주시기 바랍니다.</p>
+							<p>- 쉼표(,), 구분선(|), 역슬래시(\, ₩), 작은따옴표('), 큰따옴표(") 등 발송불가 특수문자는 저장되지 않습니다.</p>
+							<p>- 휴대폰 번호는 필수입력 항목입니다.</p>
+							<p>- 전화번호 형태는 010-1234-5678 또는 01012345678 모두 가능합니다. 단, 공백은 허용되지 않습니다.</p>
+							<p>- 엑셀 파일에 비밀번호 설정, 제한된 보기, 수식 등이 설정되어 있는 경우 업로드가 불가합니다.</p>
+							<p>- 이름 20byte, [*1*]~[*4*] 40byte, 메모 250byte까지 입력 가능합니다.</p>
+							<p>- 첨부가능 파일 : xlsx, xls(최대용량 3MB)</p>
+							<p>- ‘오류 검사’를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.</p>
+							<p>- 주소록 등록이 어려우신 경우에는 주소록 입력대행 메뉴를 이용하시면 됩니다.</p>
+	                       <button type="button" class="excel_btn" onclick="location.href='/download/addr/주소록_대량등록.xlsx'"><i class="downroad"></i>샘플파일 다운로드</button>
+	                   </div>
+	                   <div class="pop_more_wrap">
+	                   		<button type="button" class="pop_more" onclick="popMore(this);">더보기<i></i></button>
+	                   </div>
+	                </div><!--// 엑셀입력 -->
+	                
+					<!-- 공통 -->
+					<div>
+		                <table class="layer_tType1">
+		                    <caption>엑셀입력 표</caption>
+		                    <colgroup>
+		                        <col style="width: 95px">
+		                        <col style="width: auto">
+		                    </colgroup>
+		                    <tbody>
+		                        <tr>
+		                            <th>그룹 선택</th>
+		                            <td>
+		                                <label for="" class="label">그룹 선택</label>
+		                                <select id="addrGrpIdInfo" name="addrGrpIdInfo">
+		                                </select>
+	                                    <label for="" class="label">그룹명 입력</label>
+	                                    <input type="text" id="addrGrpNm" name="addrGrpNm" placeholder="새 그룹명을 입력해주세요." onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명을 입력해주세요.'"class="inputLight" style="width: 300px;">
+	
+<!-- 		                                <input type="file" id="excelFile" accept=".xls, .xlsx, .txt" onchange="excelExport(event); return false;" style="display:none"/> -->
+		                                <input type="file" id="excelFile" accept=".xls, .xlsx, .txt" style="display:none"/>
+<!-- 		                                  <button type="button" id="file-load-trigger">Choose File</button> -->
+		                                <button type="button" class="excel_btn2 btnType c3"><i class="uproad"></i>엑셀, TXT파일 업로드</button>
+		                            </td>
+		                        </tr>
+		                    </tbody>
+		                </table>
+	                </div>
+					<div class="file_add upload_area">
+						<p><img src="/publish/images/content/file_add.png" alt="파일 붙여넣기">마우스로 엑셀, TXT파일을 여기에 끌어다 놓으세요</p>
+					</div>
+					<div class="excel_middle2">
+						<p>
+							총 <span class="c_e40000 fwBold" id="rowTotCnt">0</span>건 / 중복 <span class="c_002c9a fwBold" id="rowDupCnt">0</span>건
+							&nbsp; 
+							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" onclick="GetAddrMassDupli()" id="btnAddrMassDupli">중복번호</button>
+							&nbsp;
+							<button type="button" class="btnType btnType6" data-tooltip="addrMassSaveDupli_layer" onclick="GetAddrMassSaveDupli()" id="btnAddrMassSaveDupli">중복번호</button>
+						</p>
+<!-- 						<button type="button" class="btnType btnType6 addCallToF">번호추가</button> -->
+					</div>
+					
+					
+					
+
+                    <div class="adr_excel" style="margin-top: 13px;">
+                        <!-- thead -->
+                        <div class="adr_hd select_adr_hd" data-group="tableExcel">
+                            <div></div>
+                            <div style="width: 125px;">
+                            	<label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                        </div>
+                     </div>					
+					
+					<div class="drag_drop_wrap callList_box" id="tabulator_excel">
+						<img src="/publish/images/content/excel.jpg" style="width: 100%;">
+					</div>
+					<div class="excel_middle">
+						<div class="select_btnWrap clearfix">
+							<div>
+								<button type="button" class="all_del"><i class="remove_img"></i>전체삭제</button>
+								<button type="button" class="select_del"><i class="remove_img"></i>선택삭제</button>
+								<button type="button" class="chkVali_del"><i class="remove_img"></i>오류번호삭제</button>
+								<button type="button" class="check_validity">오류 검사 <i></i></button>
+								<div class="error_hover_cont send_hover_cont addr_hover_cont">
+									<p>휴대폰 번호 입력 시 해당 휴대폰 번호에 대한 형식이 어긋나거나 휴대폰 번호에 오류가 있는지 등을 검사하는 기능</p>
+									<span>(예시) 010-1234-0001(O) / 010-123-0001(X)</span>
+								</div>
+							</div>
+	
+						</div>
+					</div><!--// 공통 -->     
+	
+					<!-- 붙여놓기 설명 -->
+	                <div class="req_area">
+	                  	<div class="text_box">
+	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br>
+							- 휴대폰 번호는 필수입력 항목입니다.<br>
+							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br>
+							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br>
+							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.
+						</div>
+	                </div>
 
src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforSelf.jsp (added)
+++ src/main/webapp/WEB-INF/jsp/web/addr/include/addrListforSelf.jsp
@@ -0,0 +1,697 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+
+<script type="text/javascript" src="<c:url value='/publish/js/content.js'/>"></script>
+
+<script type="text/javascript">
+$(document).ready(function(){
+	
+	// 중복 휴대폰번호 버튼 노출여부
+// 	$("#btnAddrMassDupli").hide();
+// 	$("#btnAddrMassSaveDupli").hide();
+
+	//붙여넣기 이벤트 핸들러
+	document.querySelector('#tabulator_clip').addEventListener('paste', function(e) {
+		e.preventDefault();
+		var text = e.clipboardData.getData('text/plain');
+		var rows = text.split('\n').map(row => row.split(',').map(cell => cell.trim()));
+		
+		var tableData = rows.map(row => {
+			return {
+				A: row[0] || "",
+				B: row[1] || "",
+				C: row[2] || "",
+				D: row[3] || "",
+				E: row[4] || "",
+				F: row[5] || "",
+				G: row[6] || ""
+			};
+		});
+		
+		$tableClip.setData(tableData);
+	});
+
+}); 
+
+
+
+
+function addrGroupLoadAjax(){
+	$("#addrRegistSelect").load("/web/addr/selectAddrGroupAjax.do", function(response, status, xhr){});
+	$("#funcAddrGroupSelect").load("/web/addr/selectAddrGroupAjax.do", function(response, status, xhr){});
+}
+
+
+function insertAddrGroupAjax() {
+	var form = document.addrGrpInsertForm;
+	if(form.addrGrpNm.value == "") {
+		alert("주소록 그룹명을 입력해주세요.");
+		return;
+	}
+	if(!confirm("주소록 그룹을 추가하시겠습니까?")) {
+		return;
+	}
+	var data = new FormData(form);
+	
+	$.ajax({
+		cache : false,
+		url : "<c:url value='/web/addr/insertAddrGroupAjax.do' />", 
+		type : 'POST', 
+		data : data,
+		dataType:'json',
+		processData: false,
+		contentType: false,
+		success : function(returnData, status){
+			if(status == "success") {
+				if("fail"==returnData.result){
+					alert(returnData.message);
+					return;
+				} else if("dupl"==returnData.result) {
+					alert("중복된 그룹명입니다.");
+					return;
+				}
+				alert("등록되었습니다.");
+				listAddrGrp();
+				addrGroupLoadAjax();
+				
+			}else{ alert("ERROR!");return;} 
+		},
+		error: function (e) { alert("저장에 실패하였습니다."); console.log("ERROR : ", e); }
+	});
+	
+}
+
+function insertAddrAjax() {
+	var selectVal = $("#addrRegistSelect option:selected").val();
+	//alert(selectVal);
+	
+	var form = document.addrInsertForm;
+	/*
+	//필수값 아니어서 뺐음
+	if(form.addrNm.value == "") {
+		alert("주소록 이름을 입력하세요");
+		return;
+	}
+	*/
+	if(form.addrPhoneNo.value == "") {
+		alert("주소록 번호를 입력하세요");
+		return;
+	}
+	//if(!confirm("주소록을 추가하시겠습니까?")) {
+	//	return;
+	//}
+	
+	if(!checkHpNum(form.addrPhoneNo.value)){//휴대폰 유효성 검사
+		if(!checkNorPhoneNum(form.addrPhoneNo.value)){//일반전화 유효성 검사
+			
+			alert("잘못된 휴대폰번호 또는 일반전화 번호 입니다.");
+			return false;
+			
+		}
+		
+	}
+	
+	var data = new FormData(form);
+
+	$.ajax({
+		cache : false,
+		url : "<c:url value='/web/mjon/addr/insertAddrAjax.do' />", 
+		type : 'POST', 
+		data : data,
+		dataType:'json',
+		processData: false,
+		contentType: false,
+		success : function(returnData, status){
+			if(status == "success") {
+				if("fail"==returnData.result){
+					alert(returnData.message);
+					return;
+				} else if("dupl"==returnData.result){
+					alert("해당 그룹에 중복된 번호가 있습니다.");
+					return;
+				}
+				//alert("저장 되었습니다.");
+				
+				listAddrGrp();
+				addrGroupLoadAjax();
+				addrLoadAjax();
+				
+				// 주소록그룹 콤보박스 유지
+				setTimeout(setSelectSetting, 500, selectVal);			
+				
+			}else{ alert("ERROR!");return;} 
+		},
+		error: function (e) { alert("저장에 실패하였습니다."); console.log("ERROR : ", e); }
+	});
+	
+}
+
+// 주소록그룹 콤보박스 유지
+function setSelectSetting(selectVal) {
+	$("#addrRegistSelect").val(selectVal).prop("selected", true);	
+}
+	
+function linkPage(pageNo){
+	if ($('#searchKeywordAddr').val() != "" && $('#searchKeywordAddr').val() != null && $('#searchKeywordAddr').val() != undefined) {
+		// 문자전송 검색용
+		$("#msgStartKeyword").val("");
+	}
+
+	var searchForm = document.searchAddrForm;
+	searchForm.pageIndex.value = pageNo;
+	searchForm.pageUnit.value = $('#pageUnit').val();
+	searchForm.searchCondition.value = $('#searchConditionAddr').val();
+	searchForm.searchKeyword.value = $('#searchKeywordAddr').val();
+	searchForm.startKeyword.value = $("#msgStartKeyword").val();
+	
+	var sendData = $(document.searchAddrForm).serializeArray();
+	$("#adr1_right").load("/web/mjon/addr/selectAddrAjax.do", sendData, function(response, status, xhr){tableAllChk();});
+	addrGroupLoadAjax();
+}
+
+
+
+//#############################################################################################
+//Tabulator
+//#############################################################################################
+
+$(document).ready(function(){
+	//Tabulator AJAX Data Loading
+
+    // 파일 선택 버튼 클릭 이벤트
+    $("#file-load-trigger").on("click", function() {
+        $("#excelFile").click();
+    });
+
+    // 파일 입력 이벤트
+    $("#excelFile").on("change", function(event) {
+    	excelFileChange(event.target.files[0]);
+    });
+    
+
+
+	//받는사람 전체삭제 버튼 처리
+	$('.all_del').click(function(){
+		var data = $tableClip.getRows();	
+		if(data == null || data == ""){
+			alert("받는사람을 추가해 주세요.");
+			return false;
+		}else{
+			$tableClip.clearData();
+			$("#rowTotCnt").text(0); //총건수 수정
+			$("#rowDupCnt").text(0); //중복건수 수정
+			dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
+		}
+		
+	});
+
+
+	// 받는사람 선택삭제 버튼 처리해주기
+	$('.select_del').click(function(){
+		$("#rowDupCnt").text(0); //중복건수 수정
+		dupliPhoneDataRealList.length = 0;	// 중복 휴대폰번호 초기화
+		
+		if($tableClip == null || $tableClip == ""){
+			alert("받는사람을 추가해 주세요.");
+			return false;
+		}
+		
+		var selectedData = $tableClip.getSelectedRows();
+		
+		if(selectedData == "" || selectedData == null){
+			alert("받는 사람을 선택해 주세요.");
+			return false;
+		}else{ // 선택한 Row 데이터 삭제하기
+			for(var i=0; i < selectedData.length; i++){
+				selectedData[i].delete();
+			}
+		}
+		
+		totRows = $tableClip.getRows().length;
+	    
+		updateTotCnt(totRows);
+	});
+
+	//받는사람 오류번호 삭제 처리해주기
+	$('.chkVali_del').click(function(){
+		//기존 연락처 모두 불러오기
+	    var data = $tableClip.getRows();
+	    var tableData = [];
+	    var totLen = $tableClip.getRows().length;
+	    var errCnt = 0;
+	    
+	    if(totLen > 0){
+	    	if(confirm("올바르지 않은 연락처 정보를 삭제 하시겠습니까?")){
+	    		for(var i=0; i < totLen; i++){
+
+	    			
+	            	var phone = data[i].getData().phone;
+	            	var valiCheck = checkHpNum(phone);
+	            	if(valiCheck){
+	            		tableData.push({name: data[i].getData().name.trim(), phone: data[i].getData().phone.trim(), info1:data[i].getData().info1, info2:data[i].getData().info2, info3:data[i].getData().info3, info4:data[i].getData().info4, memo:data[i].getData().memo});
+	            	}else{
+	            		errCnt++;
+	            	}
+	            }
+	            
+	            var removeDuplData = dupliPhoneData(tableData);
+	        	
+	            $tableClip.setData(removeDuplData);
+	            
+	            //총 받는사람 수 계산
+	            totRows = $tableClip.getRows().length;
+	            updateTotCnt(totRows);
+	            
+	          	if(errCnt > 0){
+	          		alert(errCnt + " 건의 연락처를 삭제하였습니다.");
+	          		return false;
+	          	}else{
+	          		alert("오류가 있는 연락처가 없습니다.");
+	          	}
+	    	}
+	    }else{
+	    	alert("연락처 정보를 입력해 주세요.");
+	    	return false;
+	    }
+	});
+	
+
+
+    
+    
+	// 오류검사 항목 중복제거
+	function SetTableErrorDupliCheck(sVal) {
+		var isDuplicate = false;
+		if (tableErrorCheckData.length == 0) {
+			tableErrorCheckData.push(sVal);
+		}
+		else {
+			for (var i = 0; i < tableErrorCheckData.length; i++)
+			{
+				if (tableErrorCheckData[i] == sVal) {
+					isDuplicate = true;
+				}
+			}
+			
+			if (isDuplicate) {
+				return;
+			}
+			else {
+				tableErrorCheckData.push(sVal);
+			}
+		}
+	}	
+	
+	
+	// 오류검사 항목 중복제거
+	function SetTableErrorDupliCheck(sVal) {
+		var isDuplicate = false;
+		if (tableErrorCheckData.length == 0) {
+			tableErrorCheckData.push(sVal);
+		}
+		else {
+			for (var i = 0; i < tableErrorCheckData.length; i++)
+			{
+				if (tableErrorCheckData[i] == sVal) {
+					isDuplicate = true;
+				}
+			}
+			
+			if (isDuplicate) {
+				return;
+			}
+			else {
+				tableErrorCheckData.push(sVal);
+			}
+		}
+	}	
+	
+	$('.check_validity').click(function(){
+		tableErrorCheckData.length = 0;	// 오류 번호 배열 초기화
+		
+		var data = $tableClip.getRows();
+		var invalid = $tableClip.getInvalidCells();		//오류 데이터 체크
+		var dataLen = $tableClip.getRows().length;		//연락처 데이터 갯수
+		var totLen = invalid.length;				//오류 데이터 갯수
+		var errMsg = "";							//최종 alert에 표시할 메시지 저장 변수
+		
+		if(dataLen > 0) { //연락처 정보가 있으면 수행
+			if(totLen > 0) { //내용에 오류가 있으면 수행
+				//오류 데이터 값 저장
+				for(var i=0; i < totLen; i++) {
+					var cellValue = invalid[i].getValue();
+					SetTableErrorDupliCheck(cellValue);
+				}
+				
+				for(var i=0; i < dataLen; i++){
+					// 휴대폰번호 체크
+		        	var phone = data[i].getData().phone;
+		        	var valiCheck = checkHpNum(phone);
+		        	if(!valiCheck){
+		        		SetTableErrorDupliCheck(phone);
+		        	}
+				}
+			}
+			else {
+				for(var i=0; i < dataLen; i++){
+					// 휴대폰번호 체크
+		        	var phone = data[i].getData().phone;
+		        	var valiCheck = checkHpNum(phone);
+		        	if(!valiCheck){
+		        		SetTableErrorDupliCheck(phone);
+		        	}
+				}				
+			}
+		}
+		else {
+			alert("연락처를 입력해 주세요.");
+			return false;
+		}
+		
+		if (tableErrorCheckData.length > 0) {
+			for (var i = 0; i < tableErrorCheckData.length; i++)
+			{
+				errMsg += tableErrorCheckData[i];
+				if ((tableErrorCheckData.length - 1) > i) {
+					errMsg += ", ";
+				}
+			}			
+    		alert(errMsg + "의 내용에 오류가 있습니다.");			
+		}
+		else {
+			alert("오류 데이터가 없습니다.");			
+		}
+		
+		return false;		
+	});
+	
+
+
+	//받는사람 중복 삭제
+	$('.duple_del').click(function(){
+		//기존 연락처 모두 불러오기
+	    var data = $tableClip.getRows();
+	    var tableData = [];
+	    var dpCnt = 0;
+	    var totLen = $tableClip.getRows().length;
+	    
+	    for(var i=0; i < totLen; i++){
+	    	tableData.push({name: data[i].getData().name.trim(), phone: data[i].getData().phone.trim()});
+	    }
+	    
+	    var removeDuplData = dupliPhoneData(tableData);
+	    $tableClip.setData(removeDuplData);
+	    
+	    //총 받는사람 수 계산
+	    totRows = $tableClip.getRows().length;
+	    updateTotCnt(totRows);
+	});	
+	
+	
+});
+
+
+// Show Html
+function getAddrGroupListShow(jsonList) {
+	var sHtml = "";
+	sHtml += "<option value='NEW'>그룹추가</option>";
+	sHtml += "<option value='0'>그룹미지정</option>";
+	sHtml += "<option value='bookmark'>자주보내는 번호</option>";
+	for (var j = 0; j < jsonList.length; j++) {
+		sHtml += "	<option value='" + $.trim(jsonList[j].addrGrpId) + "' />" + $.trim(jsonList[j].addrGrpNm) + "</option>";
+	}
+	    	
+	$("#addrGrpIdInfo").html(sHtml);
+}
+
+$(document).on('change', '#addrGrpIdInfo', function() {
+	if ($("#addrGrpIdInfo option:selected").val() != "NEW") {
+		$("#addrGrpNm").val(""); //	새그룹명 Clear;
+	}
+});
+
+//#############################################################################################
+//파일 불러오기
+//#############################################################################################
+
+
+//체크박스 전체선택/해제
+$(document).on("click", "#chkAll", function(e) {
+    var isChecked = $(this).is(":checked");
+    $("input[name=addrCheck]:checkbox").prop("checked", isChecked);
+});
+
+$(document).on("click", "#duplicationChkAll", function(e) {
+    var isChecked = $(this).is(":checked");
+    $("input[name=addrCheck]:checkbox").prop("checked", isChecked);
+});	
+
+
+
+// 중복 연락처
+function GetAddrMassDupli() {
+	var sHtml = "";
+	sHtml += "<div class='' style='overflow-x:auto; height:350px;'>";
+	sHtml += "<table class='tType4'>";
+	sHtml += "		<colgroup>";
+	sHtml += "			<col style='width:auto' />";
+	sHtml += "		</colgroup>";
+	sHtml += "		<thead>";
+	sHtml += "			<tr>";
+	sHtml += "				<th>중복 휴대폰번호 (" + numberWithCommas(dupliPhoneDataRealList.length) + "개)</th>";
+	sHtml += "			</tr>";
+	sHtml += "		</thead>";
+	sHtml += "		<tbody>";
+	for (var i = 0; i < dupliPhoneDataRealList.length; i++) {
+		sHtml += "		<tr>";
+		sHtml += "			<td>" + dupliPhoneDataRealList[i] + "</td>";
+		sHtml += "		</tr>";
+	}
+	sHtml += "		</tbody>";
+	sHtml += "	</table>";
+	sHtml += "	</div>";
+	
+	$("#addrMassDupli_layer").html(sHtml);
+}
+
+//중복 연락처 => 저장시
+function GetAddrMassSaveDupli() {
+	var sHtml = "";
+	sHtml += "<div class='' style='overflow-x:auto; height:350px;'>";
+	sHtml += "<table class='tType4'>";
+	sHtml += "		<colgroup>";
+	sHtml += "			<col style='width:auto' />";
+	sHtml += "		</colgroup>";
+	sHtml += "		<thead>";
+	sHtml += "			<tr>";
+// 	sHtml += "				<th>중복 휴대폰번호 (" + numberWithCommas(addrMassDupliSaveList.length) + "개)</th>";
+	sHtml += "				<th>중복 휴대폰번호 (10개)</th>";
+	sHtml += "			</tr>";
+	sHtml += "		</thead>";
+	sHtml += "		<tbody>";
+	for (var i = 0; i < addrMassDupliSaveList.length; i++) {
+		sHtml += "		<tr>";
+		sHtml += "			<td>" + addrMassDupliSaveList[i].addrPhoneNo + "</td>";
+		sHtml += "		</tr>";
+	}
+	sHtml += "		</tbody>";
+	sHtml += "	</table>";
+	sHtml += "	</div>";
+	
+	$("#addrMassSaveDupli_layer").html(sHtml);
+}
+
+</script>
+	             
+	                <!-- 붙여넣기 -->
+	                <div class="popCont pop_more_cont" id="popCont_2">
+	                    <div class="titBox">
+	                        <p>- 텍스트(txt) 파일로 작성된 주소록을 등록하실 수 있습니다.</p>
+	                        <p>- 반드시 샘플파일을 다운로드하여 작성방법을 확인하신 후 정해진 양식에 맞추어 주소록을 붙여 넣으셔야 합니다.</p>
+	                        <p>- 입력 내용은 (Tab) 또는 (,) 구분하여 입력하여야 합니다.</p>
+	                        <p>- 한 줄(열)에 주소 한 건만 입력 가능합니다.</p>
+	                        <p>- 전화번호 형태는 010-1234-5678 또는 01012345678 모두 가능합니다. 단, 공백은 허용되지 않습니다.</p>
+	                        <p>&nbsp;&nbsp;(예) 홍길동,010-1234-5678 또는 홍길동,01012345678</p>
+	                        <p>- 한번에 많은 양의 데이터를 입력하시려면 ‘주소록 복사(Ctrl+c) + 붙여넣기(Ctrl+v)’ 또는 ‘엑셀입력’을 이용하세요.</p>
+	                        <p>- 주소록 등록이 어려우신 경우에는 주소록 입력대행 메뉴를 이용하시면 됩니다.</p>
+	                        <button type="button" class="txt_btn" onclick="location.href='/download/addr/주소록_대량등록.zip'"><i></i>TXT샘플 다운로드</button>                        
+	                    </div>
+	                    <div class="pop_more_wrap">
+	                   		<button type="button" class="pop_more" onclick="popMore(this);">더보기<i></i></button>
+	                   </div>
+	                </div><!--// 붙여넣기 -->                
+	
+					<!-- 공통 -->
+					<div>
+		                <table class="layer_tType1">
+		                    <caption>엑셀입력 표</caption>
+		                    <colgroup>
+		                        <col style="width: 95px">
+		                        <col style="width: auto">
+		                    </colgroup>
+		                    <tbody>
+		                        <tr>
+		                            <th>그룹 선택</th>
+		                            <td>
+		                                <label for="" class="label">그룹 선택</label>
+		                                <select id="addrGrpIdInfo" name="addrGrpIdInfo">
+		                                </select>
+	                                    <label for="" class="label">그룹명 입력</label>
+	                                    <input type="text" id="addrGrpNm" name="addrGrpNm" placeholder="새 그룹명을 입력해주세요." onfocus="this.placeholder=''" onblur="this.placeholder='새 그룹명을 입력해주세요.'"class="inputLight" style="width: 300px;">
+	
+<!-- 		                                <input type="file" id="excelFile" accept=".xls, .xlsx, .txt" onchange="excelExport(event); return false;" style="display:none"/> -->
+		                                <input type="file" id="excelFile" accept=".xls, .xlsx, .txt" style="display:none"/>
+<!-- 		                                  <button type="button" id="file-load-trigger">Choose File</button> -->
+		                                <button type="button" class="excel_btn2 btnType c3"><i class="uproad"></i>엑셀, TXT파일 업로드</button>
+		                            </td>
+		                        </tr>
+		                    </tbody>
+		                </table>
+	                </div>
+					<div class="file_add upload_area">
+						<p><img src="/publish/images/content/file_add.png" alt="파일 붙여넣기">마우스로 엑셀, TXT파일을 여기에 끌어다 놓으세요</p>
+					</div>
+					<div class="excel_middle2">
+						<p>
+							총 <span class="c_e40000 fwBold" id="rowTotCnt">0</span>건 / 중복 <span class="c_002c9a fwBold" id="rowDupCnt">0</span>건
+<!-- 							&nbsp;  -->
+<!-- 							<button type="button" class="btnType btnType6" data-tooltip="addrMassDupli_layer" onclick="GetAddrMassDupli()" id="btnAddrMassDupli">중복번호</button> -->
+<!-- 							&nbsp; -->
+<!-- 							<button type="button" class="btnType btnType6" data-tooltip="addrMassSaveDupli_layer" onclick="GetAddrMassSaveDupli()" id="btnAddrMassSaveDupli">중복번호</button> -->
+						</p>
+						<button type="button" class="btnType btnType6 addCallToF">번호추가</button>
+					</div>
+					
+					
+					
+
+                    <div class="adr_excel" style="margin-top: 13px;">
+                        <!-- thead -->
+                        <div class="adr_hd select_adr_hd" data-group="tabulClip">
+                            <div></div>
+                            <div style="width: 125px;">
+                            	<label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                            <div style="width: 125px;">
+                                <label for="" class="label"></label>
+								<select class="field-selector">
+									<option value="">선택하기</option>
+									<option value="addrNm">이름</option>
+									<option value="addrPhoneNo">휴대폰</option>
+									<option value="addrInfo1">[*1*]</option>
+									<option value="addrInfo2">[*2*]</option>
+									<option value="addrInfo3">[*3*]</option>
+									<option value="addrInfo4">[*4*]</option>
+									<option value="addrComment">메모</option>
+								</select>
+                            </div>
+                        </div>
+                     </div>					
+					
+					<div class="drag_drop_wrap callList_box" id="tabulator_clip">
+						<img src="/publish/images/content/excel.jpg" style="width: 100%;">
+					</div>
+					<div class="excel_middle">
+						<div class="select_btnWrap clearfix">
+							<div>
+								<button type="button" class="all_del"><i class="remove_img"></i>전체삭제</button>
+								<button type="button" class="select_del"><i class="remove_img"></i>선택삭제</button>
+								<button type="button" class="chkVali_del"><i class="remove_img"></i>오류번호삭제</button>
+								<button type="button" class="check_validity">오류 검사 <i></i></button>
+								<div class="error_hover_cont send_hover_cont addr_hover_cont">
+									<p>휴대폰 번호 입력 시 해당 휴대폰 번호에 대한 형식이 어긋나거나 휴대폰 번호에 오류가 있는지 등을 검사하는 기능</p>
+									<span>(예시) 010-1234-0001(O) / 010-123-0001(X)</span>
+								</div>
+							</div>
+	
+						</div>
+					</div><!--// 공통 -->     
+	
+					<!-- 붙여놓기 설명 -->
+	                <div class="req_area">
+	                  	<div class="text_box">
+	                    	- 휴대폰 번호가 입력된 txt 파일을 열어 복사(Ctrl+c) + 붙여넣기(Ctrl+v)로도 입력하실 수 있습니다.<br>
+							- 휴대폰 번호는 필수입력 항목입니다.<br>
+							- 이름,휴대폰 번호,[*1*],[*2*],[*3*],[*4*],메모 순서대로 입력해주세요.(예 : 010-1234-5678,홍길동,변수1…메모)<br>
+							- 이름은 24byte, [*1*]~[*4*] 40byte, 메모는 250byte까지 입력 가능합니다.<br>
+							- '오류 검사'를 통해 등록된 데이터에 전화번호 입력 오류를 확인하실 수 있습니다.
+						</div>
+	                </div>
 
src/main/webapp/js/web/addr/event.js (added)
+++ src/main/webapp/js/web/addr/event.js
@@ -0,0 +1,117 @@
+
+
+$(document).ready(function(){
+
+	
+	//타이틀 select 선택 이벤트
+	 $('[data-group]').on('change', '.field-selector', function() {
+		 
+		var group = $(this).closest('[data-group]').data('group');
+		var selectedFields = [];
+		var isDuplicate = false;
+		
+
+		// 타불 객체 가져오기
+		var $objTabul = fn_utils_getTabulator();
+
+		console.log('$objTabul : ', $objTabul);
+		
+		if($objTabul.getData().length < 1){
+			alert('데이터 입력 후 선택해 주세요.');
+			$(this).val(""); 
+			return false;
+		}
+		
+		// 중복체크
+		$('[data-group="' + group + '"] .field-selector').each(function() {
+			var selectedField = $(this).val();
+			if (selectedField) {
+				if (selectedFields.includes(selectedField)) {
+					alert("중복된 필드를 선택할 수 없습니다.");
+					$(this).val(""); // 중복 필드를 선택한 경우 빈 값으로 초기화
+					isDuplicate = true;
+					return false; // 반복문 종료
+				}
+				selectedFields.push(selectedField);
+			}
+		});
+
+
+		// 
+		updateTableFields($objTabul, group);
+		
+		// 필드가 휴대폰이면 열 중복체크
+		if($(this).val() == 'phone'){
+			fn_phoneDupl($objTabul);
+		}
+	});
+
+
+	function fn_phoneDupl($objTabul){
+		
+		var phoneFields = $objTabul.getData().map(row => row.phone);
+	
+		if(phoneFields.length < 1){ return false; }
+	
+		var uniquePhones = new Set();
+		var duplicatePhones = [];
+	
+		phoneFields.forEach(phone => {
+			if (uniquePhones.has(phone)) {
+				duplicatePhones.push(phone);
+			} else {
+				uniquePhones.add(phone);
+			}
+		});
+	
+		$('#rowDupCnt').text(duplicatePhones.length);
+		if (duplicatePhones.length > 0) {
+			alert("중복된 휴대폰 번호가 있습니다: \n" + duplicatePhones.join(", "));
+		} else {
+//			alert("중복된 phone 필드 값이 없습니다.");
+		}
+	}
+
+	/* 
+	* 타이틀 select 선택할때마다 실행해서         
+	* 데이터테이블 필드값 수정                  
+	*/
+	function updateTableFields($objTabul, group) {
+		var currentData = $objTabul.getData();
+		var columns = [
+			{formatter: "rowSelection", titleFormatter: "rowSelection", clipboard: false, hozAlign: "center", headerHozAlign: "center", headerSort: false, cellClick: function(e, cell) {
+				cell.getRow().toggleSelect();
+			}}
+		];
+
+		var fieldMapping = [];
+		$('[data-group="' + group + '"] .field-selector').each(function(index) {
+			var selectedField = $(this).val();
+			//  ASCII 문자 코드 사용 - 65=A, 66=B ...
+			var field = String.fromCharCode(65 + index);
+			if (selectedField) {
+				columns.push({title: field, field: selectedField, hozAlign: "center", headerHozAlign: "center", editor: "input", width: 125, validator: ["maxLength:100", "string"]});
+				fieldMapping.push(selectedField);
+			} else {
+				columns.push({title: field, field: field, hozAlign: "center", headerHozAlign: "center", editor: "input", width: 125, validator: ["maxLength:100", "string"]});
+				fieldMapping.push(field);
+			}
+		});
+
+		var updatedData = currentData.map(row => {
+			var newRow = {};
+			fieldMapping.forEach((field, index) => {
+				newRow[field] = row[Object.keys(row)[index]] || "";
+			});
+			return newRow;
+		});
+
+		$objTabul.setColumns(columns);
+		$objTabul.setData(updatedData);
+		
+		
+	}
+	
+	
+	
+}); (No newline at end of file)
 
src/main/webapp/js/web/addr/init.js (added)
+++ src/main/webapp/js/web/addr/init.js
@@ -0,0 +1,120 @@
+
+
+var tableErrorData = [];
+var tableErrorCheckData = [];
+var addrMassDupliSaveList = null;
+
+var gArrRestartIndex = 0;	//배열 재시작카운드
+var gNameList = [];		//치환문자 이름
+var gPhoneList = [];	//받는사람
+var gInfo1List = [];		//치환문자1
+var gInfo2List = [];		//치환문자2
+var gInfo3List = [];		//치환문자3
+var gInfo4List = [];		//치환문자4
+var gMemoList = [];			//메모
+
+
+var $tableExcel = null; //엑셀입력 탭
+var $tableClip = null; //붙여넣기 탭
+var $tableSelf = null; //붙여넣기 탭
+
+$(document).ready(function(){
+
+	//Tabulator AJAX Data Loading
+	$tableExcel = new Tabulator("#tabulator_excel", {
+		height:"255px",
+		width:"100%",
+	    layout:"fitColumns",
+	    autoColumns:false,
+	    headerHozAlign:"center", 
+	    validationMode:"highlight",
+	    clipboard:false,
+	    clipboardCopySelector:"table",
+	    clipboardPasteAction:"insert", // insert, update, replace
+	    placeholder:"Excel 파일을 업로드 해주세요.", //fit columns to width of table (optional)
+	 	columns:[ //Define Table Columns
+	 		{formatter:"rowSelection", titleFormatter:"rowSelection",clipboard:false, hozAlign:"center", headerSort:false, cellClick:function(e, cell){
+	 	        cell.getRow().toggleSelect();
+		 		}
+		 	}, 
+		 	{title:"A", hozAlign:"center", headerHozAlign: "center", field:"A", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"B", hozAlign:"center", headerHozAlign: "center", field:"B", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"C", hozAlign:"center", headerHozAlign: "center", field:"C", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"D", hozAlign:"center", headerHozAlign: "center", field:"D", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"E", hozAlign:"center", headerHozAlign: "center", field:"E", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"F", hozAlign:"center", headerHozAlign: "center", field:"F", editor:"input", width:125, validator:["maxLength:100", "string"]},
+		 	{title:"G", hozAlign:"center", headerHozAlign: "center", field:"G", editor:"input", width:125, validator:["maxLength:100", "string"]}
+	 	],
+	 	validationFailed:function(cell, value, parameters){ // 유효성 체크 함수 
+	        var valid = cell.isValid();
+	 		if(!valid){
+	 			alert("양식에 맞지 않는 정보가 입력되었습니다.");
+	 			
+	 			//해당 셀 데이터 삭제
+	 			cell.setValue("");
+	 		}
+	 		return value % parameters.phone;
+	    },
+	});
+
+	
+
+
+
+	$tableClip = new Tabulator("#tabulator_clip", {
+		height:"255px",
+		width:"100%",
+		layout:"fitColumns",
+		editor:true,
+		headerHozAlign:"center",
+		validationMode:"highlight",
+	    placeholder:"복사(Ctrl+C)한 내용을 여기에 붙여넣기(Ctrl+V) 해주세요.", //fit columns to width of table (optional)
+		clipboard:true, // 클립보드 기능 활성화
+	    clipboardPasteAction:"insert", // insert, update, replace
+	    clipboardPasteParser: function(clipboard) {
+	    	
+	    	// clipboard 기능 
+			var rows = clipboard.split('\n').map(row => row.split(/[\t,]+/).map(cell => cell.trim()));
+			console.log('rows : ', rows);
+			var tableData = rows.map(row => {
+				return {
+					A: row[0] || "",
+					B: row[1] || "",
+					C: row[2] || "",
+					D: row[3] || "",
+					E: row[4] || "",
+					F: row[5] || "",
+					G: row[6] || ""
+				};
+			});
+	        return tableData;
+	    },
+	    columns: [
+            {formatter: "rowSelection", titleFormatter: "rowSelection", clipboard: false, hozAlign: "center", headerHozAlign: "center", headerSort: false, cellClick: function(e, cell) {
+                cell.getRow().toggleSelect();
+            }},
+			{title:"A", field:"A", hozAlign:"center", headerHozAlign: "center", width:125, validator:["maxLength:100", "string"]},
+			{title:"B", field:"B", hozAlign:"center", headerHozAlign: "center", width:125, validator:["maxLength:100", "string"]},
+			{title:"C", field:"C", hozAlign:"center", headerHozAlign: "center", width:125, validator:["maxLength:100", "string"]},
+			{title:"D", field:"D", hozAlign:"center", headerHozAlign: "center", width:125, validator:["maxLength:100", "string"]},
+			{title:"E", field:"E", hozAlign:"center", headerHozAlign: "center", width:125, validator:["maxLength:100", "string"]},
+			{title:"F", field:"F", hozAlign:"center", headerHozAlign: "center", width:125, validator:["maxLength:100", "string"]},
+			{title:"G", field:"G", hozAlign:"center", headerHozAlign: "center", width:125, validator:["maxLength:100", "string"]}
+		],
+	 	validationFailed:function(cell, value, parameters){ // 유효성 체크 함수 
+	        var valid = cell.isValid();
+	 		if(!valid){
+	 			alert("양식에 맞지 않는 정보가 입력되었습니다.");
+	 			
+	 			//해당 셀 데이터 삭제
+	 			cell.setValue("");
+	 		}
+	 		return value % parameters.phone;
+	    },
+	});
+	
+	
+	
+	
+	
+}); (No newline at end of file)
 
src/main/webapp/js/web/addr/utils.js (added)
+++ src/main/webapp/js/web/addr/utils.js
@@ -0,0 +1,24 @@
+
+
+$(document).ready(function(){
+
+	
+	
+}); 
+
+/*
+ * @discription 타블레이터 객체 가져오기
+ * */
+function fn_utils_getTabulator(){
+
+    var activeTab = $('#tbTabl .tab.active');
+    // data-tabul 값 가져오기
+    var tabulValue = activeTab.data('tabul');
+    console.log('tabulValue : ',tabulValue);
+	
+	return window['$' + tabulValue]; 
+}
+
+function fn_utils_isEmpty(obj){
+	return obj == null || obj == "";
+}(No newline at end of file)
Add a comment
List