2020.11.13
서버에 업로드되어 있는 파일을 읽은 후 데이터를 추가(수정)하고 다운로드하는 기능 구현
- 업로드되어 있는 파일 (양식)
- DB에 저장된 데이터를 엑셀에 추가
사용
- HttpServletRequest, HttpServletResponse
- FileInputStream
- XSSFWorkbook
- ServletOutputStream
1. Controller
API를 호출하면 엑셀다운로드 기능을 제공하는 Service를 호출한다.
@GetMapping(value = "/v1/cpnType/{cpnTypeId}/promotion/iss/{issDstrSeq}/target/excel/down")
public void excelDownloadIssTarget(HttpServletRequest request, HttpServletResponse response,
@PathVariable(value = "cpnTypeId") Long cpnTypeId, @PathVariable(value = "issDstrSeq") Long issDstrSeq) {
PromCpnIssTgtr promCpnIssTgtr = new PromCpnIssTgtr();
promCpnIssTgtr.setCpnTypeId(cpnTypeId);
promCpnIssTgtr.setIssDstrSeq(issDstrSeq);
promotionCpnIssTgtrService.excelTypeTargetExcelDownload(request, response, promCpnIssTgtr);
}
2. HttpServletResponse header설정
서블릿을 이용하여 엑셀 다운로드기능 구현
엑셀 파일을 출력하기 위해 서블릿의 헤더를 설정해주는 메소드 구현.
궁금증)
1. 서블릿의 헤더에서 각각 키의 역할이 궁금하다.
public class ExcelUtils {
public static final Logger logger = LoggerFactory.getLogger(ExcelUtils.class);
public static void setServletHeader(HttpServletResponse response, String fileName)
{
String headerKey = "Content-Disposition";
String headerValue = "attachment; filename=".concat(fileName);
response.setContentType("application/octet-stream");
response.setHeader(headerKey, headerValue);
}
}
3. 엑셀파일 읽기, 수정, 다운로드 - FileInputStream, POI(XSSF), ServletOutputStream
엑셀파일 읽기 - FileInputStream
FileInputStream vs FileOutputStream
https://hyeonstorage.tistory.com/236
FileInputStream
- InputStream 클래스를 상속받은 후손 클래스이다.
- 하드 디스크상에 존재하는 파일을 바이트 단위로 입력을 받는 클래스이다.
- 이 클래스는 출발지점과 도착지점을 연결하는 통로(?)로, 즉 스트림을 생성하는 클래스이다.
생성자 | 설명 |
new FileInputStream(String); | filepath로 지정한 파일에 대한 입력 스트림을 생성한다. FileNotFoundException 발생 |
new FileInputStream(File); | fileObj로 지정한 파일에 대한 입력 스트림을 생성한다. FileNotFoundException 발생 |
new FileInputStream(FileDescriptor); | fdObj 로 기존의 접속을 나타내는 파일 시스템의 입력 스트림을 생성한다. SecurityException 발생 |
FileOutputStream
- OutputStream 클래스의 후손 클래스
- 바이트 단위로 파일에 출력을 하는 클래스이다.
엑셀파일 수정 - POI (XSSF)
HSSFWorkbook vs XSSFWorkbook vs SXSSFWorkbook
http://poi.apache.org/components/spreadsheet/
HSSFWorkbook
- 엑셀 97~2003버전을 위한 Workbook
- .xls 파일형식만을 다룬다.
XSSFWorkbook
- 2007이상의 버전을 위한 Workbook
- .xlsx 파일형식을 다룬다.
- XSSF는 문서의 모든 행에 대한 액세스를 제공하여 SXSSF보다 메모리사용량이 높다.
SXSSFWorkbook
- XSSF의 성능을 개선한 버전으로, 대용량 스프레드 시트를 위한 Workbook이다.
- XSSF와 다르게 슬라이딩 윈도우 내에 있는 행에 대한 액세스를 제한하여 XSSF보다 메모리 사용량을 줄였다.
- 한 시점에 제한된 수의 행만 액세스 할수 있다.
- Sheet.clone()이 지원되지 않는다.
엑셀파일 다운로드 - ServletOutputStream
docs.oracle.com/javaee/7/api/javax/servlet/ServletOutputStream.html
궁금증)
1. ServletOutputStream과 FileOutputStream의 차이
2. HttpServletResponse에 헤더를 설정해줬는데 이거랑 관려이 있나? 두개가 전혀 다른 역할을 하는 것인가? 그럼 각각 정확히 어떤 기능을 제공해 주는것이고 왜 있는것인가?
3. 아래 코들르 보면 ServletOutputStream을 생성하고 XSSFWorkbook에 write를 했다. 두개의 연관성은? 이렇게해서 다운로드가 되는건가? 어떻게 되는건가?
public void excelTypeTargetExcelDownload(HttpServletRequest request, HttpServletResponse response, PromCpnIssTgtr obj) {
if(ObjectUtils.isEmpty(obj.getIssDstrSeq()) || ObjectUtils.isEmpty(obj.getCpnTypeId())) {
return;
}
// DB에 저장된 데이터
List<PromCpnIssTgtr> list = this.listPromCpnIssTgtrWithName(obj);
// 엑셀 다운로드
FileInputStream fin = null;
try {
// 엑셀 양식 파일 읽어오기
// 문자열 형태의 파일경로명으로 읽을 파일 지정
fin = new FileInputStream(request.getSession().getServletContext().getRealPath(CpnConstants.ISS_TARGET_EXCEL_FORMAT_PATH));
XSSFWorkbook wb = new XSSFWorkbook(fin);
// 엑셀 양식 파일 수정 (=DB에 저장된 발행/배포대상자 정보를 엑셀에 입력)
XSSFSheet sheet = wb.getSheetAt(0);
XSSFRow row = null;
XSSFCell cell = null;
int rowIdx = 0;
for(PromCpnIssTgtr pcit : list) {
row = sheet.createRow(++rowIdx); // start index 1 row, already input index 0 row.
// account no.
cell = row.createCell(0);
cell.setCellValue(pcit.getMbsAccNo());
// account name
cell = row.createCell(1);
cell.setCellValue(pcit.getAccNm());
// phone
cell = row.createCell(2);
cell.setCellValue(pcit.getPhoneNo());
// email.
cell = row.createCell(3);
cell.setCellValue(pcit.getEmailAdr());
}
// 엑셀 파일 출력
ServletOutputStream outputStream = response.getOutputStream();
wb.write(outputStream);
wb.close();
outputStream.close();
// 엑셀파일 다운로드를 위한 서블릿 헤더 설정
ExcelUtils.setServletHeader(response, this.getExcelFileName(obj) + ".xlsx");
} catch(Exception e) {
throw new CpnRuntimeException();
} finally {
try {
if (fin != null) {
fin.close();
}
} catch (Exception ex) {
LOGGER.error(ex.toString(), ex);
} finally {
fin = null;
}
}
}
'Language > JAVA' 카테고리의 다른 글
[JAVA] ReflectionUtil (0) | 2020.11.30 |
---|---|
[JAVA] AES256, SHA256 - 암호화 복호화 (0) | 2020.11.30 |
[JAVA] FilterChain, doFilter - API 호출 기록 DB에 저장하기 (0) | 2020.11.19 |
[JAVA] 두개 Object의 값 비교하기 (0) | 2020.11.19 |
[JAVA] Map to Object, Object to Map (0) | 2020.11.19 |