338 lines
13 KiB
C#
338 lines
13 KiB
C#
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> Ŭ<><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? NoteEntitiesSheet { 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();
|
||
|
||
// Note Entities Sheet <20>߰<EFBFBD>
|
||
NoteEntitiesSheet = (Excel.Worksheet)workbook.Sheets.Add();
|
||
NoteEntitiesSheet.Name = "Note Entities";
|
||
SetupNoteEntitiesHeaders();
|
||
|
||
// <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> <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>
|
||
TitleBlockSheet.Cells[1, 7] = "FileName"; // <20><><EFBFBD><EFBFBD> DWG <20><><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD>
|
||
|
||
// <20><><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> <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>
|
||
TextEntitiesSheet.Cells[1, 5] = "FileName"; // <20><><EFBFBD><EFBFBD> DWG <20><><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD>
|
||
|
||
// <20><><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> <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><>
|
||
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> <20><> <20><>)
|
||
|
||
// <20><><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);
|
||
}
|
||
|
||
// Note Entities <20><>Ʈ <20><><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
private void SetupNoteEntitiesHeaders()
|
||
{
|
||
if (NoteEntitiesSheet == null) return;
|
||
|
||
NoteEntitiesSheet.Cells[1, 1] = "Type"; // Note, NoteContent
|
||
NoteEntitiesSheet.Cells[1, 2] = "Layer"; // Layer <20≯<EFBFBD>
|
||
NoteEntitiesSheet.Cells[1, 3] = "Text"; // <20><><EFBFBD><EFBFBD> <20>ؽ<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>
|
||
NoteEntitiesSheet.Cells[1, 4] = "X"; // X <20><>ǥ
|
||
NoteEntitiesSheet.Cells[1, 5] = "Y"; // Y <20><>ǥ
|
||
NoteEntitiesSheet.Cells[1, 6] = "SortOrder"; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
NoteEntitiesSheet.Cells[1, 7] = "TableCsv"; // <20><><EFBFBD>̺<EFBFBD> CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
NoteEntitiesSheet.Cells[1, 8] = "Path"; // <20><><EFBFBD><EFBFBD> DWG <20><><EFBFBD><EFBFBD> <20><>ü <20><><EFBFBD>
|
||
NoteEntitiesSheet.Cells[1, 9] = "FileName"; // <20><><EFBFBD><EFBFBD> DWG <20><><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD>
|
||
|
||
// <20><><EFBFBD> <20><> <20><>Ÿ<EFBFBD><C5B8>
|
||
Excel.Range headerRange = NoteEntitiesSheet.Range["A1:I1"];
|
||
headerRange.Font.Bold = true;
|
||
headerRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightCoral);
|
||
}
|
||
|
||
/// <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> <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> <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> <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(NoteEntitiesSheet);
|
||
ReleaseComObject(MappingSheet);
|
||
ReleaseComObject(TitleBlockWorkbook);
|
||
ReleaseComObject(MappingWorkbook);
|
||
ReleaseComObject(ExcelApplication);
|
||
|
||
TitleBlockSheet = null;
|
||
TextEntitiesSheet = null;
|
||
NoteEntitiesSheet = 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}");
|
||
}
|
||
}
|
||
}
|
||
} |