반응형
목차
아래 포스팅에서 이어진 내용입니다.
모듈화 ver 1에서는 화면이 늘어나고 구분자가 늘어남에 따라 ExcelUtil의 static method가 길어진다는 단점이 있어서 불편했다.
그래서 더 고민 끝에 구분자에 따른 시트명, 파일명, 헤더정보를 별도의 파일로 빼기로 했다.
이렇게 되면 파일에 내용만 추가하면 되고 소스는 건드릴 필요가 없게된다.
pages.json(시트명, 파일명, 헤더 정보가 있는 파일) resources 하위에 생성
{
"comments": {
"description": "이 파일은 엑셀 다운로드에 사용되는 엑셀 정보를 포함합니다.",
"fileType": "json"
},
"singer": {
"sheetName": "가수시트",
"fileName": "가수",
"headers": ["아이디", "이름", "직업"]
},
"currency": {
"sheetName": "통화시트",
"fileName": "통화",
"headers": ["나라", "통화"]
},
"actor": {
"sheetName": "배우시트",
"fileName": "배우",
"headers": ["성명", "연기력"]
}
//필요 시 추가..
}
PageInfo
package study.dev.thboard3.board.file.web;
import lombok.Data;
@Data
//pages.json의 필드를 담을 객체
public class PageInfo {
private String sheetName; //시트명
private String fileName; //엑셀파일명
private String headers[]; //헤더 목록
}
Controller
매개변수 개수가 줄었다.
package study.dev.thboard3.board.file.web;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import study.dev.thboard3.board.file.service.ExcelService;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
@Slf4j
@RequiredArgsConstructor
public class ExcelController {
private final ExcelService excelService;
/**
* 엑셀 다운로드 처리
* @param paramData
* @param pageGubun
* @param response
*/
@GetMapping("/exceldownload")
public void downloadExcel(@RequestParam(name = "selectedData") String paramData,
@RequestParam(name = "pageGubun") String pageGubun,
HttpServletResponse response) throws IOException {
excelService.download(paramData, response, pageGubun);
}
}
Service
package study.dev.thboard3.board.file.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
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.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import study.dev.thboard3.board.file.web.PageInfo;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
@Service("excelService")
public class ExcelService {
@Value("classpath:pages.json")
private Resource pagesJsonResources;
/**
* 엑셀 다운로드 처리
* @param paramData
* @param response
* @param pageGubun
* @throws IOException
*/
public void download(String paramData, HttpServletResponse response, String pageGubun) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
//json파일에서 페이지 정보 읽어서 map으로 반환
Map<String, PageInfo> pageMap = objectMapper.readValue(pagesJsonResources.getInputStream(), new TypeReference<Map<String, PageInfo>>() {});
//구분자에 해당되는 json파일의 내용이 담긴 객체
PageInfo pageInfo = pageMap.get(pageGubun);
// map타입의 list로 반환
List<Map<String, String>> dataList = convertJsonToList(paramData);
if (pageInfo != null) {
// 엑셀 생성/다운로드 처리
excelParsingProcess(dataList, response, pageInfo.getSheetName(), pageInfo.getFileName(), pageInfo.getHeaders());
}
}
/**
* 엑셀 파싱, 다운로드 처리
* @param dataList
* @param response
* @param sheetName
* @param fileName
* @param headers
* @throws IOException
*/
private void excelParsingProcess(List<Map<String, String>> dataList,
HttpServletResponse response,
String sheetName,
String fileName,
String[] headers) throws IOException {
//엑셀 생성
Workbook wb = new XSSFWorkbook();
//시트 생성
Sheet sheet = wb.createSheet(sheetName);
// header row 세팅
Row headerRow = sheet.createRow(0);
int cellNum = 0;
for (String header : headers) {
//헤더값 세팅
headerRow.createCell(cellNum++).setCellValue(header);
}
// body row 세팅
int rowNum = 1;
for (Map<String, String> data : dataList) {
Row row = sheet.createRow(rowNum++);
cellNum = 0;
//데이터 세팅
for (String key : data.keySet()) {
row.createCell(cellNum++).setCellValue(data.get(key));
}
}
String extension = ".xlsx";
// HTTP 응답 설정
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName + extension, "UTF-8"));
wb.write(response.getOutputStream());
wb.close();
}
/**
* json 형식 데이터를 map타입의 list로 반환한다.
* @param jsonData
* @return
* @throws JsonProcessingException
*/
private List<Map<String, String>> convertJsonToList(String jsonData) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(jsonData, new TypeReference<List<Map<String, String>>>() {});
}
}
ver 1의 ExcelUtil 클래스는 삭제해도 된다.(pages.json로 대체)
테스트
개인 스터디 기록을 메모하는 공간이라 틀린점이 있을 수 있습니다.
틀린 점 있을 경우 댓글 부탁드립니다.
반응형
'IT > development' 카테고리의 다른 글
[JavaScript] selectbox 동적 표시 (59) | 2024.01.21 |
---|---|
[jQuery] 전체 체크박스 체크 (61) | 2024.01.21 |
[spring] spring excel download 모듈화 ver 1 (41) | 2024.01.14 |
[spring] spring excel download (feat. 체크박스) (41) | 2024.01.13 |
[IDE] IntelliJ jdk 버전 변경 (21) | 2023.12.30 |