뽀미의 개발노트

웹사이트 내용 엑셀 파일로 다운받기 본문

Trouble_Shooting

웹사이트 내용 엑셀 파일로 다운받기

산타는 뽀미 2023. 6. 26. 12:05

내 사이트에서는 studentlist를 table 형태로 보여주고 있었는데 문득 이걸 엑셀파일로 다운받고 싶다는 생각이 들었다. (왜냐하면 학원에서 애들 출석부에 출결 체크하는건 기본이니까!)

그래서 많이 찾아보고 여러 시행착오를 거쳐서 웹사이트 내용을 엑셀파일로 다운받을 수 있게 되었다!!

<pom.xml>

<!-- 엑셀 파일 다운로드를 위한 -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.1.0</version>
</dependency>

 

<studentlist.jsp>

<div class="table-box-type-1">
  <table class="table w-full" id="memberlisttable">
    <thead>
      <tr>
        <th>가입날짜</th>
        <th>로그인 아이디</th>
        <th>학생 이름</th>
        <th>수강하는 반</th>
        <th>휴대전화</th>
        <th>부모님 휴대전화</th>
      </tr>
    </thead>

    <c:forEach var="student" items="${students }">
    <tbody>
      <tr>
        <td>${student.regDate }</td>
        <td>${student.loginID }</td>
        <td>${student.name }</td>
        <td>${student.groupName }</td>
        <td>${student.cellphoneNum }</td>
        <td>${student.parentPhoneNum }</td>
      </tr>
    </tbody>
    </c:forEach>
  </table>
</div>
	  
<a class="btn" href="excelDownload?classId=${classId }">출석부 파일 다운로드</a>

 

<controller>

public static String fileName = "";
/**
 * 학생 명단 출석부로 다운받기
 * @param response (다운로드시 웹사이트 하단에 header 설정해서 보낼것임)
 * @param classId (이걸로 반 정보 가져와야함)
 * @throws IOException
 * apache.poi maven dependancy 추가
 */
@RequestMapping("/project/member/excelDownload")
@ResponseBody
public void excelDownload(HttpServletResponse response, int classId) throws IOException {

    List<Member> students = memberService.getMemberByClassId(classId);

    Group group = groupService.getGroupById(classId);

    // 엑셀파일 제목 만들기
    fileName = group.getGroupName() + "_attendance_book.xlsx";

    // 엑셀파일 생성 (.xlsw 파일 포맷 사용할때 XSSF로 시작하는 class 사용)
    XSSFWorkbook workbook = new XSSFWorkbook();

    // 엑셀파일 안에 sheet 생성하고 이름 짓기
    XSSFSheet sheet = workbook.createSheet("attendance book");

    // 일단 맵에다가 정보들을 저장하고 저 맵을 엑셀의 행열에 추가할것임
    Map<String, Object[]> data = new TreeMap<>();

    // 첫번째 줄에 표의 head 만들기
    data.put("1", new Object[]{"학생 이름", "수강하는 반", "전화번호", "부모님 번호"});
    int i = 2;
    for(Member student : students) {
        // 두번째 줄부터 웹페이지 속 학생 정보들을 한줄한줄 채우기
        data.put(String.valueOf(i), new Object[]{student.getName(), student.getGroupName(), 
                student.getCellphoneNum(), student.getParentPhoneNum()});
        i++;
    }

    // data에서 keySet를 가져와서 조회하며 데이터들을 sheet에 입력한다.
    // map에 key값만 전체 출력 (키는 행 번호들이 문자화된 모습임)
    Set<String> keyset = data.keySet();
    int rownum = 0;

    // TreeMap을 통해 생성된 keySet는 for로 조회시, 키값의 오름차순으로 조회된다.
    // 시트에서 행(row) 생성
    // key값에 맞는 데이터들(이름, 반이름, 폰번호, 부모님번호)를 뽑아서 배열에 넣어놓고
    // 행에서 cell 하나씩 생성해서 배열 속 데이터들 하나씩 넣어줌
    // 데이터들의 형태가 다양할 수 있으므로 일단 object로 넣어놓고
    // 나중에 뽑아쓸때 string, integer 등 원래 타입을 다시 적용해줌
    for (String key : keyset) {
        Row row = sheet.createRow(rownum++);
        Object[] objArr = data.get(key);
        int cellnum = 0;
        for (Object obj : objArr) {
            Cell cell = row.createCell(cellnum++);
            if(obj instanceof String) {
                cell.setCellValue((String)obj);
            } else if (obj instanceof Integer){
                cell.setCellValue((Integer)obj);
            }
        }
    }

    // 위에까지만 하면 view 상에서는 어떤 변화도 없이 엑셀파일만 다운받아짐. 그래서 아래 코드 추가
    // 파일을 client에게 전송할 때 response 사용함
    // 다운로드 받을때 브라우저 하단에 다운로드 헤더 나오게 하기!!
    // 그냥 fileName 쓰면 브라우저가 유니코드로 인식해서 꼭 UTF-8 encoding 해줘야함
    // stream은 데이터의 입력과 출력을 하도록 이어주는 통로
    // stream은 buffer에 임시적으로 데이터를 보아서 보내줌

    // 파일 유형설정
    response.setContentType("ms-vnd/excel");
    // 데이터 형식 설정 (attachment : 첨부파일)
    response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
    // 버퍼의 출력스트림을 출력
    workbook.write(response.getOutputStream());
    // 출력 스트림 닫기
    workbook.close();

}

참고했던 블로그들과 상황이 완벽하게 똑같지 않아서 조금 헤맸다.

처음엔 파일은 잘 다운받아지는데 웹사이트 하단에 다운로드 표시가 안 떠서 그거 해결하느라 좀 오래 걸렸다.

암튼 너무 재밌고 멋진 기능이고 꼭 엑셀 파일 말고도 다른 파일 다운로드 받을때도 사용할 수 있으니 잘 기억해놨다가 나중에 유용하게 써먹자!!

 

<내가 참고했던 블로그들>

https://dailylifecoding.tistory.com/entry/apache-POI-%EA%B0%84%EB%8B%A8-%EC%82%AC%EC%9A%A9%EB%B2%95-1

 

[apache POI] 간단 사용법

apache POI는 언제 사용하는가? 아파치 POI(Apache POI)는 아파치 소프트웨어 재단에서 만든 라이브러리로서 마이크로소프트 오피스 파일 포맷을 순수 자바 언어로서 읽고 쓰는 기능을 제공한다. JDK 호

dailylifecoding.tistory.com

https://hyeounstory.tistory.com/67

 

[Spring 분석] 파일다운로드

1. 방법 @Controller public class CommonController { @Resource(name="commonService") private CommonService commonService; @RequestMapping(value="/common/downloadFile.do") public void downloadFile(CommandMap commandMap, HttpServletResponse response) throws

hyeounstory.tistory.com