POI 엑셀 업로드

Hanbyul·2023년 11월 28일

Java

목록 보기
18/23
@RequestMapping(value = "/uploadExcel", method = RequestMethod.POST)

-> 클라이언트가 "/uploadExcel" URL로 POST 요청을 보내면 이 메서드가 호출.


public String uplodadExcel(
				@RequestParam("file") MultipartFile file, 
                Model model) throws IOException

-> 클라이언트가 보낸 파일을 받아서 처리하며, 오류가 발생하면 해당 오류를 Model에 담아서 반환.


Workbook workbook = new XSSFWorkbook(file.getInputStream());

-> 엑셀 파일을 읽어서 Workbook 객체를 생성.


Sheet sheetList = workbook.getSheetAt(0);

-> Workbook에서 첫 번째 시트를 가져옴.


for (Row row : sheetList)

-> 시트의 각 행에 대해 반복.


if(row.getRowNum() == 0) { 
	continue; 
    }

-> 첫 번째 행(헤더)는 건너뜀.


Cell noCell = row.getCell(0);

-> 각 행에서 첫 번째 셀(번호)를 가져옴.


if (noCell == null || noCell.getCellType() == Cell.CELL_TYPE_BLANK) { 
	no = 0; 
	}
    
-> 번호 셀이 비어있으면 번호를 0으로 설정.


else if (noCell.getCellType() == Cell.CELL_TYPE_NUMERIC) { 
	no = (int) noCell.getNumericCellValue(); 
    }

-> 번호 셀이 숫자 유형이면 해당 숫자를 가져옴.
비슷한 방식으로 다른 셀들(제목, 작성자, 내용, 조회수)의 값을 가져옴.


(writedateCell.getCellType() == Cell.CELL_TYPE_NUMERIC 
&& DateUtil.isCellDateFormatted(writedateCell)) 

->  DateUtil은 Apache POI 라이브러리의 DateUtil 클래스에 있는 메서드임. 이 메서드는 주어진 셀이 날짜 형식으로 포맷되어 있는지 확인함. 엑셀 셀에는 숫자, 문자열 등 다양한 형식이 있을 수 있지만, 그 중에서도 날짜로 표현된 셀은 특별한 형식을 갖게됨. 이 메서드는 주어진 셀이 날짜 형식으로 저장되었는지 여부를 체크하여 true 또는 false를 반환.


writedate = convertToLocalDateTimeViaInstant(writedateCell.getDateCellValue());

-> convertToLocalDateTimeViaInstant() 부분은 
주어진 셀의 날짜 값을 java.util.Date 객체로부터 
java.time.LocalDateTime 객체로 변환하는 역할을 수행함. 
이 메서드는 보통 java.util.Date 객체를 
java.time.LocalDateTime 객체로 변환하는 방법 중 하나임. 
자바 8 이후에는 java.time 패키지가 도입되었고, 
LocalDateTime은 날짜와 시간 정보를 포함하는 객체임. 
그러나 엑셀에서 읽어온 값은 주로 java.util.Date 객체로 표현. 
따라서 날짜 값을 java.util.Date에서 java.time.LocalDateTime으로
변환하는 작업이 필요할 때 이러한 메서드들이 사용.


boardService.savePost(title, content, writer, null);

-> 가져온 값을 서비스 메서드를 통해 데이터베이스에 저장.


workbook.close();

->엑셀 파일을 닫음.

} catch (IllegalStateException e) { 
	model.addAttribute("errorMessage", e.getMessage()); 
    return "error/error"; 
    }

-> 만약 중간에 오류가 발생하면 해당 오류 메시지를 Model에 담아서 오류 페이지로 이동.


return "redirect:/board";

->처리가 모두 끝나면 "/board" 페이지로 리다이렉트.


