지난 포스팅인, 구글 시트에서 다국어 JSON 파일 자동 생성하기에 이어 이번엔 MS Excel (XLSX) 파일을 Node.js를 사용하여 각 언어별 JSON 파일로 변환하는 방법에 대해 알아보겠습니다.
국제화(i18n) 작업을 하다 보면 여러 언어의 텍스트를 관리해야 하는데, Excel 파일 형식으로 관리하던 번역 데이터를 웹 애플리케이션에서 사용할 수 있는 JSON 형태로 변환이 필요했습니다. 🌍
Node.js 생태계에는 엑셀 파일을 읽고 쓸 수 있는 훌륭한 라이브러리들이 있는데, 그 중에서도 가장 널리 사용되는 xlsx 라이브러리를 활용해보겠습니다. ✨
아직 설치되어 있지 않다면 Node.js 공식 웹사이트에서 다운로드하여 설치하세요!
mkdir excel-to-json-converter
cd excel-to-json-converter
npm init -y
npm install xlsx
먼저 첫 번째 시트의 첫 번째 행에는 다음과 같은 제목 열이 있다고 가정하겠습니다:
key | ko | en | jp |
---|---|---|---|
greeting | 안녕하세요 | Hello | こんにちは |
welcome | 환영합니다 | Welcome | ようこそ |
button.ok | 확인 | OK | OK |
menu.file | 파일 | File | ファイル |
이런 형태의 Excel 파일을 translations.xlsx
라는 이름으로 프로젝트 폴더 안에 저장해주세요!
📌 다국어 엑셀 파일 작성 시, 언어 스크립트의 key 값은 통일되어야 합니다.
이제 converter.js
라는 파일을 생성하고 아래 코드를 작성해보겠습니다:
(이 스크립트는 점 표기법을 지원하여, 예를 들어 button.ok
, menu.file.save
같은 키들이 자동으로 중첩된 객체 구조로 변환됩니다.)
const XLSX = require('xlsx');
const fs = require('fs');
const path = require('path');
// 📁 엑셀 파일 경로
const excelFilePath = path.resolve(__dirname, 'translations.xlsx');
// 📂 JSON 파일을 저장할 출력 폴더
const outputDir = path.resolve(__dirname, 'output_json');
// 📁 출력 폴더가 없으면 생성
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir);
console.log('📁 Output directory created!');
}
/**
* 🔗 중첩된 키 경로(예: "button.ok")에 값을 설정하는 헬퍼 함수
* @param {object} obj - 값을 설정할 대상 객체
* @param {string} path - 키 경로 (점 표기법)
* @param {*} value - 설정할 값
*/
function setNestedValue(obj, path, value) {
const parts = path.split('.');
let current = obj;
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (i === parts.length - 1) {
current[part] = value;
} else {
// 현재 부분이 객체가 아니거나 존재하지 않으면 빈 객체로 초기화
if (typeof current[part] !== 'object' || current[part] === null) {
current[part] = {};
}
current = current[part];
}
}
}
try {
console.log('🚀 Starting conversion process...');
// 📊 엑셀 파일 읽기
const workbook = XLSX.readFile(excelFilePath);
console.log('✅ Excel file loaded successfully!');
// 📋 첫 번째 시트 가져오기
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
console.log(`📄 Working with sheet: ${sheetName}`);
// 🔄 시트를 JSON 배열로 변환 (헤더 포함)
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
// 🏷️ 첫 번째 행은 헤더 (key, ko, en, jp 등)
const headers = jsonData[0];
// 📝 실제 데이터는 두 번째 행부터
const dataRows = jsonData.slice(1);
console.log(`📊 Found ${headers.length - 1} languages: ${headers.slice(1).join(', ')}`);
console.log(`📝 Processing ${dataRows.length} translation entries...`);
// 🌐 각 언어별로 데이터를 담을 객체 초기화
const languageData = {};
const languageColumns = headers.slice(1); // 'key'를 제외한 언어 코드들
languageColumns.forEach(langCode => {
languageData[langCode] = {};
});
// 🔄 데이터 행을 순회하며 각 언어별 JSON 객체 생성
dataRows.forEach((row, rowIndex) => {
const key = row[0]; // 첫 번째 열은 key
// ✅ key가 유효한지 확인 (비어있거나 null이 아닌지)
if (key === undefined || key === null || key === '') {
console.warn(`⚠️ Warning: Skipping row ${rowIndex + 2} due to missing key`);
return; // 다음 행으로 넘어감
}
languageColumns.forEach((langCode, index) => {
const value = row[index + 1]; // 해당 언어의 값 (key 다음 열부터)
// undefined 또는 null 값을 빈 문자열로 처리
const finalValue = (value === undefined || value === null) ? '' : String(value);
// 🔗 중첩된 키에 값 설정 (예: button.ok -> { button: { ok: "값" } })
setNestedValue(languageData[langCode], String(key), finalValue);
});
});
// 💾 각 언어별 JSON 파일 생성
console.log('📄 Generating JSON files...');
for (const langCode in languageData) {
const outputFilePath = path.join(outputDir, `${langCode}.json`);
const jsonContent = JSON.stringify(languageData[langCode], null, 2); // 보기 좋게 들여쓰기
fs.writeFileSync(outputFilePath, jsonContent, 'utf8');
console.log(`✅ Generated: ${langCode}.json`);
}
console.log('🎉 Conversion completed successfully!');
console.log(`📂 Check the 'output_json' folder for your translated files!`);
} catch (error) {
console.error('❌ An error occurred during conversion:', error.message);
console.error('💡 Please check if your Excel file exists and has the correct format.');
}
cd excel-to-json-converter
translations.xlsx
파일을 프로젝트 폴더에 넣어주세요!
node converter.js
성공적으로 실행되면 다음과 같은 메시지들을 볼 수 있습니다:
🚀 Starting conversion process...
✅ Excel file loaded successfully!
📄 Working with sheet: Sheet1
📊 Found 3 languages: ko, en, jp
📝 Processing 4 translation entries...
📄 Generating JSON files...
✅ Generated: ko.json
✅ Generated: en.json
✅ Generated: jp.json
🎉 Conversion completed successfully!
📂 Check the 'output_json' folder for your translated files!
그리고 output_json
폴더가 생성되며, 그 안에 각 언어별 JSON 파일들이 생성됩니다!
ko.json
{
"greeting": "안녕하세요",
"welcome": "환영합니다",
"button": {
"ok": "확인"
},
"menu": {
"file": "파일"
}
}
en.json
{
"greeting": "Hello",
"welcome": "Welcome",
"button": {
"ok": "OK"
},
"menu": {
"file": "File"
}
}