본문 바로가기
개발툴/Spring Boot(STS)

[Spring Boot] 엑셀 다운로드 기능 Apache POI

by HmHjj 2022. 1. 7.
728x90
반응형

 

 

Spring Boot 에서 데이타를 엑셀로 다운받는 기능을 넣어보겠습니다. 사용 방법을 바로 보시고 싶으면 Apache POI API 소개 부분은 넘어가셔도 좋습니다. 

 

Apache POI API 소개

Microsoft 에서 제공하는 문서 형태에 지원을 하는 API 로 Apache POI 라고 합니다. 자세한 내용은 공식 페이지는 아래에서 접근하여 확인하면 되며, 간단히 아래에 적었습니다. 

 

https://poi.apache.org/components/

 

Apache POI - Component Overview

Apache POI - Component Overview Apache POI Project Components The Apache POI project is the master project for developing pure Java ports of file formats based on Microsoft's OLE 2 Compound Document Format. OLE 2 Compound Document Format is used by Microso

poi.apache.org

 

OLE 2 문서용 POIFS

POIFS는 POI에서 가장 오래되고 안정되어 있으며, OLE 2 복합 문서 형식을 Java로 포팅한 것입니다. 읽기 및 쓰기 기능을 모두 지원하며 바이너리(비 XML) Microsoft Office 형식에 대한 모든 구성 요소는 정의에 따라 이 형식에 의존합니다. 

Excel 문서용 HSSF 및 XSSF

HSSF는 Microsoft Excel 97(-2003) 파일 형식(BIFF8)으로, XSSF는 Microsoft Excel XML(2007+) 파일 형식(OOXML)으로  Java로 포팅가능하며, 둘 다 읽기 및 쓰기 기능을 지원합니다. 

Word 문서용 HWPF 및 XWPF

HWPF는 Microsoft Word 97(-2003) 파일 형식을 Java로 포팅하고,  읽기 및 제한된 쓰기 기능을 지원합니다. 또한 이전 Word 6 및 Word 95 형식에 대한 간단한 텍스트 추출 지원을 제공합니다. . 이 구성 요소는 개발 초기 단계에 있으나 간단한 파일은 읽고 쓸 수 있습니다. 또한 OOXML 사양의 WordprocessingML(2007+) 형식용 XWPF를 작업 중이며,  이것은 텍스트 추출 기능과 함께 조금 더 간단한 파일에 대한 읽기 및 쓰기 지원을 제공합니다.

PowerPoint 문서용 HSLF 및 XSLF

HSLF는 Microsoft PowerPoint 97(-2003) 파일 형식을 순수 Java로 포팅하고, 읽기 및 쓰기 기능을 지원합니다. 

추가로 OOXML 사양의 PresentationML(2007+) 형식용 XSLF에 대해 진행 중에 있습니다. 

 

OLE 2 문서 속성용 HPSF

HPSF는 Java에 대한 OLE 2 속성 집합 형식의 포팅을 지원합니다.  속성 집합은 주로 문서의 속성(제목, 작성자, 마지막 수정 날짜 등)을 저장하는 데 사용되지만 응용 프로그램별 목적으로도 사용할 수 있습니다. HPSF는 속성 읽기와 쓰기를 모두 지원합니다.

 

Visio 문서용 HDGF 및 XDGF

HDGF는 Microsoft Visio 97(-2003) 파일 형식을 Java로 포팅하며, 현재 매우 낮은 수준의 읽기와 간단한 텍스트 추출만 지원합니다. 자세한 내용 은 HDGF/다이어그램 프로젝트 페이지를 참조하십시오 .XDGF는 Microsoft Visio XML(.vsdx) 파일 형식을 Java로 포팅하는 것이며, HDGF보다 약간 더 지원합니다. 

 

발행인 문서용 HPBF

HPBF는 Microsoft Publisher 98(-2007) 파일 형식을 Java로 포팅하며, 현재 파일 부분의 약 절반에 대해 낮은 수준에서 읽기와 간단한 텍스트 추출만 지원합니다. 

 

TNEF용 HMEF(winmail.dat) Outlook 첨부 파일

HMEF는 Microsoft TNEF(Transport Neutral Encoding Format) 파일 형식을 Java로 포팅하며, TNEF는 Outlook에서 메시지를 인코딩하는 데 사용되는 경우가 있으며 일반적으로 winmail.dat로 전달됩니다. HMEF는 현재 낮은 수준의 읽기만 지원하지만 텍스트 및 첨부 파일 추출을 추가할 수 있기를 바랍니다. 

 

Outlook 메시지용 HSMF

HSMF는 Microsoft Outlook 메시지 파일 형식을 Java로 포팅하며,  현재 MSG 파일의 텍스트 내용 중 일부와 일부 첨부 파일만 있습니다. 현재로서는 사용자가 예제 사용을 위해 단위 테스트를 참조하는 것이 좋습니다. Microsoft에서 최근에 Outlook 파일 형식을 OSP에 추가하였습니다. 

 