전체코드
	@RequestMapping(value = "/uploadExcel", method = RequestMethod.POST)
	public String uplodadExcel(@RequestParam("file") MultipartFile file, Model model) throws IOException {
		// 엑셀 파일을 읽어오기 위해 워크북 생성
		Workbook workbook = new XSSFWorkbook(file.getInputStream());
		
		// 첫번째 시트 가져오기
		Sheet sheetList = workbook.getSheetAt(0);
		
		// 데이터 읽기
		for (Row row : sheetList) {
			
			// (첫번째 행은 헤더이므로 건너뛰어야 한다)
			if(row.getRowNum() == 0) {
				continue;
			}
			
			//int no = (int)row.getCell(0).getNumericCellValue();
			//String title = row.getCell(1).getStringCellValue();
			//String writer = row.getCell(2).getStringCellValue();
			//String content = row.getCell(3).getStringCellValue();
			//LocalDateTime writedate = convertToLocalDateTimeViaInstant(row.getCell(4).getDateCellValue());
			//LocalDateTime modifydate = convertToLocalDateTimeViaInstant(row.getCell(5).getDateCellValue());
			//int hit = (int)row.getCell(6).getNumericCellValue();
			
			try {
			Cell noCell = row.getCell(0);
			int no;
			if (noCell == null || noCell.getCellType() == Cell.CELL_TYPE_BLANK) {
			    no = 0;
			} else {
			    if (noCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
			        no = (int) noCell.getNumericCellValue();
			    } else {
			        throw new IllegalStateException("번호 셀 타입이 숫자가 아닙니다.");
			    }
			}
			
			Cell titleCell = row.getCell(1);
			String title;
			if (titleCell == null || titleCell.getCellType() == Cell.CELL_TYPE_BLANK) {
			    throw new IllegalStateException("제목은 빈 값이거나 null일 수 없습니다.");
			} else {
			    if (titleCell.getCellType() == Cell.CELL_TYPE_STRING) {
			        title = titleCell.getStringCellValue();
			    } else if (titleCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
			    		double numericTitle = titleCell.getNumericCellValue();
			    		title = String.valueOf(numericTitle);
				} else {
			        throw new IllegalStateException("제목 셀의 타입이 문자열 또는 숫자가 아닙니다.");
			    }
			}
			
			Cell writerCell = row.getCell(2);
			String writer;
			if (writerCell == null || writerCell.getCellType() == Cell.CELL_TYPE_BLANK) {
				throw new IllegalStateException("작성자는 빈 값이거나 null일 수 없습니다.");
			} else {
			    if (writerCell.getCellType() == Cell.CELL_TYPE_STRING) {
			        writer = writerCell.getStringCellValue();
			    } else if (writerCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
			    	double numericWriter = writerCell.getNumericCellValue();
			    	writer = String.valueOf(numericWriter);
			    } else {
			        throw new IllegalStateException("작성자 셀의 타입이 문자열 또는 숫자가 아닙니다.");
			    }
			}
			
			Cell contentCell = row.getCell(3);
			String content;
			if (contentCell == null || contentCell.getCellType() == Cell.CELL_TYPE_BLANK) {
				throw new IllegalStateException("내용은 빈 값이거나 null일 수 없습니다.");
			} else {
			    if (contentCell.getCellType() == Cell.CELL_TYPE_STRING) {
			    	content = contentCell.getStringCellValue();
			    } else if (contentCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
			    	double numericContent = contentCell.getNumericCellValue();
			    	content = String.valueOf(numericContent);
			    } else {
			        throw new IllegalStateException("내용 셀의 타입이 문자열 또는 숫자가 아닙니다.");
			    }
			}
			
			Cell writedateCell = row.getCell(4);
			LocalDateTime writedate;
			if (writedateCell == null || writedateCell.getCellType() == Cell.CELL_TYPE_BLANK) {
			    throw new IllegalStateException("작성 날짜는 빈 값이거나 null일 수 없습니다.");
			} else {
			    if (writedateCell.getCellType() == Cell.CELL_TYPE_NUMERIC && DateUtil.isCellDateFormatted(writedateCell)) {
			        writedate = convertToLocalDateTimeViaInstant(writedateCell.getDateCellValue());
			    } else {
			        throw new IllegalStateException("작성 날짜 셀의 타입이 날짜 형식이 아닙니다.");
			    }
			}


			Cell modifydateCell = row.getCell(5);
			LocalDateTime modifydate;
			if (modifydateCell == null || modifydateCell.getCellType() == Cell.CELL_TYPE_BLANK) {
			    modifydate = null;
			} else {
			    if (modifydateCell.getCellType() == Cell.CELL_TYPE_NUMERIC && DateUtil.isCellDateFormatted(writedateCell)) {
			    	modifydate = convertToLocalDateTimeViaInstant(modifydateCell.getDateCellValue());
			    } else {
			        throw new IllegalStateException("수정 날짜 셀의 타입이 날짜 형식이 아닙니다.");
			    }
			}

			Cell hitCell = row.getCell(6);
			int hit;
			if (hitCell == null || hitCell.getCellType() == Cell.CELL_TYPE_BLANK) {
			    hit = 0;
			} else {
			    if (hitCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
			        hit = (int) hitCell.getNumericCellValue();
			    } else {
			        throw new IllegalStateException("조회수 셀 타입이 숫자가 아닙니다.");
			    }
			}

			// 서비스 메서드를 호출해서 데이터 저장
			boardService.savePost(title, content, writer, null);
			System.out.println("엑셀업로드 컨트롤러 데이터 저장");
			
			
			// 워트북 닫기
			workbook.close();
		
			} catch (IllegalStateException e) {
				model.addAttribute("errorMessage", e.getMessage());
				return "error/error";
			}
		}
		
	// 리스트 페이지로 리다이렉트
	return "redirect:/board";
	}
profile
공부공부

0개의 댓글