319 lines
12 KiB
C#
319 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using ExcelDataReader;
|
|
using Newtonsoft.Json.Linq;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace _02.Scripts.Editor
|
|
{
|
|
public class ExcelToJsonConverter : EditorWindow
|
|
{
|
|
private readonly string excelFolderPath = "Assets/Resources/Excel";
|
|
private readonly string jsonFolderPath = "Assets/Resources/JSON";
|
|
public static Dictionary<string, bool> toggleStates;
|
|
private List<DifferencePopup.Difference> differences;
|
|
private bool showPopup = false;
|
|
private string selectedExcelFile;
|
|
public static ExcelToJsonConverter Instance { get; private set; }
|
|
private Vector2 scrollPosition;
|
|
|
|
[MenuItem("Tools/EXCEL TO JSON - BlueWater")]
|
|
public static void ShowWindow()
|
|
{
|
|
Instance = GetWindow<ExcelToJsonConverter>("EXCEL TO JSON");
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
toggleStates = new Dictionary<string, bool>();
|
|
var excelFiles = Directory.GetFiles(excelFolderPath, "*.xlsx");
|
|
foreach (var excelFile in excelFiles)
|
|
{
|
|
toggleStates[Path.GetFileNameWithoutExtension(excelFile)] = false;
|
|
}
|
|
}
|
|
|
|
public void ProcessSelectedFiles()
|
|
{
|
|
List<DifferencePopup.Difference> currentDifferences = new List<DifferencePopup.Difference>();
|
|
|
|
bool differencesFound = false;
|
|
|
|
foreach (var excelFile in toggleStates.Keys)
|
|
{
|
|
if (toggleStates[excelFile])
|
|
{
|
|
string excelPath = Path.Combine(excelFolderPath, excelFile + ".xlsx");
|
|
string jsonPath = Path.Combine(jsonFolderPath, excelFile + ".json");
|
|
|
|
JArray newJsonArray = ConvertExcelToJsonArray(excelPath);
|
|
|
|
if (File.Exists(jsonPath))
|
|
{
|
|
JArray existingJsonArray = JArray.Parse(File.ReadAllText(jsonPath));
|
|
currentDifferences = CompareJsonObjects(newJsonArray, existingJsonArray);
|
|
if (currentDifferences.Count > 0)
|
|
{
|
|
selectedExcelFile = excelFile;
|
|
differences = currentDifferences;
|
|
showPopup = true;
|
|
differencesFound = true;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
File.WriteAllText(jsonPath, newJsonArray.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!differencesFound && !showPopup)
|
|
{
|
|
EditorUtility.DisplayDialog("달라진점이 없음",
|
|
"비교 대상인 새로운 엑셀 파일과 기존의 제이슨 파일에서 다른 점을 발견하지 못했습니다.", "확인");
|
|
}
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
EditorGUILayout.LabelField("EXCEL TO JSON - Select & Compare", EditorStyles.boldLabel);
|
|
|
|
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
|
|
|
List<string> keys = new List<string>(toggleStates.Keys);
|
|
|
|
foreach (var excelFile in keys)
|
|
{
|
|
bool currentValue = toggleStates[excelFile];
|
|
bool newValue = EditorGUILayout.ToggleLeft(excelFile, currentValue);
|
|
if (currentValue != newValue)
|
|
{
|
|
toggleStates[excelFile] = newValue;
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.EndScrollView();
|
|
|
|
if (GUILayout.Button("수정사항 체크"))
|
|
{
|
|
CheckModifiedToggles();
|
|
}
|
|
|
|
GUILayout.Space(10);
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
|
|
if (GUILayout.Button("전체 해제"))
|
|
{
|
|
foreach (var excelFile in keys)
|
|
{
|
|
toggleStates[excelFile] = false;
|
|
}
|
|
}
|
|
|
|
if (GUILayout.Button("전체 선택"))
|
|
{
|
|
foreach (var excelFile in keys)
|
|
{
|
|
toggleStates[excelFile] = true;
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
GUILayout.Space(10);
|
|
|
|
if (GUILayout.Button("선택된 파일들 비교 및 병합"))
|
|
{
|
|
ProcessSelectedFiles();
|
|
}
|
|
|
|
if (showPopup)
|
|
{
|
|
DifferencePopup window = DifferencePopup.ShowWindow(differences, selectedExcelFile, jsonFolderPath);
|
|
window.OnClose += () => showPopup = false;
|
|
}
|
|
}
|
|
|
|
public void CheckModifiedToggles()
|
|
{
|
|
List<string> keysToCheck = new List<string>(toggleStates.Keys);
|
|
|
|
foreach (var excelFile in keysToCheck)
|
|
{
|
|
string excelPath = Path.Combine(excelFolderPath, excelFile + ".xlsx");
|
|
string jsonPath = Path.Combine(jsonFolderPath, excelFile + ".json");
|
|
|
|
if (File.Exists(jsonPath))
|
|
{
|
|
JArray newJsonArray = ConvertExcelToJsonArray(excelPath);
|
|
JArray existingJsonArray = JArray.Parse(File.ReadAllText(jsonPath));
|
|
List<DifferencePopup.Difference> currentDifferences =
|
|
CompareJsonObjects(newJsonArray, existingJsonArray);
|
|
|
|
if (currentDifferences.Count > 0)
|
|
{
|
|
toggleStates[excelFile] = true;
|
|
}
|
|
else
|
|
{
|
|
toggleStates[excelFile] = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static JArray ConvertExcelToJsonArray(string excelPath)
|
|
{
|
|
FileStream stream = File.Open(excelPath, FileMode.Open, FileAccess.Read);
|
|
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
|
|
|
|
DataSet result = excelReader.AsDataSet(new ExcelDataSetConfiguration()
|
|
{
|
|
ConfigureDataTable = (tableReader) => new ExcelDataTableConfiguration()
|
|
{
|
|
UseHeaderRow = true
|
|
}
|
|
});
|
|
|
|
stream.Close();
|
|
DataTable table = result.Tables[0];
|
|
|
|
JArray jsonArray = new JArray();
|
|
foreach (DataRow row in table.Rows)
|
|
{
|
|
JObject obj = new JObject();
|
|
foreach (DataColumn column in table.Columns)
|
|
{
|
|
string cellValue = row[column].ToString();
|
|
if (float.TryParse(cellValue, out float floatResult))
|
|
{
|
|
if (floatResult % 1 == 0)
|
|
{
|
|
obj[column.ColumnName] = Convert.ToInt32(floatResult);
|
|
}
|
|
else
|
|
{
|
|
obj[column.ColumnName] = floatResult;
|
|
}
|
|
}
|
|
else if (IsString(cellValue))
|
|
{
|
|
obj[column.ColumnName] = cellValue;
|
|
}
|
|
else
|
|
{
|
|
obj[column.ColumnName] = cellValue;
|
|
}
|
|
}
|
|
|
|
jsonArray.Add(obj);
|
|
}
|
|
|
|
return jsonArray;
|
|
}
|
|
|
|
private static bool IsString(string value)
|
|
{
|
|
return value.Any(c => !char.IsDigit(c));
|
|
}
|
|
|
|
|
|
|
|
private List<DifferencePopup.Difference> CompareJsonObjects(JArray newObj, JArray existingObj)
|
|
{
|
|
List<DifferencePopup.Difference> differences = new List<DifferencePopup.Difference>();
|
|
|
|
int minLength = Mathf.Min(newObj.Count, existingObj.Count);
|
|
int maxLength = Mathf.Max(newObj.Count, existingObj.Count);
|
|
|
|
for (int i = 0; i < maxLength; i++)
|
|
{
|
|
if (i < minLength)
|
|
{
|
|
JObject newItem = newObj[i] as JObject;
|
|
JObject existingItem = existingObj[i] as JObject;
|
|
|
|
if (newItem != null && existingItem != null)
|
|
{
|
|
HashSet<string> allPropertyNames = new HashSet<string>(newItem.Properties().Select(p => p.Name));
|
|
allPropertyNames.UnionWith(existingItem.Properties().Select(p => p.Name));
|
|
|
|
foreach (string propertyName in allPropertyNames)
|
|
{
|
|
JToken newToken;
|
|
JToken existingToken;
|
|
|
|
if (newItem.TryGetValue(propertyName, out newToken) &&
|
|
existingItem.TryGetValue(propertyName, out existingToken))
|
|
{
|
|
string newValueWithoutSpaces = newToken.ToString().Replace(" ", "");
|
|
string existingValueWithoutSpaces = existingToken.ToString().Replace(" ", "");
|
|
|
|
if (!newValueWithoutSpaces.Equals(existingValueWithoutSpaces))
|
|
{
|
|
differences.Add(new DifferencePopup.Difference(propertyName, newToken.ToString(),
|
|
existingToken.ToString(), i));
|
|
}
|
|
}
|
|
else if (!newItem.TryGetValue(propertyName, out newToken) &&
|
|
existingItem.TryGetValue(propertyName, out existingToken))
|
|
{
|
|
differences.Add(new DifferencePopup.Difference(propertyName, "N/A",
|
|
existingToken.ToString(), i));
|
|
}
|
|
else if (newItem.TryGetValue(propertyName, out newToken) &&
|
|
!existingItem.TryGetValue(propertyName, out existingToken))
|
|
{
|
|
differences.Add(new DifferencePopup.Difference(propertyName, newToken.ToString(), "N/A",
|
|
i));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"해당 인덱스에서 JSON 객체를 비교하지 못했습니다 {i}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 추가된 행에 대한 차이를 처리합니다.
|
|
JObject newItem = i < newObj.Count ? newObj[i] as JObject : null;
|
|
JObject existingItem = i < existingObj.Count ? existingObj[i] as JObject : null;
|
|
JObject availableItem = newItem ?? existingItem;
|
|
string newValue, existingValue;
|
|
|
|
foreach (var property in availableItem.Properties())
|
|
{
|
|
if (newItem != null && newItem.TryGetValue(property.Name, out JToken newToken))
|
|
{
|
|
newValue = newToken.ToString();
|
|
}
|
|
else
|
|
{
|
|
newValue = "N/A";
|
|
}
|
|
|
|
if (existingItem != null && existingItem.TryGetValue(property.Name, out JToken existingToken))
|
|
{
|
|
existingValue = existingToken.ToString();
|
|
}
|
|
else
|
|
{
|
|
existingValue = "N/A";
|
|
}
|
|
|
|
differences.Add(new DifferencePopup.Difference(property.Name, newValue, existingValue, i));
|
|
}
|
|
}
|
|
}
|
|
|
|
return differences;
|
|
}
|
|
}
|
|
} |