안녕하세요. 개발자 Jindory입니다.
오늘은 POI 라이브러리를 이용해서 엑셀 파일을 내려받는 과정에 대해서 글을 작성해보고자 합니다.
프로그램을 만들다 보면 데이터를 엑셀로 다운받아서 보고 싶은 경우가 생기는데요, 이때 Apache POI를 사용하면 쉽게 엑셀로 데이터를 다운로드 받을 수 있습니다.
Apache POI(Poor Obfuscation Implementation)란
Apache POI는 아파치 소프트웨어 재단에 의해 운영되는 오픈소스 프로젝트 입니다. 순수 자바 라이브러리로서 Microsoft Office의 Word, PowerPoint, Excel 형식의 파일을 읽고 쓸 수 있게 해주며 최근의 오피스 포맷인 Office Open XML File Format도 지원해줍니다.
Apache POI 라이브러리 적용하기
maven Repository(https://mvnrepository.com/artifact/org.apache.poi/poi)에 방문해서 poi를 검색해서 나온 결과를 보면 아래와 같습니다.
일단 최신 버전 중 다운로드가 많은 5.0.x를 들어가서 Maven 혹은 Gradle에 넣을 소스를 복사하여 붙혀 넣습니다.
POI를 활용하여 xls 파일 만들기
1. Excel을 만들 Controller 생성
먼저 Exceldownload를 호출할 Controller를 만들고 url을 생성합니다.
그리고 엑셀에 들어갈 데이터를 임시로 만듭니다.(만일 데이터베이스에서 데이터를 가져올 수 있다면 데이터베이스 정보를 가져와도 됩니다.)
package core;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class excelExport {
@GetMapping("/downloadExel")
public void downloadExel(HttpServletResponse response) throws IOException {
// 엑셀에 들어갈 데이터 생성
collegeStudent[] list = {
new collegeStudent(2022032401L,"김학생",2,"M","경영학"),
new collegeStudent(2022032402L,"이학생",1,"F","컴퓨터공학"),
new collegeStudent(2022032403L,"박학생",2,"M","통계학"),
new collegeStudent(2022032404L,"최학생",1,"F","식품영양학"),
new collegeStudent(2022032405L,"정학생",1,"M","영화예술학"),
new collegeStudent(2022032406L,"강학생",4,"M","디자인학"),
new collegeStudent(2022032407L,"조학생",1,"F","심리학"),
new collegeStudent(2022032408L,"윤학생",1,"F","경제학"),
new collegeStudent(2022032409L,"장학생",3,"M","체육학"),
new collegeStudent(2022032410L,"임학생",2,"M","화학"),
new collegeStudent(2022032411L,"한학생",1,"M","기계공학"),
new collegeStudent(2022032412L,"오학생",4,"F","의예"),
new collegeStudent(2022032413L,"서학생",1,"F","조경학"),
new collegeStudent(2022032414L,"신학생",1,"M","수학"),
new collegeStudent(2022032415L,"권학생",3,"M","물리"),
new collegeStudent(2022032416L,"황학생",2,"M","미술"),
new collegeStudent(2022032417L,"안학생",3,"M","제약"),
new collegeStudent(2022032418L,"송학생",4,"F","철학"),
new collegeStudent(2022032419L,"전학생",2,"M","의상학"),
new collegeStudent(2022032420L,"홍학생",1,"M","반도체")
};
}
}
class collegeStudent {
Long studentId;
String name;
int grade;
String gender;
String major;
public collegeStudent(Long studentId, String name,int grade,String gender,String major){
this.studentId = studentId;
this.name = name;
this.grade = grade;
this.gender = gender;
this.major = major;
}
@Override
public String toString() {
return "student [studentId=" + studentId + ", name=" + name + ", grade=" + grade + ", gender=" + gender
+ ", major=" + major + "]";
}
public Long getStudentId() {
return studentId;
}
public void setStudentId(Long studentId) {
this.studentId = studentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
}
2. Excel과 Sheet, Header 만들기
다음으로 엑셀파일을 만들기 위해 WorkBook을 생성하고 Sheet의 이름을 셋팅합니다.
저는 학생부 명단을 만들기로 했으니 학생부 명단이라고 Sheet 이름을 설정하겠습니다.
다음으로 엑셀의 한 줄을 넣게 위해 Row라는 자료형을 선언하고 만들어둔 sheet에 하나의 row를 추가합니다.
이때 createRow 안에는 row의 순서를 의미하는 int 자료형이 들어갑니다. 0번부터 시작이므로 0을 넣어줍니다.
다음으로 생성한 Row에 Cell을 만들어서 값을 입력합니다.
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("학생부 명단");
int rowNo = 0;
Row headerRow = sheet.createRow(rowNo++);
headerRow.createCell(0).setCellValue("학번");
headerRow.createCell(1).setCellValue("이름");
headerRow.createCell(2).setCellValue("학년");
headerRow.createCell(3).setCellValue("성별");
headerRow.createCell(4).setCellValue("전공");
3. 데이터 입력하기
이제 아래와 같이 미리 생성해둔 데이터를 한 Row씩 생성하면서 아래와 같이 입력합니다.
for (collegeStudent s : list) {
Row row = sheet.createRow(rowNo++);
row.createCell(0).setCellValue(s.getStudentId());
row.createCell(1).setCellValue(s.getName());
row.createCell(2).setCellValue(s.getGrade());
row.createCell(3).setCellValue(s.getGender());
row.createCell(4).setCellValue(s.getMajor());
}
4. Excel 형식 및 이름 정하고 다운받기
이제 마지막으로 응답 컨텐츠와 헤더를 정해 줍니다. 그러고나서는 response의 OutputStream에 workbook을 write 해줍니다. response에 바로 응답을 하면 에러가 생겼을 경우 대응하기가 어렵기 때문에 좋은 코드의 방식은 아니지만 일단 이해를 위해 최대한 간단한 코드로 작성 해 보았습니다.
헤더에는 한글이 들어갈 수 없기 때문에 header를 통해 파일명을 지정해주는 방식으로는 한글 파일명을 사용할 수 없습니다.
response.setContentType("ms-vnd/excel");
response.setHeader("Content-Disposition", "attachment;filename=studentList.xls");
workbook.write(response.getOutputStream());
workbook.close();
전체적인 소스는 아래와 같으니 참고해주세요.
package core;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class excelExport {
@GetMapping("/downloadExel")
public void downloadExel(HttpServletResponse response) throws IOException {
// 엑셀에 들어갈 데이터 생성
collegeStudent[] list = {
new collegeStudent(2022032401L,"김학생",2,"M","경영학"),
new collegeStudent(2022032402L,"이학생",1,"F","컴퓨터공학"),
new collegeStudent(2022032403L,"박학생",2,"M","통계학"),
new collegeStudent(2022032404L,"최학생",1,"F","식품영양학"),
new collegeStudent(2022032405L,"정학생",1,"M","영화예술학"),
new collegeStudent(2022032406L,"강학생",4,"M","디자인학"),
new collegeStudent(2022032407L,"조학생",1,"F","심리학"),
new collegeStudent(2022032408L,"윤학생",1,"F","경제학"),
new collegeStudent(2022032409L,"장학생",3,"M","체육학"),
new collegeStudent(2022032410L,"임학생",2,"M","화학"),
new collegeStudent(2022032411L,"한학생",1,"M","기계공학"),
new collegeStudent(2022032412L,"오학생",4,"F","의예"),
new collegeStudent(2022032413L,"서학생",1,"F","조경학"),
new collegeStudent(2022032414L,"신학생",1,"M","수학"),
new collegeStudent(2022032415L,"권학생",3,"M","물리"),
new collegeStudent(2022032416L,"황학생",2,"M","미술"),
new collegeStudent(2022032417L,"안학생",3,"M","제약"),
new collegeStudent(2022032418L,"송학생",4,"F","철학"),
new collegeStudent(2022032419L,"전학생",2,"M","의상학"),
new collegeStudent(2022032420L,"홍학생",1,"M","반도체")
};
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("학생부 명단");
int rowNo = 0;
Row headerRow = sheet.createRow(rowNo++);
headerRow.createCell(0).setCellValue("학번");
headerRow.createCell(1).setCellValue("이름");
headerRow.createCell(2).setCellValue("학년");
headerRow.createCell(3).setCellValue("성별");
headerRow.createCell(4).setCellValue("전공");
for (collegeStudent s : list) {
Row row = sheet.createRow(rowNo++);
row.createCell(0).setCellValue(s.getStudentId());
row.createCell(1).setCellValue(s.getName());
row.createCell(2).setCellValue(s.getGrade());
row.createCell(3).setCellValue(s.getGender());
row.createCell(4).setCellValue(s.getMajor());
}
response.setContentType("ms-vnd/excel");
response.setHeader("Content-Disposition", "attachment;filename=studentList.xls");
workbook.write(response.getOutputStream());
workbook.close();
}
}
class collegeStudent {
Long studentId;
String name;
int grade;
String gender;
String major;
public collegeStudent(Long studentId, String name,int grade,String gender,String major){
this.studentId = studentId;
this.name = name;
this.grade = grade;
this.gender = gender;
this.major = major;
}
@Override
public String toString() {
return "student [studentId=" + studentId + ", name=" + name + ", grade=" + grade + ", gender=" + gender
+ ", major=" + major + "]";
}
public Long getStudentId() {
return studentId;
}
public void setStudentId(Long studentId) {
this.studentId = studentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
}
5. 엑셀 다운로드 받고 확인하기
화면단에서 url을 호출하면 아래의 그림처럼 엑셀이 다운로드 됨을 알 수 있습니다.
다운 받아진 엑셀을 열어보면 아래와 같이 생성되었음을 알 수 있습니다.
이렇게 POI 라이브러리를 이용해서 엑셀 파일을 내려받는 과정에 대해서 알아봤습니다.
혹시라도 정정할 내용이나 추가적으로 필요하신 정보가 있다면 댓글 남겨주시면 감사하겠습니다.
오늘도 Jindory 블로그에 방문해주셔서 감사합니다.
[ 참조 ]
'개발 > Java' 카테고리의 다른 글
[Java] Java8의 변경사항 (0) | 2022.04.12 |
---|---|
[Java] 함수형 인터페이스(Functional Interface)란? (0) | 2022.04.09 |
[Java] Java 나누기 사용시 주의사항 (0) | 2022.03.09 |
[Java] Json Array 정렬 (0) | 2022.03.06 |
[Java] SMTP와 Mail 발송 (0) | 2022.03.06 |