-
[excel upload] apache POI를 사용하여 사용자가 업로드한 엑셀파일 읽어오기 / controller에서 엑셀 파일을 읽는 중 오류발생회사/사내개발 2020. 10. 28. 17:31
심각: Servlet.service() for servlet [appServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: invalid code lengths set] with root cause java.util.zip.ZipException: invalid code lengths set at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:164) at java.util.zip.ZipInputStream.read(ZipInputStream.java:194) at java.io.FilterInputStream.read(FilterInputStream.java:107)
java.util.zip.ZipException: invalid code lengths set
* 현재 개발한 로직
사용자가 형식에 맞춰 엑셀을 업로드 하면 해당 엑셀 파일을 읽어 서버단 dto 데이터 형식에 맞게 변환하여 리턴
"ajax excel upload" 라는 키워드로 검색하면 너무나도 많은 예제가 있다.
예제를 보고 적용하는데 계속 위에 언급한 오류가 나는 것이다.
난 오늘 이 오류때문에 퇴근을 못할 뻔했다 ..
-----해결 직후 분노해서 일이 안돼서 블로그 끄적끄적-----
이유는 내가 업로드 한 엑셀 파일이 깨진 거였다......
디버깅 해보니
InputStream is = new FileInputStream(finalFilePath);
workbook = new XSSFWorkbook(is); //여기서 오류발생workbook을 생성할 때 오류가 발생하는데 그게 업로드된 파일 자체의 문제일꺼라곤 생각을 못했다..
그저 서버에서 파일을 전달받을 때 형식이 맞지 않아서 또는 파일을 inputStream으로 읽어오는 데에서 오류가 나서
정상동작하지 않는다고 생각을 했다 ㅠㅠ
앞으로는 소스상의 문제만 생각하지 않고 리소스, 테스트파일도 잘 확인 하는걸로 스스로 약속 ㅎㅎㅎ
* 소스코드
1. html
<form id="excelUploadForm" name="excelUploadForm" enctype="multipart/form-data" method="post" action= "/common/sms/read_excel"> <div class="filebox"> <input class="upload-name" value="파일선택" readOnly style="width:60%;cursor:pointer;"/> <!-- 파일선택박스 --> <label for="ex_filename" style="display:none;" ><!-- 번호일괄등록 --></label> <input style="display:none;" type="file" name="excelFile" id="ex_filename" class="upload-hidden" accept=".xlsx"> <!-- 파일등록박스 --> <label class="btn-regist" id="btn-bundle-regist">번호일괄등록</label> </div> </form>
2. js
$( "#btn-bundle-regist" ).on( "click", function() { $("#excelUploadForm").ajaxSubmit( { success : function(data) { if( !$.isArray( data ) || data.length == 0 ) { alert( "추가된 사용자가 없습니다." ); return; } if( data ) { alert("수신자번호 추가가 완료되었습니다."); } else { alert("데이터 업로드에 실패하였습니다. 잠시 후 다시 시도해 주세요."); } } ,type : "POST" // ,async : false ,error: function (e) { console.log("ERROR : ", e); } } ); } );
3. controller
@RequestMapping(value = "/sms/read_excel", method = RequestMethod.POST) @ResponseBody public List<DeptEmpDto> excelUploadAjax( @RequestParam("excelFile") MultipartFile excelFile ) throws Exception { if (excelFile == null || excelFile.isEmpty()) { throw new RuntimeException("엑셀파일을 선택 해 주세요."); } String extension = FilenameUtils.getExtension(excelFile.getOriginalFilename()); if (!extension.equals("xlsx")) { throw new IOException("등록된 양식에 엑셀파일만 업로드 해주세요."); } // 해당경로를 실제 경로로... String finalFilePath = "D:\\" + excelFile.getOriginalFilename(); File destFile = new File(finalFilePath); try { excelFile.transferTo(destFile); } catch (IllegalStateException | IOException e) { throw new RuntimeException(e.getMessage(), e); } Workbook workbook = null; if ( extension.equals("xlsx") ) { InputStream is = new FileInputStream(finalFilePath); workbook = new XSSFWorkbook(is); } Sheet worksheet = workbook.getSheetAt(0); List<DeptEmpDto> list = new ArrayList<DeptEmpDto>(); // 0~3까지는 사용자 인풋값이 아님 for (int i = 4; i <= worksheet.getPhysicalNumberOfRows(); i++) { // 4 Row row = worksheet.getRow(i); DeptEmpDto dto = new DeptEmpDto(); if (row.getCell(1) != null) { dto.setEmp_nm(row.getCell(1).getStringCellValue()); } // 번호는 필수입력사항입니다. 필수입력사항이 입력되었을 때만 list에 add if (row.getCell(2) != null) { String cellPhone = row.getCell(2).getStringCellValue(); cellPhone.replaceAll( "-", "" ); dto.setCell_phone( cellPhone ); list.add(dto); } } // 임시저장 삭제 /** * @TODO test 해야함 !! */ destFile.delete(); return list; }
테스트 완료된 후 controller의 소스는 service로 분리하였다.
비지니스로직은 서비스로~~
'회사 > 사내개발' 카테고리의 다른 글
mssql @과 #로 시작하는 임시테이블 차이 (0) 2021.01.26 intellij에서 git소스를 가져온 후 gradle build 가 되지 않을 때, run application이 정상적으로 되지 않을 때 (0) 2020.10.22 [pinpoint] 자바메모리(java memory) 사용, java out of memory (?) (0) 2020.10.21 [mssql] 대괄호 텍스트검색 (0) 2020.10.20 [mssql] WHERE DELETE_FLAG <> 'Y' 결과가 제대로 나오지 않을 때 (0) 2020.10.18