axios 사용한 excel 파일 다운로드

marie·2024년 8월 30일
0

개발

목록 보기
1/1
post-thumbnail

이번에 회사에서 axios 사용해서 excel 파일 다운로드를 구현하는 개발을 진행했다
그 과정에서 공부하고 배운 내용을 정리해보려 한다😊

조건

백엔드에서 요구한 내용

  • POST 로 통신
  • data는 리스트 형태로 전달
  • Content-Disposition 헤더에서 파일명을 추출

👍🏻 axios POST 톺아보기

기본 형식

axios.post(url[, data[, config]])
  • url : api url 주소
  • data(옵션) : 요청의 본문에 담을 데이터
  • config(옵션) : 요청에 대한 추가 설정을 담은 객체 ( 헤더, 인증, 요청 타임아웃 등 )

🔹 params 전송

api 통신 할 때, 매개변수로 데이터를 전달하는 방식❗
params 속성을 사용하여 전달할 데이터를 객체 형태로 지정

const url = [ 백엔드 통신 api url ]

axios.post(url, null, { params: { key1: value1, key2: value2 } })

🔹 URLSearchParams() 사용하기

( URLSearchParams 필요성에 대한 부연설명은 뒤에 )

const params = new URLSearchParams();
params.append('key1', value1);
params.append('key2', value2);
params.toString();

axios.post(url, null, { params });
  • URLSearchParams() 객체의 append() 메서드를 이용해서 파라미터를 하나씩 추가
  • 문자열로 변환하기 위해 toString() 메서드 사용
url?key1=value1&key2=value2

🔹 data 에 직접 담아 보내기

data 속성에 데이터를 담은 객체를 전달한다
대용량의 데이터나 구조화된 데이터를 전송할 때 유용👍🏻

const data = {
 key1: value1,
 key2: value2,
};

axios.post(url, data);

🔍 URLSearchParams 객체의 필요성

쿼리스트링이란❓

쿼리스트링은 url에서 경로명( pathname ) 다음에 나오는 ? 기호로 시작하는 문자열이다
검색, 필터링, 페이지네이션, 정렬 등 다양한 용도로 사용된다

일반적으로, 웹 서버는 url 쿼리스트링을 분석해서 작업을 수행한다
여러 개의 key와 value의 쌍을 & 기호로 구분하여 매개변수를 나타낸다

url?key1=value1&key2=value2&...

매개변수의 개수가 많아지게 되면❓

길이가 너무 길어져서 읽기가 어렵다💩
만약 다국어나 특수 문자가 포함되어 있으면 인코딩 작업도 필요하다😥

💡 해결

URL API에서 제공하는 URLSearchParams() 를 사용하면 수월하게 쿼리스트링을 다룰 수 있다❗


excel 파일 다운로드 코드 설명

const url = [ 백엔드 통신 api url ]
const data = [
  { key1: value1 }
];

// excel 파일 다운로드 요청
const response = await axios.post(url, data, {
  responseType: 'blob', // 파일 데이터를 Blob으로 받기 위해 설정
});
  • responseTypeblob 으로 설정하여 응답을 Blob 객체 로 받는다
    Blob 객체 는 파일 데이터와 같은 바이너리 데이터를 나타내는 객체이다 ( 여기서는 excel 파일을 의미❗ )
// Content-Disposition 헤더에서 파일 이름 추출
const disposition = response.headers['content-disposition'];
let fileName = 'initialFileName.xlsx'; // 기본 파일 이름

// filename이 존재하는 확인
if (disposition?.indexOf('filename=') !== -1) {
  const fileNameMatch = disposition.match(/filename="([^"]*)"/);
  if (fileNameMatch && fileNameMatch[1]) {
    // URL 인코딩된 파일 이름을 디코딩
    fileName = decodeURIComponent(fileNameMatch[1]);
  }
}
  • response.headers['content-disposition'] : 서버 응답 헤더에서 Content-Disposition 값을 가져온다
    이 헤더에는 서버가 파일을 어떻게 처리하길 원하는지에 대한 정보가 포함되어 있다 ( 나의 경우, 파일 이름이 있음❗ )
  • disposition.match(/filename="([^"]*)"/) : 정규 표현식을 사용하여 filename="파일명" 형식으로 되어 있는 부분 추출
    match() 메서드를 통해 문자열이 정규식과 일치하는 부분을 검색한다
    match() 메서드는 문자열이 정규식과 일치하면, 일치하는 전체 문자열을 첫 번째 요소로 포함하는 Array를 반환한다 ( 나의 경우, fileNameMatch[0]에는 "filename=파일명.xlsx" 이, fileNameMatch[1]에는 "파일명.xlsx" 만 담겨있어서 개발 편의성을 위해 배열 index 1의 값을 사용했다❗ )
  • decodeURIComponent() : URL 인코딩된 파일 이름을 decodeURIComponent() 를 사용하여 디코딩한다
