(수근수근)

[JS] JSON데이터 CSV파일로 저장 본문

type & Javascript

[JS] JSON데이터 CSV파일로 저장

InformationFarm 2021. 9. 26. 19:13
해당 글은 클라이언트 측에서 JSON데이터를 CSV파일로 내보내는 방법을 정리하였습니다.

📓 JSON 데이터

  • JSON의 KEY형태는 항상 String이다.
  • JSON의 VALUE 형태는 아래의 형식 중 하나여야한다
    • String
    • Number
    • JSON Object
    • Array
    • Boolean
    • Null
  • JSON의 형태는 아주 까다롭다. 따라서 사소한 실수는 절대 허용하지 않는다.
  • 순수하게 데이터 포맷이기 떄문에 프로퍼티만 담을 수 있다. 메서드는 담을 수 없습니다.

👾 Function, Data, undefined의 형태는 값으로 사용 불가합니다.

{
    "이름":"심주하",
    "나이" : 10,
    "가족":{ "동생1":"심민하", "동생2":"심세하"},
    "취미" : ["JS", "HTML", "CSS"],
    "자차소유" : true,
    "남친유무" : null
}

💻 JSON데이터 CSV파일 변환 소스코드

json데이터의 형태에 대해서 알아봤으니 실제 소스코드를 먼저 보면서 이해해봅시다.

1. CSV파일을 다운할 버튼 생성

해당 디자인은 ReactUI antd를 활용하여 개발하였습니다.

<Button type="primary" onClick={this.downloadCSV}>download CSV</Button>

2. downloadCSV function 소스 구현

전체소스는 아래 토글에 있습니다.

더보기

 

downloadCSV = () => {
    const data = this.props.data;
    const jsonData = JSON.stringify(data);
    let arrData = JSON.parse(jsonData);
    let CSV = '';
    CSV += "IVR채널" + '\r\n\n';

    let row = "";
    for (let index in arrData[0]) {
        row += index + ',';
    }
    row = row.slice(0, -1);
    CSV += row + '\r\n';

    for (let i = 0; i < arrData.length; i++) {
      let row = "";
      for (let index in arrData[i]) {
          row += '"' + arrData[i][index] + '",';
      }

      row.slice(0, row.length - 1);
      CSV += row + '\r\n';
    }

    if (CSV == '') {        
        alert("Invalid data");
        return;
    }   
  
    let fileName = "MyReport_";
    fileName += "IVR채널".replace(/ /g,"_");   
    
    //Initialize file format you want csv or xls
    let uri = 'data:text/csv;charset=utf-8,' + escape(CSV);
    
    let link = document.createElement("a");    
    link.href = uri;
    link.style = "visibility:hidden";
    link.download = fileName + ".csv";
    
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }

csv파일로 내보낼 데이터 형태

1. props로 받아온 데이터를 JSON형태로 파싱해준다.

(기존 데이터의 포맷이 JSON이라면 생략가능)

const data = this.props.data; //이 데이터가 JSON이라면 아래코드는 생략가능합니다
const jsonData = JSON.stringify(data);
let arrData = JSON.parse(jsonData);

2. 데이터 정의 및 첫째줄에 Title을 설정해줍니다.

(Title을 설정하고 싶지 않다면 생략가능)
\n 한 줄 띄기

let CSV = '';
    CSV += "TITLE" + '\r\n\n';

3. JSON의 KEY를 열의 데이터 라벨로 넣기

let row = "";
    for (let index in arrData[0]) {
        row += index + ',';
    }
    row = row.slice(0, -1);
    CSV += row + '\r\n';
  • csv에서는 , (comma)가 구분자의 역할을 합니다.
  • slice(0, -1) JSON데이터의 key부분만 가져옵니다.

4. JSON데이터 value값 넣기

우리는 기존에 행 형태로 데이터가 정의되어 있던 것을 CSV에서는 열 형태로 데이터 구조를 가지고 가야한다. 따라서 이 부분을 보여주기 위해 이중 포문을 활용한다

for (let i = 0; i < arrData.length; i++) {
      let row = "";
      for (let index in arrData[i]) {
          row += '"' + arrData[i][index] + '",';
      }

      row.slice(0, row.length - 1);
      CSV += row + '\r\n';
    }

이렇게 데이터를 돌아가면서 CSV에 , 를 구분자로 문자열로 만들어주면 데이터 포멧팅은 끝난다.

 

5. URI 식별자 정의 및 다운로드 하기

URI(Uniform Resource Identifier, 통합 자원 식별자)는 언제 어디서든 늘 같은 리소스(텍스트, 이미지, 비디오 등)를 보여줄 수 있도록 해주는 식별자이다.

let uri = 'data:text/csv;charset=utf-8,' + escape(CSV);
let link = document.createElement("a");    
    link.href = uri;
    link.style = "visibility:hidden";
    link.download = fileName + ".csv";

        document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  • escape() 함수
    • 아스키문자에 해당하지 않는 문자들은 유니코드로 변환시켜줍니다.
  • a태그의 다운로드 속성
    • 브라우저는 태그에 download 속성이 설정되어 있으면 링크가 가리키는 파일을 다운로드한다.
    • HTML5가 도입되면서 웹 브라우저에서도 바이너리 콘텐츠를 생산하는 경우가 많아졌는데(이미지 편집, 사운드 편집, Blob 등) 이를 사용자가 다운로드하려면 일단 서버로 보낸 뒤 서버가 전송해주는 비효율적인 방법을 사용하거나 사용자가 링크 위에서 문맥 메뉴(context menu)를 사용해 링크의 내용을 다운로드 받도록 해야 한다. 하지만 download 속성을 두면 링크를 무조건 다운로드 받도록 만들 수 있다.

👾 한글깨짐 현상

🌟 해결방법

let uri = 'data:text/csv;charset=utf-8,\uFEFF' + encodeURI(CSV);

해당 현상이 생기는 이유는 UTF-8인코딩 방식에서 Byte Order Mark(BOM)이 문제를 일으킬 수 있기 때문입니다.

자세한 설명은 아래 URL에 있습니다 ㅎㅎ

http://blog.wystan.net/2007/08/18/bom-byte-order-mark-problem

'type & Javascript' 카테고리의 다른 글

[NodeJS] Hello Node  (0) 2021.10.03
[NodeJS] Nodejs 기초  (0) 2021.10.01
[JS] 콜백함수  (0) 2021.09.15
[JS] expression & operator  (0) 2021.09.11
변수와 상수  (0) 2021.09.11
Comments