728x90
반응형
이전 포스팅에 이어간다.
https://123okk2.tistory.com/509
이번에는 OpenCSV를 활용한 csv 파일 만들기이다.
DB에서 데이터를 가져왔다 가정하고, 해당 데이터를 csv 팡ㄹ로 만들어 사용자에게 파일을 제공하는 코드를 공유하려고 한다.
코드 작성
작성 방법은 별게 없다. 그냥 String[]을 CSVReader.writeNext()의 파라미터로 입력만 해주면 된다.
DownloadService.java
package com.mwlee.test.service;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
import com.opencsv.CSVWriter;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class DownloadService {
// 엑셀 파일로 만들 데이터
// 실구현에서는 DB에서 쿼리 결과로 가져온 것.
private List<Map<String, Object>> result = new ArrayList<>();
/**
* 원래는 DB에서 데이터를 빼와야하지만,
* 굳이 그럴 필요 없으므로 가라 데이터 생성
*/
@PostConstruct
private void setDate() {
// result 세팅
// 컬럼들
String[] columns = new String[] {
"col_1",
"col_2",
"col_3"
};
Map<String, Object> firstRow = new HashMap<>();
firstRow.put(columns[0], 1);
firstRow.put(columns[1], "a");
firstRow.put(columns[2], "20240101");
result.add(firstRow);
// 1번 데이터 빼기
Map<String, Object> secondRow = new HashMap<>();
secondRow.put(columns[0], 2);
secondRow.put(columns[2], "20240102");
result.add(secondRow);
// 3번 데이터 빼기
Map<String, Object> thirdRow = new HashMap<>();
thirdRow.put(columns[0], 3);
thirdRow.put(columns[1], "b");
result.add(thirdRow);
}
/**
* CSV 파일을 만들어 전송
* @return
*/
public byte[] generateCsv() {
try {
// 필요 stream 및 writer 선언
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
CSVWriter csvWriter = new CSVWriter(writer);
// 맨 위에 각 컬럼명 작성
List<String> keys = new ArrayList<>(result.get(0).keySet());
csvWriter.writeNext(keys.toArray(new String[0]));
// 둘째 줄부터 데이터 삽입
for(Map<String, Object> data : result) {
// row 생성
// keys의 length 만큼 row 생성
String[] rowData = new String[keys.size()];
int index = 0;
for(String key : keys) {
if(data.get(key) == null) {
// 데이터가 없으면 빈 값
rowData[index++] = "";
}
else {
// 데이터가 존재하면 String으로 변환해서 입력
rowData[index++] = data.get(key).toString();
}
}
csvWriter.writeNext(rowData);
}
// csvWriter close 및 byte[]를 return
csvWriter.close();
return outputStream.toByteArray();
}
catch(Exception e) {
e.printStackTrace();
return new byte[] {};
}
}
}
이제 서비스에서 파일을 가져와 사용자에게 다운로드 파일을 제공하는 컨트롤러이다.
DownloadRestController.java
package com.mwlee.test.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DownloadRestController {
@Autowired DownloadService service;
@GetMapping("/download/csv")
public ResponseEntity<Resource> downloadCsv() {
byte[] excelData = service.generateCsv();
if(excelData == null || excelData.length == 0) {
return ResponseEntity.internalServerError().build();
}
Resource resource = new ByteArrayResource(excelData);
return ResponseEntity.ok()
.contentType(
MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
)
// 파일명 입력
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"test-download-csv.csv\"")
.body(resource);
}
}
테스트
위에서 입력한 /download/csv url로 들어가서 파일을 다운로드받아보자.
728x90
반응형
'실습 > [스프링 부트] 채팅 웹 사이트 만들기' 카테고리의 다른 글
[Thymeleaf] Lang 설정을 통한 다국어 페이지 제공 (0) | 2024.06.10 |
---|