일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- react
- JavaScript
- 코딩테스트 고득점 Kit 완전탐색
- 자바스크립트
- React JS
- Java
- 자바 공부
- 디자인 패턴
- 리액트
- 코딩테스트 고득점 Kit
- 리액트 훅
- useState
- design pattern
- 자바
- codesandbox
- 백준
- 데이터모델링과마이닝
- react firebase
- 장고
- websocket
- react hook
- 프로그래머스
- 코틀린
- NextJS
- 컴퓨터 네트워크
- 프로그래밍 언어론
- 프로그래머스 완전탐색
- useEffect
- vanillaJS
- 프로그래머스 자바
- Today
- Total
기록하는 개발자
[React] React+typescript에서 엑셀(csv)다운로드 구현 본문
위와 같이 진행 중인 프로젝트에서는 시작, 종료 날짜 입력 후 버튼을 클릭 하면
해당 기간에 대한 직원들의 출근부를 엑셀 파일로 추출해주는 기능이 있다.
서버에서 파일을 만들어서 넘겨주는 것보다 프론트에서 작업하는 것이 훨씬 빨랐다.
react-csv라는 훌륭한 라이브러리가 있기 때문이다🥹🥹🥹
1. 라이브러리 react-csv 다운로드
// npm
npm install react-csv --save;
// yarn
yarn add react-csv
// typescript
npm install --save @types/react-csv
2. react-csv의 컴포넌트
react-csv는 CSVLink 와 CSVDownload 두 가지 컴포넌트를 제공한다.
내가 사용한 기능은 사용자가 버튼을 클릭했을 때 csv 파일이 다운로드 되는 CSVLink 이다.
- CSVLink :해당 링크를 클릭하면 csv 파일을 다운받을 수 있다.
- CSVDownload : 해당 컴포넌트가 마운트 될 때 자동으로 csv가 다운로드 된다.(엑셀 파일 다운로드가 필요한 시점이 마운트될 때가 아니라면 사용을 권장하지 않는다.)
3. react-csv의 props
CSVLink 컴포넌트에서는 여러가지 props 를 사용할 수 있다.
아래의 네 가지 외에도 더 많은 props가 있으니 공식 홈페이지를 참고하자.
- data : csv 파일에서 정보가 들어가는 부분으로 이중배열, 객체 배열, 문자열 형식으로 사용 가능
- header : csv 파일에서 필드를 지정할 수 있는 부분으로 label과 key값 부여 가능
- filename : 다운로드 받는 csv 파일의 이름을 지정
- onClick : 링크를 클릭 시 동기/비동기적으로 작업 수행 시 사용
4. header와 data
const headers = [
{ label: "이름", key: "name" },
{ label: "전화번호", key: "number" },
{ label: "이메일", key: "email" }
];
const data = [
{ name: "kim", number: "1234", email: "kim@gmail.com" },
{ name: "lee", number: "7890", email: "lee@naver.com" },
{ name: "park", number: "4567", email: "park@daum.com" }
];
header에는 label과 key가 있다.
label은 실제 엑셀 파일 상단에 표시되는 값이다.
key는 해당 필드의 키 값으로, 위와 같이 data 내 { key : value } 형태에서의 key값과 동일해야한다.
사용자 시나리오
시작 날짜와 종료 날짜를 입력 받는다 ↓ |
버튼을 클릭 한다 ↓ |
입력받은 기간에 대한 출근부 데이터를 서버로부터 받아온다 ↓ |
데이터 길이 > 0 : 엑셀 파일을 다운로드 한다. 데이터 길이 == 0 : window.alert("해당 기간에 출근부 데이터가 없습니다.") |
ExcelDownload.tsx
날짜를 입력 받고 버튼을 클릭한 뒤에 엑셀 파일을 만들 데이터를 받아오기 때문에
데이터를 모두 받아온 뒤 파일 다운로드가 이루어져야 한다.
따라서 CSVLink 컴포넌트에 useRef를 사용해 ref 속성을 넣어주고
데이터가 변경 되면 useEffect를 통해 csvlink의 click() 함수를 실행했다.
import { useState, useRef, useEffect } from "react";
import { CSVLink } from "react-csv";
import { GetExcelDataApi } from "../../../api/workcheck";
import * as type from "../type";
const ExcelDownload = ({ startTime, endTime }: type.ExcelDownloadProps) => {
const header = [
{ label: "날짜", key: "date" },
{ label: "직원명", key: "name" },
{ label: "근무 시간", key: "time" },
{ label: "근무 형태", key: "workType" },
{ label: "총 근무 시간", key: "totalWorkTime" },
];
const [excelData, setExcelData] = useState<Array<type.excelDataProps>>([]);
const csvLink = useRef<
CSVLink & HTMLAnchorElement & { link: HTMLAnchorElement }
>(null);
useEffect(() => {
if (excelData.length > 0) {
csvLink?.current?.link.click();
setExcelData([]);
}
}, [excelData]);
const getWorkcheckData = async () => {
if (startTime == "") window.alert("시작일을 입력해주세요");
else if (endTime == "") window.alert("마감일을 입력해주세요");
else {
GetExcelDataApi({ startTime, endTime, setExcelData });
}
};
return (
<div>
<button className="getFileButton" onClick={getWorkcheckData}>
출근부 엑셀 파일 다운로드
</button>
<CSVLink
data={excelData}
headers={header}
filename="출근부.csv"
className="hidden"
ref={csvLink}
target="_blank"
/>
</div>
);
};
export default ExcelDownload;
csvLink의 useRef 선언과 useEffect
- ref 의 current를 사용하여 click 함수 실행 후
의존성 배열에 excelData 있으므로 excelData를 초기화한다.
const csvLink = useRef<
CSVLink & HTMLAnchorElement & { link: HTMLAnchorElement }
>(null);
useEffect(() => {
if (excelData.length > 0) {
csvLink?.current?.link.click();
setExcelData([]);
}
}, [excelData]);
typescript 에서 useRef를 사용하기 위해서는 위와 같이
CSVLink & HTMLAnchorElement & { link: HTMLAnchorElement }
를 type으로 넣어주어야 에러가 발생하지 않는다.
Header.tsx
import ExcelDownload from "./ExcelDownload";
const Header = () => {
...
return (
<div>
...
<ExcelDownload startTime={startTime} endTime={endTime}></ExcelDownload>
</div>
);
};
export default Header;
다운로드 받은 엑셀 파일
참고
https://developer-talk.tistory.com/106
https://stackoverflow.com/questions/65611889/how-to-add-ref-to-csvlink-in-react-typescript
'Web > React' 카테고리의 다른 글
React와 Vue (0) | 2024.03.05 |
---|---|
[React] React에서 chartJs data label 추가하기 (0) | 2023.04.25 |
[React] react-select를 사용해보자 (1) | 2023.04.07 |
[React] React+typescript에서 chartJs의 update() 사용법 (0) | 2023.04.07 |
[React] axios interceptor를 이용한 token refresh (1) | 2023.04.07 |