[Nodejs] 엑셀 파일을 Json 또는 XML 형태로 변환하기
회사에서 업무를 하다 보니 엑셀 파일을 XML 또는 Json 형태로 변환하는 작업이 필요했다.
처음 몇 번은 수동으로 텍스트를 편집해서 excel -> xml 파일 변환 작업을 하였지만 너무 오래 걸리고 비효율적(노가다) 작업이어서 간단한 프로그램을 만들었다.
마침 Nodejs 공부가 필요했던터라 잘 모르지만 공부도 할 겸 nodejs를 사용하여 노가다 작업을 개선하기로 했다.
npm 모듈 설치 명령어 (window 기준)
> npm install express http body-parser multiparty xlsx jstoxml fs --save
nodejs 실행 명령어
> node 파일명.js
excel 파일을 Json 및 xml로 변환 (nodejs 소스 코드)
//필요한 모듈 가져오기
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 주소로 접속