웹페이지에서 버튼을 누르면 JavaScript로 csv파일을 다운받을 수 있게 만들려고 한다.
여기서 csv는 콤마로 구분된 데이터인데 각 데이터 항목은 콤마로 구분되고 행은 줄 바꿈으로 구분된다.
현재 가지고 있는 data 배열의 각 항목을 csv로 변환해 줄 것이다.
첫번째 행은 미리 추가해주고 다른 행들은 데이터 배열을 처리하여 csv형식으로 바꿔준다.
const getCSV = (filename) => {
let row = [];
let csvdata = [];
row.push("상품명", "가격", "상세 내용");
csvdata.push(row.join(","));
//데이터 배열
data.map((x) => {
row = [];
row.push(x.name, x.price, x.content);
csvdata.push(row.join(","));
});
downCSV(csvdata.join("\n"), filename);
};
이때 각 데이터는 콤마로 연결해서 push해준다.
그리고 csv를 다운로드하는 downCSV 함수에 파라미터를 넘길때는 줄바꿈으로 연결해서 보내준다.
그 이유는 위에서 설명했으니 이해했을거라 믿고...
csv형식으로 바꿔놨으니 이제 다운만 해주면 된다.
// 한글 처리
const BOM = "\uFEFF";
const csvBOM = BOM + csv;
csv에서는 한글이 깨지기 때문에 BOM(Byte Order Mark, \uFEFF)을 추가해준다.
const csvFile = new Blob([csvBOM], { type: "text/csv" });
이제 웹 브라우저에서 직접 파일을 만들거나 조작하려면 Blob(Binary Large Object)이 필요하다. 데이터를 파일처럼 다룰 수 있게 해주는 객체인데 Blob을 만들때 type을 지정하면 csv형식이라는 것을 알릴 수 있다.
const downlink = document.createElement("a");
downlink.download = filename;
downlink.href = window.URL.createObjectURL(csvFile);
<a>
태그를 동적으로 생성하여 download 속성에서 파일 이름을 설정하고 Blob데이터를 실제 파일 URL로 변환하면 브라우저가 이 파일을 다운로드할 수 있게 해준다.
downlink.click();
마지막으로 다운로드 링크를 클릭해준다.
a태그가 DOM에 추가되지 않아도 click() 함수가 잘 작동하기 때문에 DOM에 추가는 불필요하다고 느껴서 안 해줬다.(해줘야한다면... 저에게 알려주세요)
window.URL.revokeObjectURL(url);
위 코드는 Blob 객체를 사용하여 URL을 생성했으니 메모리 누수가 발생하는 것을 방지하기 위해 추가해주었다. 필수는 아니지만, 메모리 관리 측면에서...
여기서 문제가 생겼다.
데이터 자체에 콤마가 포함되어있어서 그 데이터들도 구분되어 들어간 것이다...
그렇지만 걱정 노노
모르면 검색하면 되지 ㅎㅎ
값에 콤마가 있으면 따옴표(")로 감싸면 되는군!
음음 새로운 사실을 알아간다 ^^
그럼 바로 적용!
row.push(`"${x.name}"`, `"${x.price}"`, `"${x.content}"`);
좋아좋아