jxls 이용한 엑셀 업로드

갓김치·2021년 2월 9일
1

최종프로젝트

목록 보기
12/19

업로드

참고 사이트

필요 dependency

<dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls-reader</artifactId>
    <version>2.0.6</version>
</dependency> 

dependency exclusion 추가

<dependency>
  <groupId>org.jxls</groupId>
  <artifactId>jxls-reader</artifactId>
  <version>2.0.6</version>
  <exclusions>
    <exclusion>
      <groupId>commons-beanutils</groupId>
      <artifactId>commons-beanutils</artifactId>
    </exclusion>
    <exclusion>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
    </exclusion>
  </exclusions>
</dependency> 
  • 다른 디펜던시에 이미 logging과 beanutils가 들어있기때문에 지워줌
  • 우리 프로젝트는 jxls-reader외에도 poi, jxls 관련하여 다음의 디펜던시를 사용하고있음
<!-- Reporting -->
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>${org.apache.poi-version}</version>
</dependency>
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>${org.apache.poi-version}</version>
</dependency>

<!-- POI 4 version matching JXLS -->
<dependency>
  <groupId>org.jxls</groupId>
  <artifactId>jxls</artifactId>
  <version>2.9.0</version>
</dependency>
<dependency>
  <groupId>org.jxls</groupId>
  <artifactId>jxls-jexcel</artifactId>
  <version>1.0.9</version>
</dependency>
<dependency>
  <groupId>org.jxls</groupId>
  <artifactId>jxls-poi</artifactId>
  <version>2.8.1</version>
  <exclusions>
    <exclusion>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
    </exclusion>
  </exclusions>
</dependency>

업로드 양식을 지정한 xml config파일

  • config위치 : classpath:kr/or/anyapart/jxlstmpl/moveinList.xml
<?xml version="1.0" encoding="UTF-8"?>
<workbook>
  <worksheet name="Sheet1">
    <section startRow="0" endRow="1"/> <!-- 데이터 들어가지 않는 셀 -->
    <loop startRow="2" endRow="2" items="residentList" var="resident" varType="kr.or.anyapart.resident.vo.ResidentVO">
      <section startRow="2" endRow="2">
        <mapping row="2" col="0">resident.dong</mapping>
        <mapping row="2" col="1">resident.ho</mapping>
        <mapping row="2" col="2">resident.resName</mapping>
        <mapping row="2" col="3">resident.resHp</mapping>
        <mapping row="2" col="4">resident.resTel</mapping>
        <mapping row="2" col="5">resident.resMail</mapping>
        <mapping row="2" col="6">resident.resBirth</mapping>
        <mapping row="2" col="7">resident.resJob</mapping>
        <mapping row="2" col="8">resident.resMovein</mapping>
      </section>
      <loopbreakcondition>
        <rowcheck offset="0"/>
      </loopbreakcondition>
    </loop>
  </worksheet>
</workbook>

사용자에게 제공할 템플릿의 모습

  • xml에서 section에 해당하는 부분: 입주민일괄등록, 동/호/...
  • 입력하지 않은 셀은 null로 들어감

스크립트

// 엑셀 업로드
const uploadExcelBtn = $("#uploadExcelBtn"); // 업로드버튼

uploadExcelBtn.on("click", function() {
  console.log(excelFile);
  if (isEmpty(excelFile.val())) {
    getErrorNotyDefault("엑셀 파일을 첨부해 주세요.");
    return;
  }
  if(!confirm("등록하시겠습니까?")) return;

  const formData = new FormData($("#moveinExcelForm")[0]);

  // fetch api로 파일 전송
  let url = $.getContextPath() +"/office/resident/movein/uploadExcel.do";
  fetch(url, {
    method: "POST"
    , body: formData
  })
    .then(function(response) {
    return response.json();
  })
    .then(function(json) {
    if(json.message) { // 실패시 message를 model에 넘김
      getNoty(json);
    }else { // model에 message 없는 경우는 성공이어서 모달창 닫아줌
      moveinExcelUploadModal.modal("hide");
    }
  })
    .catch((error) => {
    console.error('Error:', error);
  });
});

컨트롤러

@RequestMapping(value="/office/resident/movein/uploadExcel.do", produces=MediaType.APPLICATION_JSON_UTF8_VALUE, method=RequestMethod.POST)
	public String uploadJXLS(
			@AuthenticationPrincipal(expression="realMember") MemberVO authMember
			,@RequestPart("excelFile") MultipartFile excelFile
			,Model model) {

			NotyMessageVO message = INSERT_SERVER_ERROR_MSG;
			ServiceResult result = ServiceResult.FAILED;

			List<ResidentVO> residentList = new ArrayList<>();
			Resource tmpl = container.getResource("classpath:kr/or/anyapart/jxlstmpl/moveinList.xml");

			try (
					InputStream is = new BufferedInputStream(tmpl.getInputStream())
			) {

					XLSReader reader = ReaderBuilder.buildFromXML(is);

					Map<String, Object> beans = new HashMap<>();
					beans.put("residentList", residentList);

					try {
						InputStream excelStream = excelFile.getInputStream();
						reader.read(excelStream, beans);

						// houseCode 생성하기 위해 aptCode 미리 셋팅
						residentList.forEach( resident -> resident.setAptCode(getAptCode(authMember)));

						result = service.createMuitlpleResident(residentList);

					} catch (InvalidFormatException | SQLException e) {
						LOGGER.error(this.getClass().getName() + " " + e.getMessage());
					}

			} catch (SAXException | IOException e) {
				LOGGER.error(this.getClass().getName() + " " + e.getMessage());
			}

			switch (result) {
			case OK:
				message = null;
				break;
			case ALREADYEXIST:
				message = getCustomNoty("이미 입주한 세대를 포함한 파일입니다.");
				break;
			case FAILED:
				message = getCustomNoty("엑셀 업로드 양식에 맞지 않습니다.");
				break;
			}
		if(message != null) model.addAttribute("message", message);

		return "jsonView";

	}

다운로드

profile
갈 길이 멀다

0개의 댓글