프로그래밍 언어/JS TS

JSON 데이터 엑셀로 저장하기

트리맨스 2022. 9. 25. 02:45
반응형


최근 Node환경에서 데이터를 받아와 excel로 저장하는 로직을 구현해야 해서 라이브러리를 찾아보니, 압도적으로 많이 사용하는 SheetJS (xlsx) 라이브러리가 있었다. 하지만 해당 라이브러리는 xlsx를 stream을 사용해서 저장할 수 없었기에, stream을 지원하는 exceljs를 사용하기로 했다. 내가 뽑으려는 데이터의 row가 100만개 이상이고, nodejs의 메모리를 초과하기에 충분히 큰 데이터였기에 stream을 지원하는 라이브러리를 사용하게 되었다.

 

Stream을 사용하는 이유


파일을 로컬에 쓰거나 로컬에 있는 파일을 가져올 때, 이는 메모리에 적재가 된다. 만약 메모리 한계보다 더 큰 파일을 처리해야 될 때는 당연히 프로그램이 터진다. NodeJS의 메모리 한계는 1.9GB이고, 이보다 더 큰 파일을 다루려고 할때는 프로그램이 터진다. 

 

그렇다면 매우 큰 파일을 다루기 위해서는 어떻게 해야 할까? 답은 Stream을 이용하는 것이다. 간단히 말하면, 큰 파일을 여러개의 chunk로 분할하여 하나씩 쓰고 비우고, 다음파일 가져와서 쓰고 비우고 이런 식으로 파일을 다루게 되는 것이다. 

 

내가 뽑으려는 데이터는 100만개의 row를 넘어서는 것은 물론이고, 용량까지 높았기 때문에 Stream을 지원하는 라이브러리가 필요했던 것이다.

 

 

Typescript 기준 사용법 정리


물론 공식 도큐먼트가 제일 정리가 잘 되어있겠지만... 빨리 사용하기 위해서 간단히 정리를 해 보았다.

 

파일 객체 생성하기

import { stream } from 'exceljs';

const workbook = new stream.xlsx.WorkbookWriter({
  filename: '파일이름.xlsx',
});

 

워크북 객체 생성 후 대입하기

await workbook.addWorksheet('Sheet1');
const worksheet = workbook.getWorksheet('Sheet1');

 

데이터 헤더 설정하기

worksheet.columns = [
	{ header: '표시되는 헤더', key: '실제 키값' },
]

 

데이터 push하기

const data = {
	userID: 'key 밑에 들어갈 값',
};
workbook.addRow(data).commit();

 

데이터 파일에 쓰기 (푸쉬 이후 커밋을 따로 해줘야 하는거 같다. 비동기 객체이기 때문에 await을 사용해야 함.)

await worksheet.commit();
await workbook.commit();

 

반응형