티스토리 뷰
화면에 출력된 HTML 테이블을 엑셀로 export시킬 수 있도록 해달라는 요청사항을 받고 개발을 하던중 마주한 버그에 대해서 정리를 해보려고 해요.
저는 이런 버그가 있는줄 확인 못했는데 사실 오픈하고 나서 버그수정요청이 들어와 알게 되었네용 X(
조회 기간을 선택 후 ' 엑셀로 내보내기 ' 버튼을 누르면 테이블이 CSV파일로 다운로드 되도록 구현했던 로직이에요 !
'click .excel-export-btn' : function(e,t) {
t.list = [{...},{...},{...}...{...},{...},{...}];
let gridData = [];
let initialValue = 0;
(function() {
for(let i=0; i<t.list.length; i++) {
gridData.push({
No : 1+i,
상품명 : t.list[i].productName,
상품가격 : t.list[i].productPrice,
합계 : t.list[i].sum,
전체합계 : ( initialValue += t.list[i].sum ).toLocaleString('kr')
});
}
})();
let showLabel = true;
let row = "";
let index = "";
let arrData = typeOf gridData !== 'object' ? JSON.parse(gridData) : gridData;
let CSV = "";
if(showLabel) {
for(index in arrData[0]) {
row += index + ','
}
row = row.slice(0,-1);
CVS += row + '\u000d\n';
}
let i = 0;
while(i<arrData.length) {
for(index in arrData[i]) {
row += ' "" ' + arrData[i][index] + ' ", ';
}
row.slice( 0 , row.length-1 );
CSV += row + '\u000d\n';
i++
}
if( CSV === ' ' ) {
alert('Invalid data');
return
}
let fileName = '조회기간';
fileName += ' 20190801~20190822';
let uri = 'data:text/cvs;charset=utf-8,\uFEFF' + encodeURI(CSV);
let link = document.createElement('a');
link.href = uri;
link.style = 'visibility:hidden';
link.download = fileName + '.csv';
document.body.appendChild(link);
link.click();
return document.body.removeChild(link);
}
위와 같이 로직을 구현하였을때 조회 기간이 길어지자 CSV파일을 다운로드 받는 도중 '네트워크 오류' 가 뜨는 버그가 발견되었어요.
원인을 찾아본 결과, CSV를 encodeURI( ) 하게 되면서 버그가 발생하게 된것인데, 그 이유는 아래 이미지를 참고해서 설명하도록 할게요.
"안녕하세요"를 hello 라는 변수에 저장한 후 encodeURI( hello )한 결과 escaping 처리가 되면서 알 수 없는 긴 문자열이 된것을 확인 할 수 있었어요 !
따라서 CSV파일을 다운로드 받는 도중 '네트워크 오류' 가 뜨는 버그가 발생한 이유는 조회기간이 길어지자 CSV에 담긴 text양이 많아졌고 그 text를 인코딩하게 되면서 그 양이 방대해져 네트워크가 뻑나게 된거였어요 !
● 해결방법
let uri = URL.createObjectURL(new Blob([CSV], { type: 'text/csv;charset=utf-8;' }));
new Blob[ ]에 CSV라는 많은 양의 binary data를 넣어서 URL.createObjectURL( ) 해주게 되면 한줄의 blob URL이 생성되는 것을 확인 할 수 있어요.
생성된 blob URL을 들어가보면 CSV에 들어있는 text 정보가 모두 들어있는걸 확인할 수 있어요.
이렇게 되면 uri라는 변수 안에 한줄의 blob URL만으로 많은 양의 데이터를 전달 받을 수 있게 되어 네트워크 오류가 발생하는 일은 없겠네요 : )
'Frontend > Javascript' 카테고리의 다른 글
# 데이터 타입 (0) | 2020.10.21 |
---|---|
# TypeScript를 시작하며 (0) | 2020.09.29 |
# Javascript 클로저 (2) | 2020.08.30 |
# export / import (0) | 2019.10.31 |
# express 라우트 메소드 .get()과 .post() (0) | 2019.09.16 |