Componet 타입별 Maven 표.

Component Application Type Maven
POIFS OLE2 Filesystem poi
HPSF OLE2 Property Sets poi
HSSF Excel XLS poi
HSLF PowerPoint PPT poi-scratchpad
HWPF Word DOC poi-scratchpad
HDGF Visio VSD poi-scratchpad
HPBF Publisher PUB poi-scratchpad
HSMF Outlook MSG poi-scratchpad
DDF Escher common drawings poi
HWMF WMF drawings poi-scratchpad
OpenXML4J OOXML poi-ooxml plus either poi-ooxml-lite or
poi-ooxml-full
XSSF Excel XLSX poi-ooxml
XSLF PowerPoint PPTX poi-ooxml
XWPF Word DOCX poi-ooxml
XDGF Visio VSDX poi-ooxml
Common SL PowerPoint PPT and PPTX poi-scratchpad and poi-ooxml
Common SS Excel XLS and XLSX poi-ooxml

 

Apache POI Spring Boot 적용 

프로젝트는 이전 블로그에서 생성한 상태에서 진행하였습니다. 

 

Gradle.build 의존성 추가

아래의 이름으로 의존성 추가합니다. 다른 의존성은 아래 프로젝트 진행할때 필요하니 넣으시기 바랍니다. 

implementation 'org.apache.poi:poi-ooxml:5.1.0'

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.apache.poi:poi-ooxml:5.1.0'
}

 

Gradle Refesh 후 라이브러리를 확인.

 

Apache POI API 소스 작성

 

백엔드(back-end)

com.server 패키지에서 새로운 Java Packge를 domain이란 이름으로 만듭니다. 

 

만들어진 패키지에 Class를 추가합니다. 

 

Board 라는 이름의 class를 만들어 게시판 내용을 담을 객체를 작성합니다. 

 

이제 게시판에서 필요한 내용 (컬럼) 을 작성하는데 여기서 Number 와 Name 두개만 작성해 봅니다. 

package com.server.domain;

public class Board {
	private Integer Number;
	private String Name;

}

 

lombok를 쓰면 getter 와 setter 가 자동으로 들어가는데 여기서는 일단 다 작성하여 사용해 봅니다. 

상단 Sorce 탭에 Generate Getters and Setters 를 누르면 자동으로 작성할 수 있다. 

 

getter, setter 넣을 변수를 체크박스에 체크해 주자. 

그럼 아래와 같이 자동으로 get, set 소스가 추가 된다. 

package com.server.domain;

public class Board {
	private Integer Number;
	private String Name;
	
	public Integer getNumber() {
		return Number;
	}
	public void setNumber(Integer number) {
		Number = number;
	}
	public String getName() {
		return Name;
	}
	public void setName(String name) {
		Name = name;
	}
}

 

이제 Controller에 엑셀 파일 다운 로드를 위한 소스 적용. contorller package에서 ExcelController 이름으로 Class를 만듭니다. 

 

 

아래 소스를 추가합니다. 

package com.server.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.server.domain.Board;

@Controller
public class ExcelController {
	static List<Board> listboard = new ArrayList<Board>();
	
