본문 바로가기

노드

[nodejs] 엑셀 파일을 json 데이터로 변환 해보기

반응형

node-telegram-bot-api 와 mongoose 를 사용하여 텔레그램 챗 봇을 만들어 보던 중 엑셀 파일을 json 형태로 변환해서 데이터베이스에 저장하는 기능을 만들어 보기로 했다. 이 기능을 구현하는 것에 큰 의미는 없지만, 연습 삼아서 해본다.

 

텔레그램 봇이나 데이터베이스 사용을 떠나서 엑셀 파일을 json 형태로 바꾸는 것에만 초점을 두고 기록해둘 것이다.

 

 패키지 설치

우선 json 형태로 변환하기 위해 npm 패키지를 설치한다. 이번에 사용한 패키지는 convert-excel-to-json 이라는 것인데, 자세한 사용법은 아래 패키지 공식 깃허브에 자세하게 나와있다.

npm install convert-excel-to-json
 

GitHub - DiegoZoracKy/convert-excel-to-json: Convert Excel to JSON, mapping sheet columns to object keys.

Convert Excel to JSON, mapping sheet columns to object keys. - GitHub - DiegoZoracKy/convert-excel-to-json: Convert Excel to JSON, mapping sheet columns to object keys.

github.com

 

 nodejs 코드 작성

"use strict";

const Comment = require("../db/Connection");

const path = require("path");
const fs = require("fs");

/** 엑셀 파일 경로를 저장하기 위한 변수*/
let excelFilePath = "";

/** fs.readdir(경로, (err, 해당 경로에서 찾은 것들이 저장)) */
fs.readdir(
  `${path.join(__dirname, "../", "download_files/")}`,
  (err, result) => {
    console.log(result);
    if (err) {
      return (excelFilePath = path.join(
        __dirname,
        "../",
        "download_files/file_10.xls"
      ));
    }
    // 파일이 존재한다면 최신 파일을 읽어온다.
    excelFilePath = path.join(
      __dirname,
      "../",
      `download_files/${result[result.length - 1]}`
    );
  }
);

/** 경로에 파일이 존재한다면 해당 파일을 읽어와서 json 데이터로 변환한다.*/
function readFile(msg, bot) {
  try {
    const excelToJson = require("convert-excel-to-json");
    const result = excelToJson({
      source: fs.readFileSync(excelFilePath),
      header: {
        rows: 1, // 헤더에서 rows : 1로 지정해두면 해당 행은 데이터로 취급하지 않는다.
      },
      columnToKey: {
        A: "{{A1}}", // A 컬럼의 A1 셀 데이터를 키로 지정한다.
        B: "{{B1}}", // B 컬럼의 B1 셀 데이터를 키로 지정한다.
      },
    });
    
    /** result 변수를 출력하면 {Sheet1:[{키:값}]},...) 형태로 되어있다.*/
    const excelData = result.Sheet1;
    console.log(excelData);

    excelData.forEach((data, i) => {
    // 몽고디비에 변환된 엑셀 데이터를 저장하는 로직
      Comment.create({ comment: data.comment })
        .then((result) => {
          console.log(result);
        })
        .catch((err) => {
          console.log("엑셀파일 데이터 저장 실패", err);
        });
    });
  } catch (err) {
    bot.sendMessage(
      msg.chat.id,
      ":: 저장 실패! 경로나 데이터 형식 등이 일치하는지 확인하세요"
    );
  }

/** 텔레그램 봇이 마지막에 보내는 메시지 */
  bot.sendMessage(
    msg.chat.id,
    "실행완료. 만약 이거 말고, 별도 메시지가 연달아 뜨면 실패한거니까 확인하삼."
  );
}

module.exports = readFile;

 

전체 코드는 위와 같은데, 솔직히 별 내용이 없어서 부연 설명은 적어놓지 않으려고 한다. 그래도 참고해야 하는 부분은 언급해두겠다. 엑셀에서 A,B,C 부분을 컬럼(열)이라 하고, 1,2,3,4 부분을 행이라 한다.

 

 

      header: {
        rows: 1, // 헤더에서 rows : 1로 지정해두면 해당 행은 데이터로 취급하지 않는다.
      },

 

      columnToKey: {
        A: "{{A1}}", // A 컬럼의 A1 셀 데이터를 키로 지정한다.
        B: "{{B1}}", // B 컬럼의 B1 셀 데이터를 키로 지정한다.

 

위 코드를 보면 header columnToKey 라는 속성이 지정된 것을 확인할 수 있는데, comment 와 createAt이 위치한 row(행)에 대해서 header 속성의 값으로 rows:1 로 지정하게 되면,  일반적인 셀 데이터가 아닌 자바스크립트 html의 table 에서 th 와 같은 역할을 하도록 지정할 수 있다.  즉, 여기서는 { 키 : 값 } 이 있다면 키와 같다고 이해하면 된다.

 

하지만 header 만 지정하는 경우에는 그저 데이터에서 제외되는 것이므로, columnToKey 속성에서  따로 명확히 지정해줘야지만 해당 셀을 키(헤더)로 사용한다.

 

 

 

반응형