본문 바로가기
Dev/reactJS

리액트 api axios 엑셀 다운로드 버튼 구현 react.JS filesaver.saveAs javascript blob response.headers 값에서 filename추출하기

by 허연동백hipublic2020 2022. 2. 4.

목차

    리액트 api 엑셀 다운로드 버튼 구현 filesaver.saveAs javascript blob response.headers 값에서 filename 추출하기 

    리액트를 제대로 시작한지 그리 오래되지 않은 관계로, php나 angular에서는 당연하게 되는 것들이 react에서는 제약이 많은 경우가 있다.

    특히 파일다운로드를 구현하는데 좀 애를 먹긴 하는데, 그게 엑셀 다운로드라면 더...

    일단 엑셀 파일은 백엔드에서 만들어준다 치고...

    api를 통해서 axios로 token을 통해서 인증도 있어야 한다.

    token axios는 별제로 다루도록 하고, 일단 axios instance를 만들어 둔 프로젝트에서 엑셀 다운로드를 구현하는 법은 filesaver컴포넌트를 사용하면 간단하다.

    다만 멋들어지게 filname을 추출하는데 꼼수를 좀 부리긴 했다.

    api를 통해서 엑셀파일을 넘겨받으면 response.headers에 filename이 존재하긴 하지만, file명이 위치한 항목이 content-disposition이라는 항목으로 돼 있다.

    react.JS에서는 리스폰스 헤더 값에서 

    let filename = response.headers.content-disposition

    과 같은 형태로 값을 추출할 수가 없다.

    -를 띄워써버리기 때문이다.

    앵귤러에서는 

    let filename = response.headers.get('content-disposition ')

    와 같이 값을 받을 수 있지만... 리액트는 이것 조차 response.headers.get('content-disposition ')=null이 된다.

    때문에 꼼수로

     let filename = JSON.stringify(res.headers)
            .split("filename=")[1]
            .split('",')[0];

    와 같은 형태로 작성했다.

    리액트 filesaver 콤포넌트 설치는 

    yarn add file-saver

    이렇게 하고,

    import FileSaver from "file-saver";

    임포트해서 사용하면 된다.

    최종적으로 엑셀 다운로드 버튼에서 작동할 함수는 다음과 같다.

      // 엑셀다운
      const handleDown = async (e) => {
        const { cmpgn_title, send_start_dt, send_end_dt } = campaignSearchData;
        let downXls = { send_start_dt: "", send_end_dt: "" };
        downXls.cmpgn_title = cmpgn_title;
        if (send_start_dt !== null) {
          downXls.send_start_dt = changeFormat(send_start_dt, "YYYY-MM-DD");
        }
        if (send_end_dt !== null) {
          downXls.send_end_dt = changeFormat(send_end_dt, "YYYY-MM-DD");
        }
        try {
          const res = await authAxios.get(
            `/api/v1/campaign-report/download?send_start_dt=${downXls.send_start_dt}&send_end_dt=${downXls.send_end_dt}&cmpgn_title=${downXls.cmpgn_title}`,
            { responseType: "blob" }
          );
          console.log("res", res.headers);
          let filename = JSON.stringify(res.headers)
            .split("filename=")[1]
            .split('",')[0];
          FileSaver.saveAs(res.data, filename);
        } catch {}
      };

    게시판에서 시작일, 발송일, 게시명을 검색해서 조건에 해당되는 리스트만 엑셀로 저장하도록 한 것이다.

    별도로 새창열림이라든지 링크(a href)를 이용하지 않고도 바로 다운로드가 가능하다.

    반응형

    댓글