// Blob 데이터를 URL로 변환
const linkUrl = window.URL.createObjectURL(
  new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
);
  • Blob 데이터를 사용해 브라우저에서 사용할 수 있는 임시 url을 생성한다 ( 이 url은 나중에 파일을 다운로드하는 데 사용된다 )
  • 서버에서 받은 응답 데이터를 통해 새로운 Blob객체` 를 생성한다
  • response.data 는 서버에서 받은 바이너리 데이터이다 ( == Blob 데이터 )
  • application/vnd.openxmlformats-officedocument.spreadsheetml.sheet : excel 파일 형식에 맞는 MIME 타입이다 ( 뒤에서 자세히 설명 )
// 링크 생성
const link = document.createElement('a');
link.href = linkUrl;
link.setAttribute('download', fileName); // 다운로드할 파일 이름 설정

// 링크 클릭하여 다운로드 트리거
document.body.appendChild(link);
link.click();
  • document.createElement('a') : 다운로드 링크 ( <a> 태그 )를 동적으로 생성한다
    태그가 실제로 페이지에 표시되지는 않지만, 프로그램적으로 클릭되어 excel 파일을 다운로드하는 기능을 수행한다
  • link.href = linkUrl : 위에서 생성한 Blob urlhref 속성에 할당한다
  • link.setAttribute('download', fileName) : download 속성을 설정한다 ( 파일을 다운로드할 때 파일 이름을 지정 )
  • document.body.appendChild(link) : link를 html <body> 에 추가
  • link.click() : 프로그램적으로 link 클릭하여 excel 파일을 다운로드한다
// 링크 삭제 및 메모리 정리
document.body.removeChild(link);
window.URL.revokeObjectURL(linkUrl);

🔹 필요없는 자원은 메모리에서 정리해주기 🔹

( 자원은 비싸니까...😥 )

  • document.body.removeChild(link) : 프로그램적 link 클릭이 완료된 후, link를 DOM에서 제거한다
  • window.URL.revokeObjectURL(linkUrl) : createObjectURL() 로 생성된 임시 url을 해제한다 ( url로 인한 메모리 점유 해제 )
    해제하지 않으면 메모리에 남아 있어 누수가 발생할 수 있기 때문에, 다운로드가 완료된 후에는 반드시 호출해주기❗

MIME 타입

MIME 타입 은 웹에서 파일의 형식과 내용을 식별하는 데 사용된다
( Microsoft Excel에서 사용하는 최신 스프레드시트 형식 )

MIME 타입 설명

application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

  • application : 파일의 주된 유형 ( 데이터 형식을 의미 )
  • vnd : Vendor 의 약자로, 특정 공급업체나 표준을 나타낸다
  • openxmlformats-officedocument : Open XML 형식의 문서 파일
    Microsoft Office의 Open XML 형식은 .xlsx, .docx, .pptx 등 다양한 문서 파일 형식에 사용된다
  • spreadsheetml.sheet : excel 스프레드시트 파일 형식을 지정한다 ( .xlsx 파일 확장자를 가진 excel 파일 )

excel 파일 MIME 타입의 사용

  • 파일 다운로드 : 웹 애플리케이션에서 사용자가 파일을 다운로드할 때, MIME 타입을 설정하여 브라우저가 파일을 올바르게 처리하고 적절한 프로그램으로(예: excel) 다운로드한다

  • 응답 헤더: 서버에서 클라이언트로 파일을 전송할 때, Content-Type 헤더를 통해 파일의 MIME 타입 을 명시한다
    클라이언트는 이 정보를 바탕으로 파일을 처리한다

profile
FE developer👩🏻‍💻

0개의 댓글