시스템아 미안해

java 엑셀 업로드(json으로 변환해서 jsp로 가져오기) 본문

java/문법

java 엑셀 업로드(json으로 변환해서 jsp로 가져오기)

if else 2023. 1. 13. 13:32

본인이 넘길 form값들에 name을 주고 ajax에서 formData객체로 넘긴다.

 

 

 

var form = $("#frm")[0];
var formData = new FormData(form); 

	$.ajax({
        method : 'POST', 
        url: '../settle/xlsUploadLoad',
        data : formData,
        dataType : 'json',
        contentType : false,
        processData : false,
        beforeSubmit: function(){
            $('button').prop('disabled',true);
	}

파일 객체도 같이 들어있기 때문에 contentType과 processData를 false로 설정, 

jsonArray안의 jsonObject를 반환받을 예정이라 dataType은 json으로 설정한다.

 

 

 

 

 

[controller]

@PostMapping(value="/xlsUploadLoad")
@ResponseBody
public JSONArray xlsUploadLoad( @RequestParam(value="yy", required = false, defaultValue = "0000")String strYear,
				@RequestParam(value="f", required = false, defaultValue = "")String strFlag,
				MultipartHttpServletRequest mpReq ) throws Exception {

		
		log.debug("=======================xlsUploadLoad=======================");
		
		JSONArray jsonArr = FileUtil.xlsUploadLoad(strFlag, strYear, mpReq);
		
		return jsonArr;
}

json을 반환할 controller는 @responseBody 어노테이션으로 명시해주고, 

FileUtil객체에서 바로 jsonArray를 return했다.

 

 

 

 

[FileUtil]

private static final String path = ApplicationProperty.getFilePath();
    
    public static JSONArray xlsUploadLoad(String strFlag, 
					String strYear,
					MultipartHttpServletRequest mpReq) throws Exception {
		
		String uploadPath = path + ApplicationProperty.getExcelFolder();
		
		File file = new File(uploadPath);
		
		verifyUploadPath(uploadPath);
		
		MultipartFile mpFile = mpReq.getFile("xls");
			
		String fileName = mpFile.getOriginalFilename();
		String fileExtension = fileName.substring(fileName.lastIndexOf("."));
		String storedFileName = getRandomString() + fileExtension;
		
		file = new File(uploadPath, storedFileName);
		
		//경로에 저장
		mpFile.transferTo(file);
		
		FileInputStream excelFile = new FileInputStream(uploadPath + storedFileName);
		
		JSONArray jsonArr = ExcelParser.excelToJsonArr(excelFile, strFlag, fileExtension);
		
		return jsonArr;
	}
    
    
     private static void verifyUploadPath(String path) {

        if (!new File(path).exists()) {
            try {
                new File(path).mkdir();
            } catch (Exception e) {
                e.getStackTrace();
            }
        }
    }

application.properties에 저장해놓은 경로값을 ApplicationProperty bean과 연결했기 때문에

해당하는 변수를 getter로 불러들이면 properties의 path를 부를 수 있다. 

verifyUploadPath 메소드에서 만약 path에 해당하는 파일이 없으면 폴더를 생성하고, 파일을 저장한 후 

ExcelParser객체에서 엑셀 파싱한 값을 jsonArray로 받는다. 

 

 

 

 

 

 

[ExcelParser]

public class ExcelParser {

	public static JSONArray excelToJsonArr(FileInputStream excelFile, String strFlag, String fileExtension) {
		
		  JSONArray jsonArray = new JSONArray();
		  
	        
        try{

            Workbook workbook =  WorkbookFactory.create(excelFile);

            Sheet sheet = workbook.getSheetAt(0);
            //행의 개수 
            int rownum = sheet.getLastRowNum();


            //첫 행은 컬럼명이므로 두번째 행인 index1부터 읽기
            for(int rowIndex=1;rowIndex<=rownum;rowIndex++){

                //현재 index의 행 읽기
                Row currentRow = sheet.getRow(rowIndex);

                // 열이 비어있으면  다음 행으로 넘어감
                if(currentRow == null || currentRow.getCell(0).getStringCellValue().equals("")) break; 

                ///현재 행의 cell 개수
                int cellnum = currentRow.getLastCellNum();

                //엑셀 데이터를 넣을 json object
                JSONObject data = new JSONObject();

                int idx = 1;
                data.put("No", idx);

                for(int cellIndex =0; cellIndex<cellnum;cellIndex++){

                    System.out.println(rowIndex+"행 "+cellIndex+"열의 값 : " + currentRow.getCell(cellIndex));

                    if("WR".equals(strFlag)) {//우리카드

                        switch(cellIndex){

                            case 0 : {    //이용일자
                                data.put("dateUse",currentRow.getCell(cellIndex).getStringCellValue());
                            };break;
                            case 2 : {    //승인번호
                                data.put("strApprovalNum",currentRow.getCell(cellIndex).getStringCellValue());
                            };break;
                            case 3 : {    //이용카드
                                data.put("strUseCardNum",currentRow.getCell(cellIndex).getStringCellValue());
                            }break;
                            case 5 : {    //이용가맹점명
                                data.put("strStore",currentRow.getCell(cellIndex).getStringCellValue());
                            }break;
                            case 9 : {    //사업자번호
                                data.put("strCorpNum",currentRow.getCell(cellIndex).getStringCellValue());
                            }break;
                            case 16 : {    //승인금액
                                data.put("moneySale",currentRow.getCell(cellIndex).getNumericCellValue());
                            }break;
                        }
                    }else if("SH".equals(strFlag)) {//신한카드

                            String dateUse = null;

                            switch(cellIndex){

                            case 6 : {    //이용일자
                                dateUse = currentRow.getCell(cellIndex).getStringCellValue().replace(".", "-");
                            };break;
                            case 7 : {    //이용일자 + 이용시간
                                String time = currentRow.getCell(cellIndex).getStringCellValue();

                                if(time == null || "".equals(time)) {
                                    data.put("dateUse",dateUse + "00:00:00");
                                }else {
                                    data.put("dataUse",dateUse + currentRow.getCell(cellIndex).getStringCellValue());
                                }
                            };break;
                            case 5 : {  //승인번호
                                data.put("strApprovalNum",currentRow.getCell(cellIndex).getStringCellValue());
                            }break;
                            case 4 : {    //이용카드
                                data.put("strUseCardNum",currentRow.getCell(cellIndex).getStringCellValue());
                            }break;
                            case 19 : {    //이용가맹점
                                data.put("strStore",currentRow.getCell(cellIndex).getStringCellValue());
                            }break;
                            case 18 : {    //사업자번호
                                data.put("strCorpNum",currentRow.getCell(cellIndex).getStringCellValue());
                            }break;
                            case 9 : {    //승인금액
                                data.put("moneySale",currentRow.getCell(cellIndex).getNumericCellValue());
                            }break;
                        }
                    }
                }

                ++idx;
                jsonArray.add(data);
            }

            return jsonArray;

        }catch(Exception e){
            System.out.println("ERROR : "  + e);
            return jsonArray;
        }
		
	}
}

엑셀을 파싱할때 주의할 점은 XSSFWorkbook, HSSFWorkbook, workbook객체의 사용 차이이다. 

XSSFWorkbook : xlsx파싱 

HSSFWorkbook : xls파싱 

어떤 엑셀 파일이 들어올 지 모르기 때문에 workbook객체를 사용했더니 모두 파싱이 됐다.

+ 정수는 getStringCellValue > string으로 파싱하지만

소수점이 포함된 숫자는 getNumericCellValue로 파싱해주어야 한다. 

매 행마다 jsonObject에 data를 넣어주고, 가장 마지막에 jsonArray에 jsonObject를 넣은 후 return.

 

 

 

 

 

[jsp]

success: function(json){

$.each(json,function(e){
    
    const row = $(this)[0];
    
    row.dateUse
    
    }
}

jsonArray를 each로 하나씩 읽어들이고, $(this)[0] 을 출력해보면 엑셀 한 행의 data가 담겨있는 jsonObject가 찍힌다. 

 

 

jsonObject의 key값이 dateUse라면 $(this)[0].dateUse로 값을 배치할 수 있다.