백엔드에서 받은 데이터를 ‘프론트’에서 가공해 CSV 로 파일을 생성해야했다.
(사프에서는 백엔드 친구들이 CSV출력 형태로 가공해줬는데,, 보고싶어 얘들아)
전회사에서는 프론트가 먹혀서 무조건 백엔드가 편한대로 까라면 까야했음ㅠ
라이브러리는 react-csv를 사용할거임. << 얘가 csv 변환중에 가장 유명한 듯
https://github.com/react-csv/react-csv
npm install react-csv --save;
원래 헤더랑, 바디랑 따로 정해서 표 하나를 만들수 있는데 나는 하나의 시트에 여러개의 표를 보여줘야해서 젤 기본 사용법으로 씀
컴포넌트는 2개를 제공하는데 어떻게 다운로드 할 지를 정한다
CSVLink
: 클릭으로 csv 다운로드CSVDownload
: 마운트되면 바로 다운로드나는 클릭해서 다운로드 할 것이기 때문에 CSVLink를 사용한다.
data는 배열형식으로 넣으면 되고 filename은 실제로 다운로드 되었을 때 어떤 이름으로 다운될지이다.
const csvData:string[][] = [...]
...
<CSVLink data={csvData} filename={'example.csv'} style={{ display: 'none' }} />
data는 행열 그대로 csv 첫번째 칸부터 순서대로 채워짐.
만약 CSVLink에 ref를 사용하고 싶은데 typescript로 작성중이면 아래 타입할당하면 된다.
const csvRef = useRef<CSVLink & HTMLAnchorElement & { link: HTMLAnchorElement }>(null)
표의 헤더를 강조하는 스타일을 적용하고 싶을 때는 제목행에 해당하는 배열을 headers Props로 넘긴다.
const headers = ['A', 'B', 'C'];
...
<CSVLink headers={headers} data={csvData} filename={'example.csv'} >
다운로드
</CSVLink>
만약 일반 배열이 아니라 객체배열형식으로 만든다면 헤더의 label값과 데이터의 속성 값을 맞춰서 렌더링 해준다.
const headers = [
{label: 'ID', key: 'id'},
{label: 'Name', key: 'name'},
{label: 'Age', key: 'age'},
]
const csvData = [
{id: 1, name: 'rulu', age: '20'},
{id: 2, name: 'alice', age: '21'},
...
]
<CSVLink headers={headers} data={csvData} filename={'example.csv'} >
다운로드
</CSVLink>
나는 하나의 시트에 여러개의 표가 나와야해서 헤더를 별개로 만들지 않고 이중배열을 이용해서 표 데이터를 채워넣었다.
진짜 코드 더럽고 이상하지만 어쩔 수 없슴.,.ㅠ
각 형태별 csv 표 데이터를 구한 다음에 데이터가 있으면 제목과 함께 표를 렌더링함.
// csv 데이터 만들어서 넣기
useEffect(() => {
const { card } = generateCardCSVData(...)
const { graphChart } = generateGraphChartCSVData(...)
const { pieChart } = generatePieChartCSVData(...)
const { heatmapChart } = generateHeatmapChartCSVData(...)
setCSVData(() => {
const data: string[][] = []
let index = 1
if (!isEmpty(card)) {
data.push([`${index++}. 요약`], ...card, [''])
}
if (!isEmpty(graphChart)) {
data.push([`${index++}. ${timeUnit === '1h' ? '시간' : '기간'}별 데이터`], ...graphChart, [''])
}
if (!isEmpty(pieData)) {
data.push([`${index++}. 비율`], ...pieChart, [''])
}
if (!isEmpty(heatmapChart)) {
data.push([`${index++}. 히트맵`], ...heatmapChart)
}
if (isEmpty(data)) {
data.push(['다운로드 할 데이터가 없습니다.'])
}
return [...data]
})
}, [rowCardData, rowChartData])
이런식의 결과물이 나온다.
CSV자체는 안어려웠는데 네트워크 탭 보면서 데이터 구조 분석해서 분기처리하는게 개빡셌음 진짜..
지금 생각해도 스웨거도 명세서도 없이 네트워크 탭으로 개발하라는건 레전드였다