본문 바로가기

프로그래밍

[Nodejs] 엑셀(excel) 파일을 Json 또는 XML 형태로 변환하기

 

[Nodejs] 엑셀 파일을 Json 또는 XML 형태로 변환하기



회사에서 업무를 하다 보니 엑셀 파일을 XML 또는 Json 형태로 변환하는 작업이 필요했다.
처음 몇 번은 수동으로 텍스트를 편집해서 excel -> xml 파일 변환 작업을 하였지만 너무 오래 걸리고 비효율적(노가다) 작업이어서 간단한 프로그램을 만들었다.
마침 Nodejs 공부가 필요했던터라 잘 모르지만 공부도 할 겸 nodejs를 사용하여 노가다 작업을 개선하기로 했다.

 

 excel 파일 데이터

 

npm 모듈 설치 명령어 (window 기준)

> npm install express http body-parser multiparty xlsx jstoxml fs --save

 

nodejs 실행 명령어

> node 파일명.js

 

excel 파일을 Json 및 xml로 변환 (nodejs 소스 코드)

excelToXml.js
0.01MB

//필요한 모듈 가져오기
const express = require('express');
const http = require('http');
const bodyParser = require('body-parser');
const multiparty = require('multiparty');
const xlsx = require('xlsx');
const jsToxml = require('jstoxml');
const fs = require('fs');

const app = express();


app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: true
}));


// array 데이터를 xml형식으로 변환 후 반환
function makeXmlData(xml) {
    const xmlOptions = {
        header: true,
        indent: '  '
    };
    
    /**
     * xml 포맷 만들기
     * jsToxml.toXML(xmlData, xmlOptions)
     * _name : 태그 이름 (<IDataXMLCoder></IDataXMLCoder>)
     * _attrs : 태그 속성 (<IDataXMLCoder version="1.0">)
     * _content : 태그 안에 들어가는 데이터 (<value>56446871</value>)
     */
    let xmlData = jsToxml.toXML({
        _name: 'IDataXMLCoder',
        _attrs: {
          version: '1.0'
        },
        
        _content: {

            _name: 'record',
            _attrs: {
              javaclass: 'com.wm.data.ISMemDataImpl'
            },
            _content: {

                _name: 'array',
                _attrs: {
                    name: 'PartNumber',
                    type: 'value',
                    depth: '1'
                },
                _content : {
                    value : xml
                
                }
         
            }
        }}, xmlOptions);

        return xmlData;
}

// array 데이터를 json형식으로 변환 후 반환
function makeJsonData(ary) {
    var result = new Array();
    var jsonObj = null;
    var jsonObjKey = new Object();
    // array 데이터 Object에 삽입
    for (var i=0;i<ary.length;i++){
        jsonObj = new Object();
        jsonObj.value = ary[i];
        result.push( jsonObj );
    }

    // json 구조 만들기 
    //{"jsonData":[{"value":"17087271"},{"value":"27640601"},{"value":"30692050"}]}
    jsonObjKey.jsonData = result;

    // Json 데이터 string 형태로 반환
    return JSON.stringify(jsonObjKey);
}

 
//브라우저에서 get 방식으로 접근 시 보여지는 html 화면
app.get('/', (req, res, next) => {
    let contents = '';
    contents += '<html><body>';
    contents += '   <form action="/" method="POST" enctype="multipart/form-data">';
    contents += '       <input type="file" name="xlsx" />';
    contents += '       <input type="submit" />';
    contents += '   </form>';
    contents += '</body></html>';

    res.send(contents);
});

//브라우저에서 post 방식으로 접근 시 처리하는 로직
app.post('/', (req, res, next) => {
    let result = {};
    let resultAry1 = {};
    let resultAry2 = {};

    //multiparty를 이용해 Form 데이터를 처리
    const form = new multiparty.Form({
        autoFiles: true, //POST 방식으로 전달된 파일만 처리
    });
 

    form.on('file', (name, file) => { //파일이 입력 되었을 때 발생하는 이벤트
        const workbook = xlsx.readFile(file.path); //xlsx 파일 가져와서 객체 생성

        const sheetnames = Object.keys(workbook.Sheets); //엑셀 sheets 이름 가져오기
 
        let i = sheetnames.length; //전체 엑셀 시트 개수
        console.log("sheetnames.length : " + i);
 
        while (i--) { // sheet 수 만큼 while문 반복
            const sheetname = sheetnames[i]; //한개의 sheet
            result = xlsx.utils.sheet_to_csv(workbook.Sheets[sheetname]).split('\n'); //엑셀 데이터를 csv로 변환 후 '\n' 구분자로 파싱하여 array로 반환
            result.shift(); //첫번째 array 데이터 삭제
            result.pop(); //마지막 array 데이터 삭제

            //업무 상 이유로 전체 array 데이터를 반으로 나누기
            resultAry1 = result.splice(0, Math.floor(result.length / 2)); // 반으로 나눈 1/2 array 데이터
            resultAry2 = result; // 나머지 반 array 데이터

        }

    });

    //form 데이타를 업로드 하는 중간중간에 현재 진행 상태를 출력하기 위한 이벤트
    form.on('progress',function(byteRead,byteExpected){

        console.log(' Reading total  '+byteRead+'/'+byteExpected);
        res.write(' Reading total  '+byteRead+'/'+byteExpected +'\n');

    });


    // form 데이터 업로드가 끝났을 때 발생하는 이벤트
    form.on('close', () => {
        
        // array 데이터를 xml 형식으로 변환 및 파일 생성 (첫번째 파일)
        fs.writeFile('send1.xml', makeXmlData(resultAry1), function (err){
            if (err) throw err;
                console.log('It\'s saved! send1.xml');
            });

        // array 데이터를 xml 형식으로 변환 및 파일 생성 (두번째 파일)
        fs.writeFile('send2.xml', makeXmlData(resultAry2), function (err){
            if (err) throw err;
                console.log('It\'s saved! send2.xml');
            });

        // array 데이터를 json 형식으로 변환 및 파일 생성 (첫번째 파일)
        fs.writeFile('send1.json', makeJsonData(resultAry1), function (err){
            if (err) throw err;
                console.log('It\'s saved! send1.json');
            });

        // array 데이터를 json 형식으로 변환 및 파일 생성 (두번째 파일)
        fs.writeFile('send2.json', makeJsonData(resultAry2), function (err){
            if (err) throw err;
                console.log('It\'s saved! send2.json');
            });
        
        
        //response 객체 종료
        res.end('It\'s saved!');

    });
 
    form.parse(req);
});

//express 서버 3000번 포트 사용
http.createServer(app).listen(3000, () => {
    console.log('HTTP server listening on port ' + 3000);
});

 

브라우저 실행 후 http://localhost:3000 주소로 접속

 

엑셀 파일 선택 후 제출

 

엑셀 변환 완료

 

엑셀 파일 변환하여 생성된 xml 파일

 

엑셀 파일 변환하여 생성된 json 파일