Terry Very Good

[javascript] base64형태로 file DB upload download 하는 모든 것(modal창의 input tag로 업로드후, 다운로드 버튼 클릭해도 새로고침되지 않음) 본문

프로그래밍/(WEB) JAVA Spring Jquery

[javascript] base64형태로 file DB upload download 하는 모든 것(modal창의 input tag로 업로드후, 다운로드 버튼 클릭해도 새로고침되지 않음)

테리베리 2023. 7. 20. 09:31
728x90
반응형

input tag로 파일을 불러와서 base64형태로 변환하여 DB로 올리고, DB에 올린 파일을 가져와서 다운로드 버튼을 누르면 다운받아지는 형태로 구현했다. 

<div class="form-group">
    <label for="exampleInputFile2" style="font-weight: bold; font-size: small;">서류등록</label>
    <div class="input-group">
        <div class="input-group">
            <input type="file" id="exampleInputFile2" class="form-control" onchange="readFile2(this, console.log)">
            <button id="downloadClick2" class="btn btn-outline-secondary" >다운로드</button>
            <script>
                function readFile2(FILE_ELEMENT, CALLBACK)
                {
                    // editEmployeeModal2
                    var file = $("#editEmployeeModal2 #exampleInputFile2")[0].files[0];
                    var filename = file.name;
                    var READER = new FileReader();
                    READER.onload = function (e) 
                    {
                        var base64data = READER.result;
                        //  base64data = btoa(base64data);
                        $('#editEmployeeModal2 #downloadClick2')[0].value = base64data;
                        alert(base64data);
                    }
                    //READER.readAsText(FILE_ELEMENT.files[0], "EUC-KR");
                    READER.readAsDataURL(file);
                } 
            
                $('#editEmployeeModal2 #downloadClick2').on('click', function(event) {
                    event.preventDefault(); // 기본 동작(새로고침) 막기

                    // 이하 코드는 이전과 동일
                    var file = $("#editEmployeeModal2 #exampleInputFile2")[0].files[0];
                    var filename = file.name;
                    var reader = new FileReader();

                    reader.onload = function(e) {
                        var base64data = e.target.result;

                        // AJAX 요청을 통해 파일 데이터를 가져옴
                        $.ajax({
                            url: base64data, // 파일 데이터를 가져올 URL
                            method: 'GET',
                            xhrFields: {
                                responseType: 'blob' // 파일 데이터를 Blob 형태로 받아옴
                            },
                            success: function(blobData) {
                                // Blob 데이터를 가지고 다운로드 링크 생성
                                var blobUrl = URL.createObjectURL(blobData);
                                var link = document.createElement('a');
                                link.href = blobUrl;
                                link.download = filename;
                                document.body.appendChild(link);
                                link.click();
                            },
                            error: function(xhr, status, error) {
                                console.error('Error while fetching file data:', error);
                            }
                        });
                    }

                    reader.readAsDataURL(file);
                });


            </script>
        </div>
    </div>
</div>

 

DB로 올릴 때에는, 수정버튼 클릭 시 값을 받아와서 등록하도록 만들었고, base64로 변환된 텍스트는 download 쪽에 입력되도록 만들었다.

        // 수정 버튼 클릭 시
        $("#edit-employee").on('click', function() {
        
            const exampleInputFile = $("#editEmployeeModal2 #exampleInputFile2").val();
            const exampleInputFilebase = $("#editEmployeeModal2 #downloadClick2").val();
            $.ajax({
                    //url: "/employee/updateEmployeeInfo",
                    url: "http://localhost:8080/employee/updateEmployeeInfo",
                    method: "POST",
                    beforeSend: function (xhr) {
                        xhr.setRequestHeader('Authorization', `Bearer ${token}`);
                    },
                    contentType:"application/json",
                    data: JSON.stringify({ 등등 exampleInputFile,exampleInputFilebase 등등 }),
                    success: function(xhr) {
                        // hide modal
                        $("#editEmployeeModal2").modal('toggle');
                        // datatable reload
                        // const table = $("#employee-table").DataTable();
                        // 사원정보 테이블 리로드
                        employeeTable.ajax.reload();
                    },
                    error:function(xhr) {
                        console.log(`error!!!`);
                    },
                    complete:function(xhr) {
                        console.log(`complete!!!`);
                    }
                })
            }
        });

 

 

DB에 있는 data를 가져와서 modal창에 보여주는 코드는 아래와 같다.

        //jquery datatable의 한 행을 클릭할 경우 모달창이 뜬다
        $('#employee-table tbody').on('click', 'tr', function () {
            var idx = $("#employee-table").DataTable().row(this).data().seq;
            console.log('idx'+idx);
            
                // console.log(`idx --> ${idx}`);
                if (idx === undefined) {
                    alert(`선택을 먼저 하시기 바랍니다.`);
                    return;
                }
                
            
            $("#editEmployeeModal2 #this_seq2").val(idx);
            
            
                for (var i = 0; i < serverData.length; i++) {
                    if (idx === serverData[i].seq) {
                        console.log("Index matches at row: " + i);
                        idx = i;
                        break; // 매치하는 행을 찾으면 반복문 종료
                    }
                }
    
                // 수정 모달 팝업
                $('#editEmployeeModal2').modal('toggle');
            
            
      
                
                //사진 올리기
                var base64Data = serverData[idx].exampleInputFilebase; // Base64로 인코딩된 사진 데이터
                console.log("base64Data:"+base64Data);
                var filename = serverData[idx].exampleInputFile; // 파일 이름
                console.log("filename:"+filename);
                if((base64Data !== undefined && base64Data !== null) ? base64Data.includes(",") : false)
                {
                    var arr = base64Data.split(',');
                    var mime = arr[0].match(/:(.*?);/)[1];
                    var bstr = atob(arr[1]);
                    var n = bstr.length;
                    var u8arr = new Uint8Array(n);
    
                    while(n--){
                        u8arr[n] = bstr.charCodeAt(n);
                    }
            
                    var file = new File([u8arr], filename, { type: mime });
                    var fileInput = $('#editEmployeeModal2 #exampleInputFile2')[0]; // input 요소를 가져올 때 인덱스 0을 사용하여 JavaScript 객체로 변환
                    var dataTransfer = new DataTransfer();
                    dataTransfer.items.add(file);
            
                    fileInput.files = dataTransfer.files;
                }
                else
                {
                    //첨부파일 없으면
                    $('#editEmployeeModal2 #exampleInputFile2').val("");
                    console.log("첨부파일 없음(base64Data데이터 반영x)");
                }
                
                
    
        });
728x90
반응형