	@GetMapping("/excel")
	public String excelhome(Model model) {
		Board board = new Board();
		board.setNumber(1);
		board.setName("test1");
		listboard.add(0, board);
		Board board2 = new Board();
		board2.setNumber(2);
		board2.setName("test2");
		listboard.add(1, board2);
		model.addAttribute("board",listboard);
		return "excel";
	}
	
	
	@RequestMapping("/exceldownload")
	public static void exceldownload(HttpServletResponse response) {
	    Row row = null;
	    Cell cell = null;
	    int rowNum = 0;
	    Workbook wb = new XSSFWorkbook();
	    Sheet sheet = wb.createSheet("sheet1");
	    
	    row = sheet.createRow(rowNum++);
	    cell = row.createCell(0);
	    cell.setCellValue("Number");
	    cell = row.createCell(1);
	    cell.setCellValue("Name");
	    
	    for (int i=0; i < listboard.size() ; i++) {
	        row = sheet.createRow(rowNum++);
	        cell = row.createCell(0);
	        cell.setCellValue(listboard.get(i).getNumber());
	        cell = row.createCell(1);
	        cell.setCellValue(listboard.get(i).getName());
	    }
	    response.setContentType("ms-vnd/excel");
	    response.setHeader("Content-Disposition", "attachment;filename=excel.xlsx");

	    try {
		    wb.write(response.getOutputStream());
		    wb.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

나눠서 자세히 설명하겠습니다. excelhome 함수는 /excel 페이지로 접근하면 실행된다. 보통은 DB를 사용해서 저장하여 불러오는데 여기선 간단히 설명을 위해 전역 변수로 선언하여 값을 입력하여 화명에 보내줍니다.  

 

static List<Board> listboard = new ArrayList<Board>();// 리스트 전역 선언
    
@GetMapping("/excel")
public String excelhome(Model model) {
	Board board = new Board(); // 리스트에 넣을 객체 생성
	board.setNumber(1); // board 객체 Number 변수에 숫자 1을 입력
	board.setName("test1"); // board 객체 Name 변수에 숫자 test1을 입력
	listboard.add(board); // boad 객체를 listboad에 입력 
	Board board2 = new Board(); // 2번째 리스트에 넣을 객체 생성
	board2.setNumber(2); // board2 객체 Number 변수에 숫자 2을 입력
	board2.setName("test2"); // board2 객체 Name 변수에 숫자 test2을 입력
	listboard.add(1, board2); // boad2 객체를 listboad에 입력 
	model.addAttribute("board",listboard); //html에서 읽을수 있도록 listboard 를 model에 넣음
	return "excel"; // excel.html 을 호출
}

 

exceldownload 함수로 /exceldownload 링크 형태로 받게 되어 있으며, 전역 변수에 있는 데이타를 엑셀로 저장합니다. 

@RequestMapping("/exceldownload")
public static void exceldownload(HttpServletResponse response) {
    Row row = null;
    Cell cell = null;
    int rowNum = 0;
	Workbook wb = new XSSFWorkbook();
	Sheet sheet = wb.createSheet("sheet1"); // 엑셀 시트 이름
    
    row = sheet.createRow(rowNum++); // 컬럼 이름
    cell = row.createCell(0); // 첫번째 항목 공간 생성
    cell.setCellValue("Number"); // 생성된 공간에 Number 입력 
    cell = row.createCell(1); // 두번째 항목 공간 생성
    cell.setCellValue("Name"); // 생성된 공간에 Name 입력
	    
    for (int i=0; i < listboard.size() ; i++) { // listboard 만큼 for 문
        row = sheet.createRow(rowNum++);
        cell = row.createCell(0);
        cell.setCellValue(listboard.get(i).getNumber()); // getNumber로 list 에서 읽음
        cell = row.createCell(1);
        cell.setCellValue(listboard.get(i).getName()); // getName로 list 에서 읽음
    }
    // excel 설정
    response.setContentType("ms-vnd/excel"); 
    // excel header 설정 파일명 설정.
    response.setHeader("Content-Disposition", "attachment;filename=excel.xlsx");

    try {
        wb.write(response.getOutputStream());
        wb.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

 

프론트엔드(front-end)

 

페이지 작성을 위한 html 를 만들어 볼건데 그전에 html 을 인식시키기 위한 설정이 필요하다. 

src/main/resources 아래 보면 application.properties 파일이 있는데 이게 파일명 그대로 설정에 관한 파일이다.

spring.mvc.view.suffix=.html 를 파일에 넣어주자. 

그리고 templates 아래에 excel.html 파일을 만들어 주자.  요 파일명을 바꾸게 되면 접속이 안된다. controller에서 return 명이 파일명이라고 생각하면 된다. 

 

아래 소스를 복사해서 넣어주자.  thymeleaf 를 사용해서 href 링크와 th:each 반복문 th:text 텍스트 입력을 사용했다.  

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <title>Excel DownLoad</title>
</head>

<body>
    <h1> Excel DownLoad </h1>
    <div>
        <a th:href="@{/exceldownload}">excel download</a>
    </div>
    <div>
        <table>
            <thead>
                <tr>
                    <th>Number</th>
                    <th>Name</th>
                </tr>
            </thead>
            <tbody>
                <tr th:each="board : ${board}">
                    <td th:text="${board.number}"></td>
                    <td th:text="${board.name}"></td>
                </tr>
            </tbody>
        </table>
    </div>
</body>

</html>

 

Application 시작

이제 소스는 완료 되었으니 application 을 실행하여 페이지에 접속해 보자. 

http://localhost:8080/excel 로 접속하면 아래와 같이  Number 컬럼 과 Name 컬럼 데이타가 출력 됩니다. 

 

파란색으로 언더바 되어있는 excel download 를 클릭하면 excel.xlsx 파일이 다운로드 됩니다. 

엑셀 파일을 열어보면 아래와 같이 저장 되어 있는 것을 확인 할 수 있습니다. 

728x90
반응형

'개발툴 > Spring Boot(STS)' 카테고리의 다른 글

[STS] 이클립스 단축키  (0) 2021.12.23
Spring Boot 프로젝트 생성  (0) 2021.12.14
Spring Boot 설치 (STS) 및 설정  (0) 2021.12.13

댓글