(수근수근)
[JS] JSON데이터 CSV파일로 저장 본문
해당 글은 클라이언트 측에서 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);
}
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