티스토리 뷰

지금 내가 하는 일
엑셀파일을 첨부한다.
엑셀파일을 읽어온다.
읽어서 리스트에 담는다.
리스트의 데이터를 AD에 보내고 DB에 보내 추가한다.


이 작업을 진행하는 프로그래스바를 생성해야한다.


파일 업로드 progress bar 검색해보니 많이 나온다. 플러그인이.
그래서 적용해보았다.
그런데 파일 업로드 progress bar여서 나는 첨부파일을 받아오는 순간 프로그래스바가 끝난다.


내가 원하는 progress bar는 파일을 업로드 하는 것 뿐 아니라 추가하는 과정까지 원하는 것.
고민하다가
사용자가 원하는건 엑셀이 추가 되는 과정?을 보고싶어하는 것이므로
리스트에 담긴 데이터를 추가해주면서 그 추가 과정을 progress bar 로 보여주기로 했다.


그래서 제일 먼저 한것은.

 

1.

리스트에 담긴 엑셀 파일을 추가하는 service 부분에서 static 으로
전체 행의 갯수, 데이터 추가가 성공할때 count, 실패할때 count, 데이터가 중복일때 count,
데이터가 null 또는 " " 일때 count들을 가져올 수 있는 변수를 선언해주었고 그 변수들에 대한
Getter/Setter를 만들어주었다. (잘은 모르지만 VO를 따로만들지 않은 그런것인가?)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
    private static int totalRowCount = 0// 전체 행 개수
    private static int successRowCount = 0// 성공한 데이터 개수
    private static int failRowCount = 0// 실패한 데이터 개수
    private static int nullRowCount = 0// 읽을 수 없는 데이터(null) 개수
    private static int doubleRowCount = 0;// 중복된 데이터 개수
    
    private static int currentStateCount = 0
    //위의 4개 변수들을 다 더한 값이다. 
    //for문이 돌면서 현재 몇개가 처리되었는지 알게 해주는 변수
    private static String currentState; //현재 상태 
 
    public static int getTotalRowCount() {
        return totalRowCount;
    }
 
    public static void setTotalRowCount(int totalRowCount) {
        ModuleServiceImpl.totalRowCount = totalRowCount;
    }
 
    public static int getSuccessRowCount() {
        return successRowCount;
    }
 
    public static void setSuccessRowCount(int successRowCount) {
        ModuleServiceImpl.successRowCount = successRowCount;
    }
 
    public static int getFailRowCount() {
        return failRowCount;
    }
 
    public static void setFailRowCount(int failRowCount) {
        ModuleServiceImpl.failRowCount = failRowCount;
    }
 
    public static int getNullRowCount() {
        return nullRowCount;
    }
 
    public static void setNullRowCount(int nullRowCount) {
        ModuleServiceImpl.nullRowCount = nullRowCount;
    }
 
    public static int getDoubleRowCount() {
        return doubleRowCount;
    }
 
    public static void setDoubleRowCount(int doubleRowCount) {
        ModuleServiceImpl.doubleRowCount = doubleRowCount;
    }
 
    public static String getCurrentState() {
        return currentState;
    }
 
    public static void setCurrentState(String currentState) {
        ModuleServiceImpl.currentState = currentState;
    }
 
    public static int getCurrentStateCount() {
        return currentStateCount;
    }
 
    public static void setCurrentStateCount(int currentStateCount) {
        ModuleServiceImpl.currentStateCount = currentStateCount;
    }
cs



2.

