본문 바로가기

Javascript/Node.js

query 결과 csv로 저장하기

Node.js 서버 개발을 하던중 query 결과를 csv로 저장해줘야 하는 일이 있었는데 한글이 포함되어 있다 보니 파일내 한글들이 깨지는 이슈가 있었다. 단순히 query를 날려서 결과를 받아오면 결과물인 json 데이터를 parsing 하여 파일에 ','로 구분자를 두고 write하는 방식으로 구현하였기 때문에 query 결과에서의 한글이 깨지지 않았다면 특별히 문제될 것이 없다고 생각했었다. 실제로 query 결과에서는 한글이 전혀 깨지지 않고 있었다.


하지만 재밌게도 Notepad로 파일을 열면 한글이 정상적으로 보이는데, AcroEdit나 Excel로 파일을 열면 한글이 깨지는 것이었다. 지금이야 재밌지만 개발할 때는 재미없었다. 심지어 Notepad로 열었던 파일을 다시 저장하기만 누르고 다시 Excel 등에서 열어주면 정상적으로 한글이 깨지지 않고 나왔기 때문에 원인이 무엇인지 추적하기가 쉽지 않았다. 구글링을 통해서 알게된 것은 csv 파일을 로드할 때 한글 깨지는 현상이 빈번하다는 것이고 그럴 때는 내가 시도했던 것처럼 Notepad로 열고 저장을 다시 해주는 방식으로 문제를 해결하고 있다는 것이었다. 조악하기 짝이 없다... 어쨌든 그렇다고 매번 그렇게 해줄수는 없는 노릇이라 csv를 내가 직접 write해주는 것이 아니라 npm에 있는 모듈을 이용하기로 했다. 내가 사용한 것은 xlsx 라는 모듈인데 원래는 Excel을 읽거나 저장하는 경우 범용적으로 사용되는 모듈이다. 하지만 해당 모듈에는 csv로 work sheet를 컨버팅해주는 기능이 있다. 이를 통해서 csv 저장시 한글 깨지는 현상을 해결했다. 


아래는 json data와 file name을 parameter로 넘겨받았을 때 파일을 저장하도록 구현한 function이다.


const xlsx = require('xlsx');
const fs = require('fs');

exports.saveXLSXWithJSON = (data, fileName) => {
const workSheet = xlsx.utils.json_to_sheet(data);

// excel로 저장하는 경우
// const workBook = xlsx.utils.book_new();
// xlsx.utils.book_append_sheet(workBook, workSheet, 'temp');

// xlsx.writeFile(workBook, __dirname + '/../temp/' + fileName + '.xlsx');

// csv로 저장하는 경우
const stream = xlsx.stream.to_csv(workSheet);
stream.pipe(fs.createWriteStream(__dirname + '/../temp/' + fileName + '.csv'));
}