first commit
This commit is contained in:
387
Models/ExportExcel.cs
Normal file
387
Models/ExportExcel.cs
Normal file
@@ -0,0 +1,387 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices; // COM 객체 해제를 위해 필요
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Teigha.DatabaseServices;
|
||||
using Teigha.Geometry;
|
||||
using Teigha.Runtime;
|
||||
using Excel = Microsoft.Office.Interop.Excel;
|
||||
|
||||
namespace DwgExtractorManual.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// DWG 파일에서 Excel로 데이터 내보내기 클래스
|
||||
/// AttributeReference, AttributeDefinition, DBText, MText 추출 지원
|
||||
/// </summary>
|
||||
internal class ExportExcel : IDisposable
|
||||
{
|
||||
// ODA 서비스 객체
|
||||
private Services appServices;
|
||||
|
||||
// Excel COM 객체들
|
||||
private Excel.Application excelApplication;
|
||||
private Excel.Workbook workbook1;
|
||||
private Excel.Worksheet titleBlockSheet; // Title Block용 시트
|
||||
private Excel.Worksheet textEntitiesSheet; // Text Entities용 시트
|
||||
|
||||
// 각 시트의 현재 행 번호
|
||||
private int titleBlockCurrentRow = 2; // 헤더가 1행이므로 데이터는 2행부터 시작
|
||||
private int textEntitiesCurrentRow = 2; // 헤더가 1행이므로 데이터는 2행부터 시작
|
||||
|
||||
// 생성자: ODA 및 Excel 초기화
|
||||
public ExportExcel()
|
||||
{
|
||||
ActivateAndInitializeODA();
|
||||
InitializeExcel();
|
||||
}
|
||||
|
||||
// ODA 제품 활성화 및 초기화
|
||||
private void ActivateAndInitializeODA()
|
||||
{
|
||||
var userInfo = "c2FtYW4gZW5naW5lZXJpbmc=";
|
||||
var userSignature = "F0kuQTmtVpHtvl/TgaFVGE92/YqGmYR9SLoXckEjnOk8NoAQh7Sg6GQruVC04JqD4C/IipxJYqpqvMfMc2auRMG+cAJCKqKUE2djIMdkUdb+C5IVx2c97fcK5ba3n8DDvB54Upokajl+6j12yD8h8MKGOR3Z3zysObeXD62bFpQgp00GCYTqlxEZtTIRjHIPAfJfix8Y0jtXWWYyVJ3LYOu86as5xtx+hY1aakpYIJiQk/6pGd84qSn/9K1w8nxR7UrFzieDeQ/xM58BHSD4u/ZxVJwvv6Uy10tsdBFBTvfJMAFp05Y7yeyeCNr100tA3iOfmWoXAVRHfxnkPfiYR54aK04QI+R6OGkI+yd1oR5BtmN6BdDt3z8KYK5EpFGJGiJIGoUy5PvkYdJ2VV6xe9JWBiIJuI/tDn1Y+uyTQFA9qaDHnOURriXsRGfy8reDPf1eejybSJxWKkpilG6RXhq3xHlCkjZzh1Q45S+xYXNGatcWMm9nkn20M8Ke5JEVaI9w/p2GE36CHRtRQbt8kfPmsbWNXJCFr4svHW2MPbCKWoyn5XEyMWBnuAKi74zvczB13DKjf29SqSIgF5k/hwy2QrgvnaKzY1k8bw8w2/k0vJXcS3GKOB/ZYDle1tf/lkAD1HtnF9zE18TiXhVnqwAVjwg4ui1RPLn/LMs6b5Y=";
|
||||
Services.odActivate(userInfo, userSignature);
|
||||
appServices = new Services();
|
||||
}
|
||||
|
||||
// Excel 애플리케이션 및 워크시트 초기화
|
||||
private void InitializeExcel()
|
||||
{
|
||||
try
|
||||
{
|
||||
var excelApp = new Excel.Application();
|
||||
excelApplication = excelApp;
|
||||
excelApplication.Visible = false; // WPF에서는 숨김 처리
|
||||
Excel.Workbook workbook = excelApp.Workbooks.Add();
|
||||
workbook1 = workbook;
|
||||
|
||||
// Title Block Sheet 설정 (기본 Sheet1)
|
||||
titleBlockSheet = (Excel.Worksheet)workbook.Sheets[1];
|
||||
titleBlockSheet.Name = "Title Block";
|
||||
SetupTitleBlockHeaders();
|
||||
|
||||
// Text Entities Sheet 추가
|
||||
textEntitiesSheet = (Excel.Worksheet)workbook.Sheets.Add();
|
||||
textEntitiesSheet.Name = "Text Entities";
|
||||
SetupTextEntitiesHeaders();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Excel 초기화 중 오류 발생: {ex.Message}");
|
||||
ReleaseExcelObjects();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// Title Block 시트 헤더 설정
|
||||
private void SetupTitleBlockHeaders()
|
||||
{
|
||||
titleBlockSheet.Cells[1, 1] = "Type"; // 예: AttributeReference, AttributeDefinition
|
||||
titleBlockSheet.Cells[1, 2] = "Name"; // BlockReference 이름 또는 BlockDefinition 이름
|
||||
titleBlockSheet.Cells[1, 3] = "Tag"; // Attribute Tag
|
||||
titleBlockSheet.Cells[1, 4] = "Prompt"; // Attribute Prompt
|
||||
titleBlockSheet.Cells[1, 5] = "Value"; // Attribute 값 (TextString)
|
||||
titleBlockSheet.Cells[1, 6] = "Path"; // 원본 DWG 파일 전체 경로
|
||||
titleBlockSheet.Cells[1, 7] = "FileName"; // 원본 DWG 파일 이름만
|
||||
|
||||
// 헤더 행 스타일
|
||||
Excel.Range headerRange = titleBlockSheet.Range["A1:G1"];
|
||||
headerRange.Font.Bold = true;
|
||||
headerRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightBlue);
|
||||
}
|
||||
|
||||
// Text Entities 시트 헤더 설정
|
||||
private void SetupTextEntitiesHeaders()
|
||||
{
|
||||
textEntitiesSheet.Cells[1, 1] = "Type"; // DBText, MText
|
||||
textEntitiesSheet.Cells[1, 2] = "Layer"; // Layer 이름
|
||||
textEntitiesSheet.Cells[1, 3] = "Text"; // 실제 텍스트 내용
|
||||
textEntitiesSheet.Cells[1, 4] = "Path"; // 원본 DWG 파일 전체 경로
|
||||
textEntitiesSheet.Cells[1, 5] = "FileName"; // 원본 DWG 파일 이름만
|
||||
|
||||
// 헤더 행 스타일
|
||||
Excel.Range headerRange = textEntitiesSheet.Range["A1:E1"];
|
||||
headerRange.Font.Bold = true;
|
||||
headerRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGreen);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 단일 DWG 파일에서 AttributeReference/AttributeDefinition 데이터를 추출하여
|
||||
/// 초기화된 Excel 워크시트에 추가합니다.
|
||||
/// </summary>
|
||||
/// <param name="filePath">처리할 DWG 파일 경로</param>
|
||||
/// <param name="progress">진행 상태 보고를 위한 IProgress 객체</param>
|
||||
/// <param name="cancellationToken">작업 취소를 위한 CancellationToken</param>
|
||||
/// <returns>성공 시 true, 실패 시 false 반환</returns>
|
||||
public bool ExportDwgToExcel(string filePath, IProgress<double> progress = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (excelApplication == null)
|
||||
{
|
||||
Console.WriteLine("Excel이 초기화되지 않았습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
progress?.Report(0);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// ODA Database 객체 생성 및 DWG 파일 읽기
|
||||
using (var database = new Database(false, true))
|
||||
{
|
||||
database.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
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;
|
||||
|
||||
foreach (ObjectId entId in btr)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (var ent = tran.GetObject(entId, OpenMode.ForRead) as Entity)
|
||||
{
|
||||
// Layer 이름 가져오기 (공통)
|
||||
string layerName = GetLayerName(ent.LayerId, tran, database);
|
||||
|
||||
// AttributeDefinition 추출
|
||||
if (ent is AttributeDefinition attDef)
|
||||
{
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 1] = attDef.GetType().Name;
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 2] = attDef.BlockName;
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 3] = attDef.Tag;
|
||||
|
||||
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 4] = attDef.Prompt;
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 5] = attDef.TextString;
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 6] = database.Filename;
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 7] = Path.GetFileName(database.Filename);
|
||||
titleBlockCurrentRow++;
|
||||
}
|
||||
// BlockReference 및 그 안의 AttributeReference 추출
|
||||
else if (ent is BlockReference blr)
|
||||
{
|
||||
foreach (ObjectId attId in blr.AttributeCollection)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (var attRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference)
|
||||
{
|
||||
if (attRef != null && attRef.TextString.Trim() !="")
|
||||
{
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 1] = attRef.GetType().Name;
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 2] = blr.Name;
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 3] = attRef.Tag;
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 4] = GetPromptFromAttributeReference(tran, blr, attRef.Tag);
|
||||
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 5] = attRef.TextString;
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 6] = database.Filename;
|
||||
titleBlockSheet.Cells[titleBlockCurrentRow, 7] = Path.GetFileName(database.Filename);
|
||||
titleBlockCurrentRow++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// DBText 엔티티 추출 (별도 시트)
|
||||
else if (ent is DBText dbText)
|
||||
{
|
||||
textEntitiesSheet.Cells[textEntitiesCurrentRow, 1] = "DBText"; // Type
|
||||
textEntitiesSheet.Cells[textEntitiesCurrentRow, 2] = layerName; // Layer
|
||||
textEntitiesSheet.Cells[textEntitiesCurrentRow, 3] = dbText.TextString; // Text
|
||||
textEntitiesSheet.Cells[textEntitiesCurrentRow, 4] = database.Filename; // Path
|
||||
textEntitiesSheet.Cells[textEntitiesCurrentRow, 5] = Path.GetFileName(database.Filename); // FileName
|
||||
textEntitiesCurrentRow++;
|
||||
}
|
||||
// MText 엔티티 추출 (별도 시트)
|
||||
else if (ent is MText mText)
|
||||
{
|
||||
textEntitiesSheet.Cells[textEntitiesCurrentRow, 1] = "MText"; // Type
|
||||
textEntitiesSheet.Cells[textEntitiesCurrentRow, 2] = layerName; // Layer
|
||||
textEntitiesSheet.Cells[textEntitiesCurrentRow, 3] = mText.Contents; // Text
|
||||
textEntitiesSheet.Cells[textEntitiesCurrentRow, 4] = database.Filename; // Path
|
||||
textEntitiesSheet.Cells[textEntitiesCurrentRow, 5] = Path.GetFileName(database.Filename); // FileName
|
||||
textEntitiesCurrentRow++;
|
||||
}
|
||||
}
|
||||
|
||||
processedCount++;
|
||||
double currentProgress = 10.0 + (double)processedCount / totalEntities * 80.0;
|
||||
progress?.Report(Math.Min(currentProgress, 90.0));
|
||||
}
|
||||
}
|
||||
|
||||
tran.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
progress?.Report(100);
|
||||
return true;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
progress?.Report(0);
|
||||
return false;
|
||||
}
|
||||
catch (Teigha.Runtime.Exception ex)
|
||||
{
|
||||
progress?.Report(0);
|
||||
Console.WriteLine($"DWG 파일 처리 중 오류 발생: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
progress?.Report(0);
|
||||
Console.WriteLine($"일반 오류 발생: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Paste the helper function from above here
|
||||
public 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;
|
||||
}
|
||||
/// <summary>
|
||||
/// 현재 Excel 워크북을 지정된 경로에 저장하고 Excel 애플리케이션을 종료합니다.
|
||||
/// </summary>
|
||||
/// <param name="savePath">Excel 파일을 저장할 전체 경로</param>
|
||||
public void SaveAndCloseExcel(string savePath)
|
||||
{
|
||||
if (workbook1 == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
string directory = Path.GetDirectoryName(savePath);
|
||||
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
workbook1.SaveAs(savePath, AccessMode: Excel.XlSaveAsAccessMode.xlNoChange);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Excel 파일 저장 중 오류 발생: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseExcelObjects();
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseExcelObjects()
|
||||
{
|
||||
if (workbook1 != null)
|
||||
{
|
||||
try { workbook1.Close(false); }
|
||||
catch { }
|
||||
}
|
||||
if (excelApplication != null)
|
||||
{
|
||||
try { excelApplication.Quit(); }
|
||||
catch { }
|
||||
}
|
||||
|
||||
ReleaseExcelObjects();
|
||||
}
|
||||
|
||||
private void ReleaseExcelObjects()
|
||||
{
|
||||
ReleaseComObject(titleBlockSheet);
|
||||
ReleaseComObject(textEntitiesSheet);
|
||||
ReleaseComObject(workbook1);
|
||||
ReleaseComObject(excelApplication);
|
||||
|
||||
titleBlockSheet = null;
|
||||
textEntitiesSheet = null;
|
||||
workbook1 = null;
|
||||
excelApplication = null;
|
||||
}
|
||||
|
||||
private void ReleaseComObject(object obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (obj != null && Marshal.IsComObject(obj))
|
||||
{
|
||||
Marshal.ReleaseComObject(obj);
|
||||
}
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
// 해제 중 오류 발생 시 무시
|
||||
}
|
||||
finally
|
||||
{
|
||||
obj = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Layer ID로부터 Layer 이름을 가져옵니다.
|
||||
/// </summary>
|
||||
/// <param name="layerId">Layer ObjectId</param>
|
||||
/// <param name="transaction">현재 트랜잭션</param>
|
||||
/// <param name="database">데이터베이스 객체</param>
|
||||
/// <returns>Layer 이름 또는 빈 문자열</returns>
|
||||
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)
|
||||
{
|
||||
Console.WriteLine($"Layer 이름 가져오기 오류: {ex.Message}");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (excelApplication != null)
|
||||
{
|
||||
CloseExcelObjects();
|
||||
}
|
||||
|
||||
if (appServices != null)
|
||||
{
|
||||
appServices.Dispose();
|
||||
appServices = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
309
Models/SqlDatas.cs
Normal file
309
Models/SqlDatas.cs
Normal file
@@ -0,0 +1,309 @@
|
||||
using Microsoft.Office.Interop.Excel;
|
||||
using Npgsql;
|
||||
using System.Diagnostics;
|
||||
using Teigha.DatabaseServices;
|
||||
using Teigha.Runtime;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System;
|
||||
|
||||
namespace DwgExtractorManual.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// DWG 파일에서 PostgreSQL 데이터베이스로 데이터 내보내기 클래스
|
||||
/// AttributeReference, AttributeDefinition, DBText, MText 추출 지원
|
||||
/// </summary>
|
||||
internal sealed class SqlDatas : IDisposable
|
||||
{
|
||||
Services appServices; // ODA 제품 활성화용
|
||||
readonly string connectionString = "Host=localhost;Database=postgres;Username=postgres;Password=Qwer1234";
|
||||
|
||||
void ActivateAndInitializeODA()
|
||||
{
|
||||
var userInfo = "c2FtYW4gZW5naW5lZXJpbmc=";
|
||||
var userSignature = "F0kuQTmtVpHtvl/TgaFVGE92/YqGmYR9SLoXckEjnOk8NoAQh7Sg6GQruVC04JqD4C/IipxJYqpqvMfMc2auRMG+cAJCKqKUE2djIMdkUdb+C5IVx2c97fcK5ba3n8DDvB54Upokajl+6j12yD8h8MKGOR3Z3zysObeXD62bFpQgp00GCYTqlxEZtTIRjHIPAfJfix8Y0jtXWWYyVJ3LYOu86as5xtx+hY1aakpYIJiQk/6pGd84qSn/9K1w8nxR7UrFzieDeQ/xM58BHSD4u/ZxVJwvv6Uy10tsdBFBTvfJMAFp05Y7yeyeCNr100tA3iOfmWoXAVRHfxnkPfiYR54aK04QI+R6OGkI+yd1oR5BtmN6BdDt3z8KYK5EpFGJGiJIGoUy5PvkYdJ2VV6xe9JWBiIJuI/tDn1Y+uyTQFA9qaDHnOURriXsRGfy8reDPf1eejybSJxWKkpilG6RXhq3xHlCkjZzh1Q45S+xYXNGatcWMm9nkn20M8Ke5JEVaI9w/p2GE36CHRtRQbt8kfPmsbWNXJCFr4svHW2MPbCKWoyn5XEyMWBnuAKi74zvczB13DKjf29SqSIgF5k/hwy2QrgvnaKzY1k8bw8w2/k0vJXcS3GKOB/ZYDle1tf/lkAD1HtnF9zE18TiXhVnqwAVjwg4ui1RPLn/LMs6b5Y=";
|
||||
Services.odActivate(userInfo, userSignature);
|
||||
appServices = new Services();
|
||||
}
|
||||
|
||||
void CreateTables()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var conn = new NpgsqlConnection(connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// AttributeReferences 테이블 생성 (Title Block용)
|
||||
using (var cmd = new NpgsqlCommand())
|
||||
{
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = @"
|
||||
CREATE TABLE IF NOT EXISTS AttributeReferences (
|
||||
Type VARCHAR(100),
|
||||
Name VARCHAR(255),
|
||||
Tag VARCHAR(255),
|
||||
Prompt VARCHAR(255),
|
||||
Value TEXT,
|
||||
Path TEXT,
|
||||
FileName TEXT,
|
||||
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// TextEntities 테이블 생성 (DBText/MText용)
|
||||
using (var cmd = new NpgsqlCommand())
|
||||
{
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = @"
|
||||
CREATE TABLE IF NOT EXISTS TextEntities (
|
||||
Type VARCHAR(50),
|
||||
Layer VARCHAR(255),
|
||||
Text TEXT,
|
||||
Path TEXT,
|
||||
FileName TEXT,
|
||||
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"테이블 생성 중 오류: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public SqlDatas()
|
||||
{
|
||||
ActivateAndInitializeODA();
|
||||
CreateTables();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DWG 파일 데이터를 데이터베이스에 저장
|
||||
/// </summary>
|
||||
/// <param name="filePath">DWG 파일 경로</param>
|
||||
/// <returns>실패시 true, 성공시 false (기존 콘솔 버전과 호환성)</returns>
|
||||
public bool DwgToDB(string filePath)
|
||||
{
|
||||
var result = false;
|
||||
using (var database = new Database(false, true))
|
||||
{
|
||||
try
|
||||
{
|
||||
database.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndWriteNoShare, false, null);
|
||||
|
||||
using (var conn = new NpgsqlConnection(connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (var tran = database.TransactionManager.StartTransaction())
|
||||
{
|
||||
// Document Information 추출
|
||||
DatabaseSummaryInfo summaryInfo = database.SummaryInfo;
|
||||
string documentInfo = $"Title: {summaryInfo.Title}, Subject: {summaryInfo.Subject}, Author: {summaryInfo.Author}";
|
||||
Dictionary<string, string> dicTagPrompt = new Dictionary<string, string>();
|
||||
|
||||
// Block Table 접근
|
||||
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)
|
||||
{
|
||||
// Layer 이름 가져오기 (공통)
|
||||
string layerName = GetLayerName(ent.LayerId, tran, database);
|
||||
|
||||
// AttributeDefinition 처리는 생략 (필요시 추가)
|
||||
if (ent is AttributeDefinition attDef)
|
||||
{
|
||||
// 현재는 AttributeDefinition 처리하지 않음
|
||||
}
|
||||
// DBText 엔티티 처리 (별도 테이블)
|
||||
else if (ent is DBText dbText)
|
||||
{
|
||||
using (var cmd = new NpgsqlCommand())
|
||||
{
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO TextEntities (Type, Layer, Text, Path, FileName)
|
||||
VALUES (@Type, @Layer, @Text, @Path, @FileName)";
|
||||
|
||||
cmd.Parameters.AddWithValue("Type", "DBText");
|
||||
cmd.Parameters.AddWithValue("Layer", layerName);
|
||||
cmd.Parameters.AddWithValue("Text", dbText.TextString ?? "");
|
||||
cmd.Parameters.AddWithValue("Path", database.Filename);
|
||||
cmd.Parameters.AddWithValue("FileName", Path.GetFileName(database.Filename));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
// MText 엔티티 처리 (별도 테이블)
|
||||
else if (ent is MText mText)
|
||||
{
|
||||
using (var cmd = new NpgsqlCommand())
|
||||
{
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO TextEntities (Type, Layer, Text, Path, FileName)
|
||||
VALUES (@Type, @Layer, @Text, @Path, @FileName)";
|
||||
|
||||
cmd.Parameters.AddWithValue("Type", "MText");
|
||||
cmd.Parameters.AddWithValue("Layer", layerName);
|
||||
cmd.Parameters.AddWithValue("Text", mText.Contents ?? "");
|
||||
cmd.Parameters.AddWithValue("Path", database.Filename);
|
||||
cmd.Parameters.AddWithValue("FileName", Path.GetFileName(database.Filename));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
else if (ent is BlockReference blr)
|
||||
{
|
||||
foreach (ObjectId attId in blr.AttributeCollection)
|
||||
{
|
||||
using (var attRef = tran.GetObject(attId, OpenMode.ForRead) as AttributeReference)
|
||||
{
|
||||
using (var cmd = new NpgsqlCommand())
|
||||
{
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO AttributeReferences (Type, Name, Tag, Prompt, Value, Path, FileName)
|
||||
VALUES (@Type, @Name, @Tag, @Prompt, @Value, @Path, @FileName)";
|
||||
|
||||
var typeFullName = attRef.GetType().ToString();
|
||||
var typeName = typeFullName.Substring(typeFullName.LastIndexOf('.') + 1);
|
||||
var blkName = blr.Name;
|
||||
var attTag = attRef.Tag;
|
||||
string prompt = "";
|
||||
string tString = "";
|
||||
|
||||
if (!bt.Has(blkName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dicTagPrompt.ContainsKey(attTag))
|
||||
{
|
||||
prompt = dicTagPrompt[attTag];
|
||||
}
|
||||
else
|
||||
{
|
||||
// 블록 정의 찾기
|
||||
ObjectId blockDefId = bt[blkName];
|
||||
BlockTableRecord blkDef = (BlockTableRecord)tran.GetObject(blockDefId, OpenMode.ForRead);
|
||||
|
||||
// AttributeDefinition 순회 및 태그 일치 확인
|
||||
foreach (ObjectId objId in blkDef)
|
||||
{
|
||||
DBObject dbObj = tran.GetObject(objId, OpenMode.ForRead);
|
||||
|
||||
if (dbObj is AttributeDefinition adef)
|
||||
{
|
||||
if (adef.Tag.ToUpper() == attTag.ToUpper())
|
||||
{
|
||||
prompt = adef.Prompt;
|
||||
dicTagPrompt.Add(attTag, prompt);
|
||||
tString = adef.TextString;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd.Parameters.AddWithValue("Type", typeName);
|
||||
cmd.Parameters.AddWithValue("Name", blr.Name);
|
||||
cmd.Parameters.AddWithValue("Tag", attTag);
|
||||
cmd.Parameters.AddWithValue("Prompt", prompt);
|
||||
|
||||
if (!string.IsNullOrEmpty(attRef.TextString))
|
||||
cmd.Parameters.AddWithValue("Value", attRef.TextString);
|
||||
else
|
||||
cmd.Parameters.AddWithValue("Value", tString);
|
||||
|
||||
cmd.Parameters.AddWithValue("Path", database.Filename);
|
||||
cmd.Parameters.AddWithValue("FileName", Path.GetFileName(database.Filename));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tran.Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
result = true; // 실패시 true 반환 (기존 버전과 호환성)
|
||||
Debug.WriteLine($"DWG 파일 처리 중 오류: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 데이터베이스 연결 테스트
|
||||
/// </summary>
|
||||
/// <returns>연결 성공 여부</returns>
|
||||
public bool TestConnection()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var conn = new NpgsqlConnection(connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"데이터베이스 연결 테스트 실패: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Layer ID로부터 Layer 이름을 가져옵니다.
|
||||
/// </summary>
|
||||
/// <param name="layerId">Layer ObjectId</param>
|
||||
/// <param name="transaction">현재 트랜잭션</param>
|
||||
/// <param name="database">데이터베이스 객체</param>
|
||||
/// <returns>Layer 이름 또는 빈 문자열</returns>
|
||||
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 이름 가져오기 오류: {ex.Message}");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 리소스 해제
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (appServices != null)
|
||||
{
|
||||
appServices.Dispose();
|
||||
appServices = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user