ExportExcel 정리, height정렬 attRef 분리

This commit is contained in:
2025-07-29 14:06:12 +09:00
parent 8bd5d9580c
commit 66dd64306c
7 changed files with 1613 additions and 1861 deletions

0
Models/AppSettings.cs Normal file
View File

397
Models/DwgDataExtractor.cs Normal file
View File

@@ -0,0 +1,397 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using Teigha.DatabaseServices;
using Teigha.Runtime;
namespace DwgExtractorManual.Models
{
/// <summary>
/// DWG <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20>ؽ<EFBFBD>Ʈ <20><>ƼƼ<C6BC><C6BC> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD>
/// </summary>
internal class DwgDataExtractor
{
private readonly FieldMapper fieldMapper;
public DwgDataExtractor(FieldMapper fieldMapper)
{
this.fieldMapper = fieldMapper ?? throw new ArgumentNullException(nameof(fieldMapper));
}
/// <summary>
/// DWG <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> ExcelRowData <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><>ȯ
/// </summary>
public DwgExtractionResult ExtractFromDwgFile(string filePath, IProgress<double>? progress = null, CancellationToken cancellationToken = default)
{
var result = new DwgExtractionResult();
if (!File.Exists(filePath))
{
Debug.WriteLine($"? <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʽ<EFBFBD><CABD>ϴ<EFBFBD>: {filePath}");
return result;
}
try
{
progress?.Report(0);
cancellationToken.ThrowIfCancellationRequested();
using (var database = new Database(false, true))
{
database.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
progress?.Report(10);
using (var tran = database.TransactionManager.StartTransaction())
{
var bt = tran.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
using (var btr = tran.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord)
{
int totalEntities = btr.Cast<ObjectId>().Count();
int processedCount = 0;
var fileName = Path.GetFileNameWithoutExtension(database.Filename);
if (string.IsNullOrEmpty(fileName))
{
fileName = "Unknown_File";
}
foreach (ObjectId entId in btr)
{
cancellationToken.ThrowIfCancellationRequested();
using (var ent = tran.GetObject(entId, OpenMode.ForRead) as Entity)
{
string layerName = GetLayerName(ent.LayerId, tran, database);
ProcessEntity(ent, tran, database, layerName, fileName, result);
}
processedCount++;
double currentProgress = 10.0 + (double)processedCount / totalEntities * 80.0;
progress?.Report(Math.Min(currentProgress, 90.0));
}
}
tran.Commit();
}
}
progress?.Report(100);
return result;
}
catch (OperationCanceledException)
{
Debug.WriteLine("? <20>۾<EFBFBD><DBBE><EFBFBD> <20><><EFBFBD>ҵǾ<D2B5><C7BE><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
progress?.Report(0);
return result;
}
catch (Teigha.Runtime.Exception ex)
{
progress?.Report(0);
Debug.WriteLine($"? DWG <20><><EFBFBD><EFBFBD> ó<><C3B3> <20><> Teigha <20><><EFBFBD><EFBFBD> <20>߻<EFBFBD>: {ex.Message}");
return result;
}
catch (System.Exception ex)
{
progress?.Report(0);
Debug.WriteLine($"? <20>Ϲ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>߻<EFBFBD>: {ex.Message}");
return result;
}
}
/// <summary>
/// DWG <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20>ؽ<EFBFBD>Ʈ <20><>ƼƼ<C6BC><C6BC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> Height <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Բ<EFBFBD> <20><>ȯ<EFBFBD>մϴ<D5B4>.
/// </summary>
public List<TextEntityInfo> ExtractTextEntitiesWithHeight(string filePath)
{
var attRefEntities = new List<TextEntityInfo>();
var otherTextEntities = new List<TextEntityInfo>();
try
{
using (var database = new Database(false, true))
{
database.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
using (var tran = database.TransactionManager.StartTransaction())
{
var bt = tran.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
using (var btr = tran.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord)
{
foreach (ObjectId entId in btr)
{
using (var ent = tran.GetObject(entId, OpenMode.ForRead) as Entity)
{
string layerName = GetLayerName(ent.LayerId, tran, database);
// AttributeReference ó<><C3B3>
if (ent is BlockReference blr)
{
foreach (ObjectId attId in blr.AttributeCollection)
{
using (var attRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference)
{
if (attRef != null)
{
var textString = attRef.TextString == null ? "" : attRef.TextString;
attRefEntities.Add(new TextEntityInfo
{
Height = attRef.Height,
Type = "AttRef",
Layer = layerName,
Tag = attRef.Tag,
Text = textString,
});
}
}
}
}
// DBText ó<><C3B3>
else if (ent is DBText dbText)
{
otherTextEntities.Add(new TextEntityInfo
{
Height = dbText.Height,
Type = "DBText",
Layer = layerName,
Tag = "",
Text = dbText.TextString
});
}
// MText ó<><C3B3>
else if (ent is MText mText)
{
otherTextEntities.Add(new TextEntityInfo
{
Height = mText.Height,
Type = "MText",
Layer = layerName,
Tag = "",
Text = mText.Contents
});
}
}
}
}
tran.Commit();
}
}
}
catch (System.Exception ex)
{
Debug.WriteLine($"? <20>ؽ<EFBFBD>Ʈ <20><>ƼƼ <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> ({Path.GetFileName(filePath)}): {ex.Message}");
}
var sortedAttRefEntities = attRefEntities.OrderByDescending(e => e.Height).ToList();
var sortedOtherTextEntities = otherTextEntities.OrderByDescending(e => e.Height).ToList();
sortedAttRefEntities.AddRange(sortedOtherTextEntities);
return sortedAttRefEntities;
}
private void ProcessEntity(Entity ent, Transaction tran, Database database, string layerName, string fileName, DwgExtractionResult result)
{
// AttributeDefinition <20><><EFBFBD><EFBFBD>
if (ent is AttributeDefinition attDef)
{
var titleBlockRow = new TitleBlockRowData
{
Type = attDef.GetType().Name,
Name = attDef.BlockName,
Tag = attDef.Tag,
Prompt = attDef.Prompt,
Value = attDef.TextString,
Path = database.Filename,
FileName = Path.GetFileName(database.Filename)
};
result.TitleBlockRows.Add(titleBlockRow);
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
AddMappingData(fileName, attDef.Tag, attDef.TextString, result);
}
// BlockReference <20><> <20><> <20><><EFBFBD><EFBFBD> AttributeReference <20><><EFBFBD><EFBFBD>
else if (ent is BlockReference blr)
{
foreach (ObjectId attId in blr.AttributeCollection)
{
using (var attRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference)
{
if (attRef != null && attRef.TextString.Trim() != "")
{
var titleBlockRow = new TitleBlockRowData
{
Type = attRef.GetType().Name,
Name = blr.Name,
Tag = attRef.Tag,
Prompt = GetPromptFromAttributeReference(tran, blr, attRef.Tag),
Value = attRef.TextString,
Path = database.Filename,
FileName = Path.GetFileName(database.Filename)
};
result.TitleBlockRows.Add(titleBlockRow);
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
var aiLabel = fieldMapper.ExpresswayToAilabel(attRef.Tag);
if (aiLabel != null)
{
AddMappingData(fileName, attRef.Tag, attRef.TextString, result);
}
}
}
}
}
// DBText <20><>ƼƼ <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> <20><>Ʈ)
else if (ent is DBText dbText)
{
var textEntityRow = new TextEntityRowData
{
Type = "DBText",
Layer = layerName,
Text = dbText.TextString,
Path = database.Filename,
FileName = Path.GetFileName(database.Filename)
};
result.TextEntityRows.Add(textEntityRow);
}
// MText <20><>ƼƼ <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD> <20><>Ʈ)
else if (ent is MText mText)
{
var textEntityRow = new TextEntityRowData
{
Type = "MText",
Layer = layerName,
Text = mText.Contents,
Path = database.Filename,
FileName = Path.GetFileName(database.Filename)
};
result.TextEntityRows.Add(textEntityRow);
}
}
private void AddMappingData(string fileName, string tag, string attValue, DwgExtractionResult result)
{
var aiLabel = fieldMapper.ExpresswayToAilabel(tag);
var mapKey = fieldMapper.AilabelToDocAiKey(aiLabel);
if (!string.IsNullOrEmpty(aiLabel))
{
var finalMapKey = mapKey ?? aiLabel;
result.AddMappingData(fileName, finalMapKey, aiLabel, tag, attValue, "");
}
else
{
var finalMapKey = mapKey ?? tag;
if (!string.IsNullOrEmpty(finalMapKey))
{
result.AddMappingData(fileName, finalMapKey, tag, tag, attValue, "");
}
}
}
private string? GetPromptFromAttributeReference(Transaction tr, BlockReference blockref, string tag)
{
string? prompt = null;
BlockTableRecord? blockDef = tr.GetObject(blockref.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
if (blockDef == null) return null;
foreach (ObjectId objId in blockDef)
{
AttributeDefinition? attDef = tr.GetObject(objId, OpenMode.ForRead) as AttributeDefinition;
if (attDef != null)
{
if (attDef.Tag.Equals(tag, System.StringComparison.OrdinalIgnoreCase))
{
prompt = attDef.Prompt;
break;
}
}
}
return prompt;
}
private string GetLayerName(ObjectId layerId, Transaction transaction, Database database)
{
try
{
using (var layerTableRecord = transaction.GetObject(layerId, OpenMode.ForRead) as LayerTableRecord)
{
return layerTableRecord?.Name ?? "";
}
}
catch (System.Exception ex)
{
Debug.WriteLine($"Layer <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>: {ex.Message}");
return "";
}
}
}
/// <summary>
/// DWG <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD>
/// </summary>
public class DwgExtractionResult
{
public List<TitleBlockRowData> TitleBlockRows { get; set; } = new List<TitleBlockRowData>();
public List<TextEntityRowData> TextEntityRows { get; set; } = new List<TextEntityRowData>();
public Dictionary<string, Dictionary<string, (string, string, string, string)>> FileToMapkeyToLabelTagValuePdf { get; set; }
= new Dictionary<string, Dictionary<string, (string, string, string, string)>>();
public void AddMappingData(string fileName, string mapKey, string aiLabel, string dwgTag, string dwgValue, string pdfValue)
{
if (!FileToMapkeyToLabelTagValuePdf.ContainsKey(fileName))
{
FileToMapkeyToLabelTagValuePdf[fileName] = new Dictionary<string, (string, string, string, string)>();
}
FileToMapkeyToLabelTagValuePdf[fileName][mapKey] = (aiLabel, dwgTag, dwgValue, pdfValue);
}
}
/// <summary>
/// Title Block <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public class TitleBlockRowData
{
public string Type { get; set; } = "";
public string Name { get; set; } = "";
public string Tag { get; set; } = "";
public string Prompt { get; set; } = "";
public string Value { get; set; } = "";
public string Path { get; set; } = "";
public string FileName { get; set; } = "";
}
/// <summary>
/// Text Entity <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public class TextEntityRowData
{
public string Type { get; set; } = "";
public string Layer { get; set; } = "";
public string Text { get; set; } = "";
public string Path { get; set; } = "";
public string FileName { get; set; } = "";
}
/// <summary>
/// <20>ؽ<EFBFBD>Ʈ <20><>ƼƼ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD>
/// </summary>
public class TextEntityInfo
{
public double Height { get; set; }
public string Type { get; set; } = "";
public string Layer { get; set; } = "";
public string Tag { get; set; } = "";
public string Text { get; set; } = "";
}
}

279
Models/ExcelDataWriter.cs Normal file
View File

@@ -0,0 +1,279 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
namespace DwgExtractorManual.Models
{
/// <summary>
/// Excel <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD> <20>۾<EFBFBD><DBBE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD>
/// </summary>
internal class ExcelDataWriter
{
private readonly ExcelManager excelManager;
public ExcelDataWriter(ExcelManager excelManager)
{
this.excelManager = excelManager ?? throw new ArgumentNullException(nameof(excelManager));
}
/// <summary>
/// Title Block <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> Excel <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD>
/// </summary>
public void WriteTitleBlockData(List<TitleBlockRowData> titleBlockRows)
{
if (excelManager.TitleBlockSheet == null || titleBlockRows == null || titleBlockRows.Count == 0)
return;
int currentRow = 2; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
foreach (var row in titleBlockRows)
{
excelManager.TitleBlockSheet.Cells[currentRow, 1] = row.Type;
excelManager.TitleBlockSheet.Cells[currentRow, 2] = row.Name;
excelManager.TitleBlockSheet.Cells[currentRow, 3] = row.Tag;
excelManager.TitleBlockSheet.Cells[currentRow, 4] = row.Prompt;
excelManager.TitleBlockSheet.Cells[currentRow, 5] = row.Value;
excelManager.TitleBlockSheet.Cells[currentRow, 6] = row.Path;
excelManager.TitleBlockSheet.Cells[currentRow, 7] = row.FileName;
currentRow++;
}
}
/// <summary>
/// Text Entity <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> Excel <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD>
/// </summary>
public void WriteTextEntityData(List<TextEntityRowData> textEntityRows)
{
if (excelManager.TextEntitiesSheet == null || textEntityRows == null || textEntityRows.Count == 0)
return;
int currentRow = 2; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
foreach (var row in textEntityRows)
{
excelManager.TextEntitiesSheet.Cells[currentRow, 1] = row.Type;
excelManager.TextEntitiesSheet.Cells[currentRow, 2] = row.Layer;
excelManager.TextEntitiesSheet.Cells[currentRow, 3] = row.Text;
excelManager.TextEntitiesSheet.Cells[currentRow, 4] = row.Path;
excelManager.TextEntitiesSheet.Cells[currentRow, 5] = row.FileName;
currentRow++;
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> Excel <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD>
/// </summary>
public void WriteMappingDataToExcel(Dictionary<string, Dictionary<string, (string, string, string, string)>> mappingData)
{
try
{
if (excelManager.MappingSheet == null || mappingData == null)
return;
int currentRow = 2; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
Debug.WriteLine($"[DEBUG] Writing mapping data to Excel. Total files: {mappingData.Count}");
foreach (var fileEntry in mappingData)
{
string fileName = fileEntry.Key;
var fileMappingData = fileEntry.Value;
Debug.WriteLine($"[DEBUG] Processing file: {fileName}, entries: {fileMappingData.Count}");
foreach (var mapEntry in fileMappingData)
{
string mapKey = mapEntry.Key;
(string aiLabel, string dwgTag, string attValue, string pdfValue) = mapEntry.Value;
if (string.IsNullOrEmpty(fileName) || string.IsNullOrEmpty(mapKey))
{
continue;
}
try
{
// <20><>ġ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20><20><><EFBFBD><EFBFBD>
object[,] rowData = new object[1, 6];
rowData[0, 0] = fileName;
rowData[0, 1] = mapKey;
rowData[0, 2] = aiLabel ?? "";
rowData[0, 3] = dwgTag ?? "";
rowData[0, 4] = attValue ?? "";
rowData[0, 5] = pdfValue ?? "";
Excel.Range range = excelManager.MappingSheet.Range[
excelManager.MappingSheet.Cells[currentRow, 1],
excelManager.MappingSheet.Cells[currentRow, 6]];
range.Value = rowData;
}
catch (System.Exception ex)
{
Debug.WriteLine($"? Error writing row {currentRow}: {ex.Message}");
}
currentRow++;
}
}
Debug.WriteLine($"[DEBUG] Mapping data written to Excel. Total rows: {currentRow - 2}");
}
catch (System.Exception ex)
{
Debug.WriteLine($"? <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Excel <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>: {ex.Message}");
throw;
}
}
/// <summary>
/// Excel <20><><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> FileName<6D><65> AILabel<65><6C> <20><>Ī<EFBFBD>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD> ã<><C3A3> Pdf_value<75><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
/// </summary>
public bool UpdateExcelRow(string fileName, string aiLabel, string pdfValue)
{
try
{
if (excelManager.MappingSheet == null)
return false;
Excel.Range usedRange = excelManager.MappingSheet.UsedRange;
if (usedRange == null) return false;
int lastRow = usedRange.Rows.Count;
for (int row = 2; row <= lastRow; row++)
{
var cellFileName = excelManager.MappingSheet.Cells[row, 1]?.Value?.ToString() ?? "";
var cellAiLabel = excelManager.MappingSheet.Cells[row, 3]?.Value?.ToString() ?? "";
if (string.Equals(cellFileName.Trim(), fileName.Trim(), StringComparison.OrdinalIgnoreCase) &&
string.Equals(cellAiLabel.Trim(), aiLabel.Trim(), StringComparison.OrdinalIgnoreCase))
{
excelManager.MappingSheet.Cells[row, 6] = pdfValue;
return true;
}
}
return false;
}
catch (System.Exception ex)
{
Debug.WriteLine($"? Excel <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><> <20><><EFBFBD><EFBFBD>: {ex.Message}");
return false;
}
}
/// <summary>
/// DWG <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ũ<EFBFBD><C5A9><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> (PDF <20>÷<EFBFBD> <20><><EFBFBD><EFBFBD>)
/// </summary>
public void SaveDwgOnlyMappingWorkbook(Dictionary<string, Dictionary<string, (string, string, string, string)>> mappingData, string resultFolderPath)
{
try
{
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string savePath = System.IO.Path.Combine(resultFolderPath, $"{timestamp}_DwgOnly_Mapping.xlsx");
Debug.WriteLine($"[DEBUG] DWG <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ũ<EFBFBD><C5A9> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>: {savePath}");
var dwgOnlyWorkbook = excelManager.CreateNewWorkbook();
var dwgOnlyWorksheet = (Excel.Worksheet)dwgOnlyWorkbook.Worksheets[1];
dwgOnlyWorksheet.Name = "DWG Mapping Data";
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (PDF Value <20>÷<EFBFBD> <20><><EFBFBD><EFBFBD>)
dwgOnlyWorksheet.Cells[1, 1] = "<22><><EFBFBD>ϸ<EFBFBD>";
dwgOnlyWorksheet.Cells[1, 2] = "Map Key";
dwgOnlyWorksheet.Cells[1, 3] = "AI Label";
dwgOnlyWorksheet.Cells[1, 4] = "DWG Tag";
dwgOnlyWorksheet.Cells[1, 5] = "DWG Value";
// <20><><EFBFBD><EFBFBD> <20><>Ÿ<EFBFBD><C5B8> <20><><EFBFBD><EFBFBD>
var headerRange = dwgOnlyWorksheet.Range["A1:E1"];
headerRange.Font.Bold = true;
headerRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray);
headerRange.Borders.LineStyle = Excel.XlLineStyle.xlContinuous;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Է<EFBFBD>
int totalRows = mappingData.Sum(f => f.Value.Count);
if (totalRows > 0)
{
object[,] data = new object[totalRows, 5];
int row = 0;
foreach (var fileEntry in mappingData)
{
string fileName = fileEntry.Key;
foreach (var mapEntry in fileEntry.Value)
{
string mapKey = mapEntry.Key;
var (aiLabel, dwgTag, dwgValue, pdfValue) = mapEntry.Value;
data[row, 0] = fileName;
data[row, 1] = mapKey;
data[row, 2] = aiLabel;
data[row, 3] = dwgTag;
data[row, 4] = dwgValue;
row++;
}
}
Excel.Range dataRange = dwgOnlyWorksheet.Range[
dwgOnlyWorksheet.Cells[2, 1],
dwgOnlyWorksheet.Cells[totalRows + 1, 5]];
dataRange.Value = data;
}
dwgOnlyWorksheet.Columns.AutoFit();
excelManager.SaveWorkbookAs(dwgOnlyWorkbook, savePath);
Debug.WriteLine($"? DWG <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ũ<EFBFBD><C5A9> <20><><EFBFBD><EFBFBD> <20>Ϸ<EFBFBD>: {System.IO.Path.GetFileName(savePath)}");
dwgOnlyWorkbook.Close(false);
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}
catch (System.Exception ex)
{
Debug.WriteLine($"? DWG <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ũ<EFBFBD><C5A9> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>: {ex.Message}");
throw;
}
}
/// <summary>
/// Height <20><><EFBFBD>ĵ<EFBFBD> Excel <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
/// </summary>
public void WriteHeightSortedData(List<TextEntityInfo> textEntities, Excel.Worksheet worksheet, string fileName)
{
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
worksheet.Cells[1, 1] = "Height";
worksheet.Cells[1, 2] = "Type";
worksheet.Cells[1, 3] = "Layer";
worksheet.Cells[1, 4] = "Tag";
worksheet.Cells[1, 5] = "FileName";
worksheet.Cells[1, 6] = "Text";
// <20><><EFBFBD><EFBFBD> <20><>Ÿ<EFBFBD><C5B8> <20><><EFBFBD><EFBFBD>
var headerRange = worksheet.Range["A1:F1"];
headerRange.Font.Bold = true;
headerRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
// <20><><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD> ExtractTextEntitiesWithHeight<68><74><EFBFBD><EFBFBD> <20>̹<EFBFBD> <20><><EFBFBD>ĵǾ<C4B5><C7BE><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʽ<EFBFBD><CABD>ϴ<EFBFBD>.
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Է<EFBFBD>
int row = 2;
foreach (var entity in textEntities) // sortedEntities<65><73> textEntities<65><73> <20><><EFBFBD><EFBFBD>
{
worksheet.Cells[row, 1] = entity.Height;
worksheet.Cells[row, 2] = entity.Type;
worksheet.Cells[row, 3] = entity.Layer;
worksheet.Cells[row, 4] = entity.Tag;
worksheet.Cells[row, 5] = fileName;
worksheet.Cells[row, 6] = entity.Text;
row++;
}
worksheet.Columns.AutoFit();
}
}
}

309
Models/ExcelManager.cs Normal file
View File

@@ -0,0 +1,309 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace DwgExtractorManual.Models
{
/// <summary>
/// Excel COM <20><>ü <20><><EFBFBD><EFBFBD> <20><> <20><20>۾<EFBFBD><DBBE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD>
/// </summary>
internal class ExcelManager : IDisposable
{
public Excel.Application? ExcelApplication { get; private set; }
public Excel.Workbook? TitleBlockWorkbook { get; private set; }
public Excel.Workbook? MappingWorkbook { get; private set; }
public Excel.Worksheet? TitleBlockSheet { get; private set; }
public Excel.Worksheet? TextEntitiesSheet { get; private set; }
public Excel.Worksheet? MappingSheet { get; private set; }
/// <summary>
/// Excel <20><><EFBFBD>ø<EFBFBD><C3B8><EFBFBD><EFBFBD>̼<EFBFBD> <20><> <20><>ũ<EFBFBD><C5A9>Ʈ <20>ʱ<EFBFBD>ȭ
/// </summary>
public void InitializeExcel()
{
try
{
var excelApp = new Excel.Application();
ExcelApplication = excelApp;
ExcelApplication.Visible = false; // WPF<50><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3>
Excel.Workbook workbook = excelApp.Workbooks.Add();
TitleBlockWorkbook = workbook;
// Title Block Sheet <20><><EFBFBD><EFBFBD> (<28>⺻ Sheet1)
TitleBlockSheet = (Excel.Worksheet)workbook.Sheets[1];
TitleBlockSheet.Name = "Title Block";
SetupTitleBlockHeaders();
// Text Entities Sheet <20>߰<EFBFBD>
TextEntitiesSheet = (Excel.Worksheet)workbook.Sheets.Add();
TextEntitiesSheet.Name = "Text Entities";
SetupTextEntitiesHeaders();
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ϳ<EFBFBD> <20><>ũ<EFBFBD><C5A9> <20><> <20><>Ʈ <20><><EFBFBD><EFBFBD>
MappingWorkbook = excelApp.Workbooks.Add();
MappingSheet = (Excel.Worksheet)MappingWorkbook.Sheets[1];
MappingSheet.Name = "Mapping Data";
SetupMappingHeaders();
}
catch (System.Exception ex)
{
Debug.WriteLine($"Excel <20>ʱ<EFBFBD>ȭ <20><> <20><><EFBFBD><EFBFBD> <20>߻<EFBFBD>: {ex.Message}");
ReleaseExcelObjects();
throw;
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD> Excel <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD>
/// </summary>
public bool OpenExistingFile(string excelFilePath)
{
try
{
if (!File.Exists(excelFilePath))
{
Debug.WriteLine($"? Excel <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʽ<EFBFBD><CABD>ϴ<EFBFBD>: {excelFilePath}");
return false;
}
if (ExcelApplication == null)
{
ExcelApplication = new Excel.Application();
ExcelApplication.Visible = false;
}
MappingWorkbook = ExcelApplication.Workbooks.Open(excelFilePath);
MappingSheet = (Excel.Worksheet)MappingWorkbook.Sheets["Mapping Data"];
if (MappingSheet == null)
{
Debug.WriteLine("? 'Mapping Data' <20><>Ʈ<EFBFBD><C6AE> ã<><C3A3> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
return false;
}
return true;
}
catch (System.Exception ex)
{
Debug.WriteLine($"? Excel <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>: {ex.Message}");
return false;
}
}
/// <summary>
/// <20><><EFBFBD>ο<EFBFBD> <20><>ũ<EFBFBD><C5A9> <20><><EFBFBD><EFBFBD> (Height <20><><EFBFBD>Ŀ<EFBFBD>)
/// </summary>
public Excel.Workbook CreateNewWorkbook()
{
if (ExcelApplication == null)
{
ExcelApplication = new Excel.Application();
ExcelApplication.Visible = false;
}
return ExcelApplication.Workbooks.Add();
}
// Title Block <20><>Ʈ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
private void SetupTitleBlockHeaders()
{
if (TitleBlockSheet == null) return;
TitleBlockSheet.Cells[1, 1] = "Type"; // <20><>: AttributeReference, AttributeDefinition
TitleBlockSheet.Cells[1, 2] = "Name"; // BlockReference <20≯<EFBFBD> <20>Ǵ<EFBFBD> BlockDefinition <20≯<EFBFBD>
TitleBlockSheet.Cells[1, 3] = "Tag"; // Attribute Tag
TitleBlockSheet.Cells[1, 4] = "Prompt"; // Attribute Prompt
TitleBlockSheet.Cells[1, 5] = "Value"; // Attribute <20><> (TextString)
TitleBlockSheet.Cells[1, 6] = "Path"; // <20><><EFBFBD><EFBFBD> DWG <20><><EFBFBD><EFBFBD> <20><>ü <20><><EFBFBD><EFBFBD>
TitleBlockSheet.Cells[1, 7] = "FileName"; // <20><><EFBFBD><EFBFBD> DWG <20><><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD>
// <20><><EFBFBD><EFBFBD> <20><> <20><>Ÿ<EFBFBD><C5B8>
Excel.Range headerRange = TitleBlockSheet.Range["A1:G1"];
headerRange.Font.Bold = true;
headerRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
}
// Text Entities <20><>Ʈ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
private void SetupTextEntitiesHeaders()
{
if (TextEntitiesSheet == null) return;
TextEntitiesSheet.Cells[1, 1] = "Type"; // DBText, MText
TextEntitiesSheet.Cells[1, 2] = "Layer"; // Layer <20≯<EFBFBD>
TextEntitiesSheet.Cells[1, 3] = "Text"; // <20><><EFBFBD><EFBFBD> <20>ؽ<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>
TextEntitiesSheet.Cells[1, 4] = "Path"; // <20><><EFBFBD><EFBFBD> DWG <20><><EFBFBD><EFBFBD> <20><>ü <20><><EFBFBD><EFBFBD>
TextEntitiesSheet.Cells[1, 5] = "FileName"; // <20><><EFBFBD><EFBFBD> DWG <20><><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD>
// <20><><EFBFBD><EFBFBD> <20><> <20><>Ÿ<EFBFBD><C5B8>
Excel.Range headerRange = TextEntitiesSheet.Range["A1:E1"];
headerRange.Font.Bold = true;
headerRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGreen);
}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ʈ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
private void SetupMappingHeaders()
{
if (MappingSheet == null) return;
MappingSheet.Cells[1, 1] = "FileName"; // <20><><EFBFBD><EFBFBD> <20≯<EFBFBD>
MappingSheet.Cells[1, 2] = "MapKey"; // <20><><EFBFBD><EFBFBD> Ű
MappingSheet.Cells[1, 3] = "AILabel"; // AI <20><><EFBFBD><EFBFBD>
MappingSheet.Cells[1, 4] = "DwgTag"; // DWG Tag
MappingSheet.Cells[1, 5] = "Att_value"; // DWG <20><>
MappingSheet.Cells[1, 6] = "Pdf_value"; // PDF <20><> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><>)
// <20><><EFBFBD><EFBFBD> <20><> <20><>Ÿ<EFBFBD><C5B8>
Excel.Range headerRange = MappingSheet.Range["A1:F1"];
headerRange.Font.Bold = true;
headerRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightYellow);
}
/// <summary>
/// <20><>ũ<EFBFBD><C5A9> <20><><EFBFBD><EFBFBD>
/// </summary>
public bool SaveWorkbook(Excel.Workbook? workbook = null)
{
try
{
if (workbook != null)
{
workbook.Save();
return true;
}
if (MappingWorkbook != null)
{
MappingWorkbook.Save();
return true;
}
if (TitleBlockWorkbook != null)
{
TitleBlockWorkbook.Save();
return true;
}
return false;
}
catch (System.Exception ex)
{
Debug.WriteLine($"? Excel <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>: {ex.Message}");
return false;
}
}
/// <summary>
/// <20><>ũ<EFBFBD><C5A9><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD> <20><><EFBFBD><EFBFBD>
/// </summary>
public void SaveWorkbookAs(Excel.Workbook? workbook, string savePath)
{
if (workbook == null) return;
string? directory = Path.GetDirectoryName(savePath);
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
workbook.SaveAs(savePath,
FileFormat: Excel.XlFileFormat.xlOpenXMLWorkbook,
AccessMode: Excel.XlSaveAsAccessMode.xlNoChange);
}
/// <summary>
/// Excel <20><>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD> <20><>ȿ<EFBFBD><C8BF> <20≯<EFBFBD><CCB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
/// </summary>
public string GetValidSheetName(string originalName)
{
if (string.IsNullOrEmpty(originalName))
return "Sheet";
// Excel <20><>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
string validName = originalName;
char[] invalidChars = { '\\', '/', '?', '*', '[', ']', ':' };
foreach (char c in invalidChars)
{
validName = validName.Replace(c, '_');
}
// 31<33>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD> (Excel <20><>Ʈ<EFBFBD><C6AE> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD>)
if (validName.Length > 31)
{
validName = validName.Substring(0, 31);
}
return validName;
}
public void CloseWorkbooks()
{
if (TitleBlockWorkbook != null)
{
try { TitleBlockWorkbook.Close(false); }
catch { }
}
if (MappingWorkbook != null)
{
try { MappingWorkbook.Close(false); }
catch { }
}
if (ExcelApplication != null)
{
try { ExcelApplication.Quit(); }
catch { }
}
}
private void ReleaseExcelObjects()
{
ReleaseComObject(TitleBlockSheet);
ReleaseComObject(TextEntitiesSheet);
ReleaseComObject(MappingSheet);
ReleaseComObject(TitleBlockWorkbook);
ReleaseComObject(MappingWorkbook);
ReleaseComObject(ExcelApplication);
TitleBlockSheet = null;
TextEntitiesSheet = null;
MappingSheet = null;
TitleBlockWorkbook = null;
MappingWorkbook = null;
ExcelApplication = null;
}
private void ReleaseComObject(object? obj)
{
try
{
if (obj != null && Marshal.IsComObject(obj))
{
Marshal.ReleaseComObject(obj);
}
}
catch (System.Exception)
{
// <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20>߻<EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
}
}
public void Dispose()
{
try
{
Debug.WriteLine("[DEBUG] ExcelManager Dispose <20><><EFBFBD><EFBFBD>");
CloseWorkbooks();
ReleaseExcelObjects();
GC.Collect();
GC.WaitForPendingFinalizers();
Debug.WriteLine("[DEBUG] ExcelManager Dispose <20>Ϸ<EFBFBD>");
}
catch (System.Exception ex)
{
Debug.WriteLine($"[DEBUG] ExcelManager Dispose <20><> <20><><EFBFBD><EFBFBD>: {ex.Message}");
}
}
}
}

File diff suppressed because it is too large Load Diff

317
Models/JsonDataProcessor.cs Normal file
View File

@@ -0,0 +1,317 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace DwgExtractorManual.Models
{
/// <summary>
/// JSON <20><><EFBFBD><EFBFBD> ó<><C3B3> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD>
/// </summary>
internal class JsonDataProcessor
{
/// <summary>
/// JSON <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> PDF <20>м<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
/// </summary>
public bool UpdateMappingDataFromJson(Dictionary<string, Dictionary<string, (string, string, string, string)>> mappingData, string jsonFilePath)
{
try
{
Debug.WriteLine($"[DEBUG] JSON <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> PDF <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>: {jsonFilePath}");
if (!File.Exists(jsonFilePath))
{
Debug.WriteLine($"? JSON <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʽ<EFBFBD><CABD>ϴ<EFBFBD>: {jsonFilePath}");
return false;
}
// JSON <20><><EFBFBD><EFBFBD> <20>б<EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
string jsonContent = File.ReadAllText(jsonFilePath, System.Text.Encoding.UTF8);
jsonContent = CleanJsonContent(jsonContent);
JObject jsonData;
try
{
jsonData = JObject.Parse(jsonContent);
}
catch (Newtonsoft.Json.JsonReaderException jsonEx)
{
Debug.WriteLine($"? JSON <20>Ľ<EFBFBD> <20><><EFBFBD><EFBFBD>: {jsonEx.Message}");
throw new System.Exception($"PDF <20>м<EFBFBD> JSON <20><><EFBFBD><EFBFBD> <20>Ľ<EFBFBD> <20><><EFBFBD><EFBFBD>: {jsonEx.Message}\n<><6E><EFBFBD><EFBFBD>: {jsonFilePath}");
}
var results = jsonData["results"] as JArray;
if (results == null)
{
Debug.WriteLine("? JSON<4F><4E><EFBFBD><EFBFBD> 'results' <20><EFBFBD><E8BFAD> ã<><C3A3> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
return false;
}
int updatedCount = 0;
int totalEntries = 0;
foreach (JObject result in results)
{
var fileInfo = result["file_info"];
var pdfAnalysis = result["pdf_analysis"];
if (fileInfo == null || pdfAnalysis == null) continue;
string fileName = fileInfo["name"]?.ToString();
if (string.IsNullOrEmpty(fileName)) continue;
string fileNameWithoutExt = Path.GetFileNameWithoutExtension(fileName);
if (!mappingData.ContainsKey(fileNameWithoutExt))
{
Debug.WriteLine($"?? <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ϳ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>: {fileNameWithoutExt}");
continue;
}
foreach (var property in pdfAnalysis.Cast<JProperty>())
{
string aiLabel = property.Name;
var valueObj = property.Value as JObject;
if (valueObj == null) continue;
string pdfValue = valueObj["value"]?.ToString();
if (string.IsNullOrEmpty(pdfValue)) continue;
totalEntries++;
var fileData = mappingData[fileNameWithoutExt];
var matchingEntry = fileData.FirstOrDefault(kvp =>
string.Equals(kvp.Value.Item1.Trim(), aiLabel.Trim(), StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrEmpty(matchingEntry.Key))
{
var existingValue = matchingEntry.Value;
fileData[matchingEntry.Key] = (existingValue.Item1, existingValue.Item2, existingValue.Item3, pdfValue);
updatedCount++;
}
}
}
Debug.WriteLine($"[DEBUG] PDF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20>Ϸ<EFBFBD>: {updatedCount}/{totalEntries} <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE>");
return true;
}
catch (System.Exception ex)
{
Debug.WriteLine($"? JSON<4F><4E><EFBFBD><EFBFBD> PDF <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><> <20><><EFBFBD><EFBFBD>: {ex.Message}");
return false;
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ųʸ<C5B3><CAB8><EFBFBD> JSON <20><><EFBFBD>Ϸ<EFBFBD> <20><><EFBFBD><EFBFBD>
/// </summary>
public void SaveMappingDictionary(Dictionary<string, Dictionary<string, (string, string, string, string)>> mappingData, string filePath)
{
try
{
Debug.WriteLine($"[DEBUG] <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ųʸ<C5B3> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>: {filePath}");
var serializableData = new Dictionary<string, Dictionary<string, object>>();
foreach (var fileEntry in mappingData)
{
var fileData = new Dictionary<string, object>();
foreach (var mapEntry in fileEntry.Value)
{
fileData[mapEntry.Key] = new
{
AILabel = mapEntry.Value.Item1,
DwgTag = mapEntry.Value.Item2,
DwgValue = mapEntry.Value.Item3,
PdfValue = mapEntry.Value.Item4
};
}
serializableData[fileEntry.Key] = fileData;
}
string jsonContent = JsonConvert.SerializeObject(serializableData, Formatting.Indented);
File.WriteAllText(filePath, jsonContent, System.Text.Encoding.UTF8);
Debug.WriteLine($"? <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ųʸ<C5B3> <20><><EFBFBD><EFBFBD> <20>Ϸ<EFBFBD>: {Path.GetFileName(filePath)}");
Debug.WriteLine($"?? <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>: {mappingData.Count}");
}
catch (System.Exception ex)
{
Debug.WriteLine($"? <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ųʸ<C5B3> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>: {ex.Message}");
throw;
}
}
/// <summary>
/// JSON <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ųʸ<C5B3><CAB8><EFBFBD> <20>ε<EFBFBD>
/// </summary>
public Dictionary<string, Dictionary<string, (string, string, string, string)>> LoadMappingDictionary(string filePath)
{
var result = new Dictionary<string, Dictionary<string, (string, string, string, string)>>();
try
{
Debug.WriteLine($"[DEBUG] <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ųʸ<C5B3> <20>ε<EFBFBD> <20><><EFBFBD><EFBFBD>: {filePath}");
if (!File.Exists(filePath))
{
Debug.WriteLine($"?? <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʽ<EFBFBD><CABD>ϴ<EFBFBD>: {filePath}");
return result;
}
string jsonContent = File.ReadAllText(filePath, System.Text.Encoding.UTF8);
jsonContent = CleanJsonContent(jsonContent);
Dictionary<string, Dictionary<string, JObject>> deserializedData;
try
{
deserializedData = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, JObject>>>(jsonContent);
}
catch (Newtonsoft.Json.JsonReaderException jsonEx)
{
Debug.WriteLine($"? JSON <20>Ľ<EFBFBD> <20><><EFBFBD><EFBFBD>: {jsonEx.Message}");
throw new System.Exception($"<22><><EFBFBD><EFBFBD> JSON <20><><EFBFBD><EFBFBD> <20>Ľ<EFBFBD> <20><><EFBFBD><EFBFBD>: {jsonEx.Message}\n<><6E><EFBFBD><EFBFBD>: {filePath}");
}
if (deserializedData != null)
{
foreach (var fileEntry in deserializedData)
{
var fileData = new Dictionary<string, (string, string, string, string)>();
foreach (var mapEntry in fileEntry.Value)
{
var valueObj = mapEntry.Value;
string aiLabel = valueObj["AILabel"]?.ToString() ?? "";
string dwgTag = valueObj["DwgTag"]?.ToString() ?? "";
string dwgValue = valueObj["DwgValue"]?.ToString() ?? "";
string pdfValue = valueObj["PdfValue"]?.ToString() ?? "";
fileData[mapEntry.Key] = (aiLabel, dwgTag, dwgValue, pdfValue);
}
result[fileEntry.Key] = fileData;
}
}
Debug.WriteLine($"? <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ųʸ<C5B3> <20>ε<EFBFBD> <20>Ϸ<EFBFBD>");
Debug.WriteLine($"?? <20>ε<EFBFBD><CEB5><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>: {result.Count}");
return result;
}
catch (System.Exception ex)
{
Debug.WriteLine($"? <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ųʸ<C5B3> <20>ε<EFBFBD> <20><> <20><><EFBFBD><EFBFBD>: {ex.Message}");
throw;
}
}
/// <summary>
/// JSON <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20>Ľ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>·<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.
/// </summary>
private string CleanJsonContent(string jsonContent)
{
if (string.IsNullOrEmpty(jsonContent))
return jsonContent;
try
{
var lines = jsonContent.Split('\n');
var cleanedLines = new List<string>();
bool inMultiLineComment = false;
foreach (string line in lines)
{
string processedLine = line;
// <20><>Ƽ<EFBFBD><C6BC><EFBFBD><EFBFBD> <20>ּ<EFBFBD> ó<><C3B3>
if (inMultiLineComment)
{
int endIndex = processedLine.IndexOf("*/");
if (endIndex >= 0)
{
processedLine = processedLine.Substring(endIndex + 2);
inMultiLineComment = false;
}
else
{
continue;
}
}
int multiLineStart = processedLine.IndexOf("/*");
if (multiLineStart >= 0)
{
int multiLineEnd = processedLine.IndexOf("*/", multiLineStart + 2);
if (multiLineEnd >= 0)
{
processedLine = processedLine.Substring(0, multiLineStart) +
processedLine.Substring(multiLineEnd + 2);
}
else
{
processedLine = processedLine.Substring(0, multiLineStart);
inMultiLineComment = true;
}
}
// <20>̱۶<CCB1><DBB6><EFBFBD> <20>ּ<EFBFBD> <20><><EFBFBD><EFBFBD>
bool inString = false;
bool escaped = false;
int commentIndex = -1;
for (int i = 0; i < processedLine.Length - 1; i++)
{
char current = processedLine[i];
char next = processedLine[i + 1];
if (escaped)
{
escaped = false;
continue;
}
if (current == '\\')
{
escaped = true;
continue;
}
if (current == '"')
{
inString = !inString;
continue;
}
if (!inString && current == '/' && next == '/')
{
commentIndex = i;
break;
}
}
if (commentIndex >= 0)
{
processedLine = processedLine.Substring(0, commentIndex);
}
if (!string.IsNullOrWhiteSpace(processedLine))
{
cleanedLines.Add(processedLine);
}
}
return string.Join("\n", cleanedLines);
}
catch (System.Exception ex)
{
Debug.WriteLine($"? JSON <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>: {ex.Message}");
return jsonContent;
}
}
}
}

View File