그리고 service 부분에서 변수들을 적절히 활용해주었다.(하하)
엑셀을 읽어오기 전 상태(currentState)를 A로 set 해주고
엑셀을 읽어와서 전체 행 개수를 가지고 오게 되면 상태를 B로 변경해준다.
상태를 변경해 주는 이유는 progress바의 실행이 파일을 업로드 하고 엑셀을 읽어온 후에,
그러니까 추가가 되는 동안에 실행되도록 하기 위함이다.
그리고 for문을 다 돌아서 전체 행 개수(totalRowCount)와 읽은 데이터개수(=현재 상태 개수 currentStateCount)가
같을 때 상태를 C로 set 해주었는데(이거의 용도는 딱히 없음)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
public void excelUpload(File destFile, MultipartHttpServletRequest request) throws Exception {
 
        ExcelReadOption excelReadOption = new ExcelReadOption();
        excelReadOption.setFilePath(destFile.getAbsolutePath());
        excelReadOption.setOutputColumns("A""B""C""D""E""F""G");
        excelReadOption.setStartRow(2);
 
        setCurrentState("A"); // 엑셀파일 읽어 오기 전 상태를 A
 
        List<Map<StringString>> excelContent = ExcelRead.read(excelReadOption);
 
        totalRowCount = excelContent.size();
 
        if (totalRowCount > 0) {
            setCurrentState("B");
 
            for (Map<StringString> article : excelContent) {
 
                // excel 안에 비어있는 셀 확인(id 데이터가 없으면 다음행으로 건너뛰기)
                if (article.get("C"== null | article.get("C"== "") {
 
                    nullRowCount++;
                    currentStateCount++;
 
                    continue;
                } else {
 
                    /* Id 중복확인 */
                    int cnt = 0;
                    UserSession mySession = sessionUtil.getAdminSession(request);
                    cnt = userService.countUserByUserIdAndTenantId(article.get("C"), mySession.getTenantId());
                    if (cnt > 0) {
                        // DB에 같은 아이디가 있으면 다음 행으로 간다. AD 추가 안함
                        System.out.println("이미 사용자가 있습니다");
 
                        doubleRowCount++;
                        currentStateCount++;
                        continue;
 
                    } else {
                        // 사용가능한 아이디 이므로 계속 입력
                        /* DeptDN 가져오는 부분 (AD에 사용) */
                        String groupDeptName = "";
                        int groupId = Integer.parseInt(article.get("A"));
                        groupDeptName = groupHelper.selectGroupDistinguishedNameByGroupOriginalId(groupId);
 
                        /* GroupFullName 가져오기 (DB에 사용) */
                        String groupFullName = "";
                        groupFullName = groupHelper.selectGroupFullNameByGroupId(groupId);
 
                        ADUserInfoVO adUserInfo = new ADUserInfoVO(); // AD
                        User user = new User(); // Ovirt,DB
 
                        adUserInfo.setJob("createUser");
                        adUserInfo.setDeptDN(groupDeptName); // DeptDN (AD)
                        adUserInfo.setDisplayName(article.get("B")); // 사용자 이름
                                                                        // (AD)
 
                        adUserInfo.setUserName(article.get("C")); // 사용자 아이디
                                                                    // (AD)
 
                        int PositionExist = userHelpler.selectPositionExist();
                        if (PositionExist > 0) {
                            // 데이터가 있는것, 그럼 setPositionYn = Y
                            // 직급 코드가 들어가면 그 코드를 DB에서 읽어와서 이름을 AD에 넣어주어야 한다.
                            String userPositionName = "";
                            userPositionName = userHelpler.selectUserPosition(article.get("D"));
                            adUserInfo.setPosition(userPositionName); // 직급 코드로 가져온 직급 이름을 넣는다.(AD)
 
                            user.setPositionYn('Y'); // (DB)
                            user.setPositionCode(article.get("D")); // DB 직급 코드(DB)
 
                        } else {
                            // 데이터가 없는것, 그럼 setPositionYn = N
                            adUserInfo.setPosition(article.get("E")); // 직급 이름(AD)
 
                            user.setPositionYn('N'); // (DB)
                            user.setPositionName(article.get("E")); // DB 직급이름(DB)
                        }
 
                        adUserInfo.setEMail(article.get("F")); // 이메일 주소 (AD)
                        adUserInfo.setCellPhone(article.get("G")); // 핸드폰 번호 (AD)
                        adUserInfo.setMustChangeYN("Y"); // 비밀번호 변경여부 (default: Y로 처음 로그인시 변경 필수) (AD)
 
                        userService.AdUser(adUserInfo); // AD에 사용자 추가
 
                        Thread.sleep(3000);
 
                        user.setUserId(article.get("C")); // 사용자 아이디 (DB)
                        user.setUserName(article.get("B")); // 사용자 이름 (DB)
                        user.setEmail(article.get("F")); // 이메일 주소 (DB)
 
                        // DB등록을 위한 RegId, TenantId 설정
                        user.setRegId(mySession.getUserId());
                        user.setTenantId(mySession.getTenantId());
 
                        userService.createUser(groupId, groupFullName, null"fusiontest.dom", user); // ovirt-engine,DB에 사용자 추가 
 
                        successRowCount++;
                        currentStateCount++;
 
                    }
                }
            }
 
        } else {
 
        }
        if (totalRowCount == currentStateCount) {
            setCurrentState("C");
        }
 
    }
cs


3.

이제 jsp 파일로 가서 progress bar 하고 %가 보이는 영역을 설정하자.
첨부파일 추가한 부분 아래에 선언 해 주었다.
progress는 상태 바 이고, excelUploadingState는 %이다.

추가 버튼을 누르면 check()함수로 이동하는데
check 함수에 progress 를 보여주도록 소스를 수정한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div class="module_01">
    <dt class="down_5 w190">사용자 추가</dt>
        <dd class="w425">
            <div class="upload_form_cont">
                <form id="excelUploadForm" name="excelUploadForm" enctype="multipart/form-data" method="post" action"${pageContext.request.contextPath}/module/excelUploadAjax">
                    <input type="hidden" id="ftpUploadState" name="ftpUploadState" value="" />                        
                        <div>                        
                            <input type="file" name="excelFile" id="excelFile" class="w350" />                                                         
                            <button type="button" id="addExcelImpoartBtn" class="btn input_btn_03" onclick="check()">추가</button>
                        </div>
                    <!-- progress bar -->
                        <div id="progress_info" class="progress_info">
                            <div id="progress" class="progress"></div>
                            <p id"excelUploadingState" class="excelUploadingState"></p>
                        </div>                                                        
                </form>
            </div
        </dd>
    </dl>
</div>
cs



4.

스크립트 소스다.
읽어보면 몬소린지 알듯 

check() 함수 위에 var progress 를 선언해 준 것은 
setInterval 준것을 성공시에 clearInterval 해주기 위함이다.

버튼을 클릭하여 추가하면 초기 progressbar 는 0이고 %도 0에서
beforeSend에서 excelUploadProgress 를 계속적으로 호출하면서 bar의 길이와 %를 
success 되어 width값이 365px %값이 100이 될 때 까지 늘려준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
            var progress;                 
            function check() {
                var file = $("#excelFile").val();
                if (file == "" || file == null) {
                    alert("파일을 선택해주세요.");
                    $("#excelFile").click();
                    return false;
                } else if (!checkFileType(file)) {
                    alert("엑셀 파일만 업로드 가능합니다.");
                    $("#excelFile").click();
                    return false;
                }
                
                var Progressbar = document.getElementById('progress');
                Progressbar.style.display= 'block';
                Progressbar.style.width ='0px';
                
                $("#excelUploadForm").ajaxForm({
                    beforeSend: function(){
                        $("#excelUploadingState").html("<font size = 3><b>0% </b></font>");
                        
                        progress = setInterval(excelUploadProgress, 50);
                        
                    },
                    success: function() {
                        document.getElementById('progress').style.width = '365px';
                        $("#excelUploadingState").html("<font size = 3><b>100% </b></font>");
                        
                        clearInterval(progress);                    
                        
                        excelUploadProgressClear();
                        //location.reload();
                    },
                    error: function(){
                        alert("에러가 발생하였습니다.");
                        clearInterval(progress);    
                        //location.reload();
                        //에러 발생시 소스를 넣는다.
                    }
                }); 
                    $("#excelUploadForm").submit();
                   
            }
cs



5.

setInterval 으로 excelUploadProgress를 호출한다.
여기서 ajax를 호출하여 progressbar 하고 %의 숫자가 늘어나게 한다.
resultData를 받아오는데 controller로 이동하여 설명해야지.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function excelUploadProgress(){
                //count를 0으로 초기화 해야하는가?
                $.ajax({
                    type: "post",
                    url: "${pageContext.request.contextPath}/module/excelUploadProgress",
                    data: {},
                    dataType :"text",
                    success : function(resultData){
//                         console.log(resultData);
                        if(resultData == 100){
                            clearInterval(progress);    
                        }
                        $("#excelUploadingState").html("<font size = 3><b>"+ resultData +"% </b></font>");
                        document.getElementById('progress').style.width = (resultData*3.65).toString() +'px';
                    },
                    error: function(e){
                        
                    }
                });                        
            }
cs


6.

ajax로 excelUploadProgress를 호출한다.
controller로 간다.
이곳에서 resultData를 결과로 보내는데
이 resultData는 serviceImpl에서 엑셀 파일 읽어서 추가할 때 count 설정해준 그 count값들을 가져온다.
BigDecimal 같은 저것은 무엇인가(도움을 받아 잘모르겠음) 
다시 한번 정리하는 걸로

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@ResponseBody
    @RequestMapping(value = "/excelUploadProgress", method = RequestMethod.POST)
    public String excelUploadProgress(HttpServletRequest request) throws Exception {
        int resultData = 0;
        
        if(ModuleServiceImpl.getCurrentState()=="B"){
            int a =ModuleServiceImpl.getCurrentStateCount();
            int b =ModuleServiceImpl.getTotalRowCount();
            //ModuleServiceImpl.getCurrentStateCount()/ModuleServiceImpl.getTotalRowCount()*100
            logger.error("a>>>>>>>>>>"+a);
            logger.error("b>>>>>>>>>>"+b);
            
            
            BigDecimal aGd = new BigDecimal(a);
            BigDecimal bGd = new BigDecimal(b);
            
        
            resultData = aGd.divide(bGd, 2, BigDecimal.ROUND_CEILING).multiply(new BigDecimal(100)).intValue();
        }
        
        logger.error("resultData>>>>>>>>>>"+resultData);
        
        return Integer.toString(resultData);
    }
cs


7.

성공하면 clearInterval로 setInterval을 중지시키고
excelUploadProgressClear()를 호출해서 count 값들을 초기화 시켜준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function excelUploadProgressClear(){
                
                $.ajax({
                    type: "post",
                    url: "${pageContext.request.contextPath}/module/excelUploadProgressClear",
                    data: {},
                    dataType :"text",
                    success : function(resultData){
                        alert("데이터가 업로드 되었습니다.");
                    },
                    error: function(e){
                        
                    }
                });        
            }
cs


8.

excelUploadProgressClear ajax 호출하면 오는 controller이다.
count 변수들을 모두 0으로 다시 초기화 해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    @ResponseBody
    @RequestMapping(value = "/excelUploadProgressClear", method = {RequestMethod.GET, RequestMethod.POST})
    public ModelAndView excelUploadProgressClear(ModelAndView mav, HttpServletRequest request, HttpServletResponse response) throws Exception {
    
        ModuleServiceImpl.setCurrentStateCount(0);
        ModuleServiceImpl.setTotalRowCount(0);
        ModuleServiceImpl.setSuccessRowCount(0);
        ModuleServiceImpl.setFailRowCount(0);
        ModuleServiceImpl.setNullRowCount(0);
        ModuleServiceImpl.setDoubleRowCount(0);
        ModuleServiceImpl.setCurrentState(null);
        
        return null;
    }
cs



그러하면

progressbar가 업로드 할때 실행된다.




댓글