본문 바로가기
Angular.js

[Angular.js] base64데이터를 blob으로 변환 후, xlsx 파일로 다운로드 받기

by 갈잃자 2024. 6. 26.

개요: 고객데이터를 xlsx로 뽑는 기능을 제작하기 위해 공부


 

로직:

1. 클라이언트에서 api 요청하며, json 형태로 고객 데이터를 전달

2. 백엔드에서 받은 데이터를 정제 후, base64(string)으로 인코딩

3. 응답받은 클라이언트는 base64를 blob형태로 디코딩

4. createObjectURL() 함수로, url을 생성한 뒤, a태그를 만들어 클릭시켜 다운로드 받게함

5. 사용된 a태그는 document에서 지움

 

// component.ts  

downloadXlsx() {
    // 요청 및 응답
    this.apiService.makeConsultingXlsxData(this.users as Policyholder[]).subscribe((res) => {
      
      // subscribe 인자값이 응답
      // res.data (base64)를 정제한 뒤, blob 형태의 데이터로 전환
      const blob = new Blob([this.s2ab(atob(res.data))], {
        type: ''
      });

      // blob 데이터를 가지고 url 생성(createObjectURL은 node 내장함수(node_modules/@types/node))
      // a 요소 생성시키고 클릭 후 지워줌
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = 'consulting_data.xlsx';
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      window.URL.revokeObjectURL(url);
    });
  }
  
// 문자열 - 버퍼로 변환하는 코드(https://github.com/SheetJS/js-xlsx/blob/master/README.md)
private s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
  }

 

 

import * as xlsx from 'xlsx';

export async function makeConsultingXlsxDataHandler(req, res) {
  let { policyholders } = req;
  let jsonData = [];
  const workbook = xlsx.utils.book_new();

  for (const policyholder of policyholders) {

    const data = {
      "이름": policyholder.profile.name,
      "생년월일": formatBirth(policyholder.profile.dateOfBirth),
      "전화번호": policyholder.profile.phoneNumber,
      "성별": policyholder.profile.gender,
      "상담신청일자": formatConsultingDate(policyholder.modifiedAt)
    }

    jsonData.push(data);
  }

  // xlsx로 변환할 수 있는 데이터를 제작 후 응답
  // 아래 코드는 xlsx node_module 임
  try {
    const worksheet = xlsx.utils.json_to_sheet(jsonData);
    xlsx.utils.book_append_sheet(workbook, worksheet, 'data');

    const buffer = xlsx.write(workbook, {type: 'base64'});

    return buffer;
  } catch (error) {
    console.error(error);
  }
  
  // timestamp 형식의 데이터를 보기좋게 변환
  function formatBirth(timestamp) {
    const date = new Date(timestamp);
    const yyyy = date.getFullYear();
    const MM = date.getMonth() + 1;
    const dd = date.getDate();

    const birth = `${yyyy}년 ${MM}월 ${dd}일`
    return birth;
  }

  // timestamp 형식의 데이터를 보기좋게 변환
  function formatConsultingDate(timestamp) {
    const date = new Date(timestamp);

    const yyyy = date.getFullYear();
    const MM = date.getMonth() + 1;
    const dd = date.getDate();

    const HH = date.getHours();
    const mm = date.getMinutes();

    return `${yyyy}년 ${MM}월 ${dd}일 ${HH}시 ${mm}분`;
  }
}

 

댓글