diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 405f86a..bebf957 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -1941,6 +1941,7 @@ namespace DwgExtractorManual /// 처리할 폴더 경로 private async Task ProcessFilesDwgOnly(string sourceFolderPath) { + ExportExcel exportExcel = null; try { string resultFolder = txtResultFolder.Text; @@ -1964,29 +1965,30 @@ namespace DwgExtractorManual LogMessage($"📂 소스 폴더: {sourceFolderPath}"); LogMessage($"💾 결과 폴더: {resultFolder}"); - LogMessage("📊 Excel 내보내기 모드로 시작합니다..."); - LogMessage("📝 Excel 애플리케이션을 초기화합니다..."); + LogMessage("📊 Excel 내보내기 모드로 시작합니다..."); + LogMessage("📝 Excel 애플리케이션을 초기화합니다..."); - _exportExcel = new ExportExcel(); + exportExcel = new ExportExcel(); + exportExcel.ClearAccumulatedData(); - // UI 응답성을 위한 양보 - await Task.Yield(); + // UI 응답성을 위한 양보 + await Task.Yield(); - // 각 DWG 파일 처리 - foreach (string dwgFile in dwgFiles) - { - LogMessage($"📄 DWG 파일 처리 중: {Path.GetFileName(dwgFile)}"); - _exportExcel.ExportDwgToExcel(dwgFile); + // 각 DWG 파일 처리 + foreach (string dwgFile in dwgFiles) + { + LogMessage($"📄 DWG 파일 처리 중: {Path.GetFileName(dwgFile)}"); + exportExcel.ExportDwgToExcel(dwgFile); - // UI 응답성을 위한 양보 - await Task.Yield(); - } + // UI 응답성을 위한 양보 + await Task.Yield(); + } - // DWG 전용 워크북 저장 - LogMessage("💾 DWG 전용 Excel 파일 저장 중..."); - _exportExcel.SaveDwgOnlyMappingWorkbook(resultFolder); + // DWG 전용 워크북 저장 + LogMessage("💾 DWG 전용 Excel 파일 저장 중..."); + exportExcel.SaveDwgOnlyMappingWorkbook(resultFolder); - LogMessage("✅ DWG 전용 Excel 파일 저장 완료"); + LogMessage("✅ DWG 전용 Excel 파일 저장 완료"); } catch (Exception ex) { @@ -1995,8 +1997,8 @@ namespace DwgExtractorManual } finally { - _exportExcel?.Dispose(); - _exportExcel = null; + exportExcel?.Dispose(); + exportExcel = null; } } diff --git a/Models/ExportExcel.cs b/Models/ExportExcel.cs index c4ba073..bd69ac5 100644 --- a/Models/ExportExcel.cs +++ b/Models/ExportExcel.cs @@ -476,12 +476,17 @@ namespace DwgExtractorManual.Models try { - mappingSheet.Cells[currentRow, 1] = fileName; // FileName - mappingSheet.Cells[currentRow, 2] = mapKey; // MapKey - mappingSheet.Cells[currentRow, 3] = aiLabel ?? ""; // AILabel - mappingSheet.Cells[currentRow, 4] = dwgTag ?? ""; // DwgTag - mappingSheet.Cells[currentRow, 5] = attValue ?? ""; // DwgValue (Att_value) - mappingSheet.Cells[currentRow, 6] = pdfValue ?? ""; // PdfValue (Pdf_value) + // 배치 업데이트를 위한 배열 사용 + object[,] rowData = new object[1, 6]; + rowData[0, 0] = fileName; // FileName + rowData[0, 1] = mapKey; // MapKey + rowData[0, 2] = aiLabel ?? ""; // AILabel + rowData[0, 3] = dwgTag ?? ""; // DwgTag + rowData[0, 4] = attValue ?? ""; // DwgValue (Att_value) + rowData[0, 5] = pdfValue ?? ""; // PdfValue (Pdf_value) + + Excel.Range range = mappingSheet.Range[mappingSheet.Cells[currentRow, 1], mappingSheet.Cells[currentRow, 6]]; + range.Value = rowData; Debug.WriteLine($"[DEBUG] Row {currentRow} written successfully"); } @@ -880,24 +885,36 @@ namespace DwgExtractorManual.Models headerRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray); headerRange.Borders.LineStyle = Excel.XlLineStyle.xlContinuous; - // 데이터 입력 - int row = 2; - foreach (var fileEntry in FileToMapkeyToLabelTagValuePdf) + // 데이터 입력 (배치 처리로 성능 향상) + int totalRows = FileToMapkeyToLabelTagValuePdf.Sum(f => f.Value.Count); + if (totalRows > 0) { - string fileName = fileEntry.Key; - foreach (var mapEntry in fileEntry.Value) + object[,] data = new object[totalRows, 5]; + int row = 0; + + foreach (var fileEntry in FileToMapkeyToLabelTagValuePdf) { - string mapKey = mapEntry.Key; - var (aiLabel, dwgTag, dwgValue, pdfValue) = mapEntry.Value; + string fileName = fileEntry.Key; + foreach (var mapEntry in fileEntry.Value) + { + string mapKey = mapEntry.Key; + var (aiLabel, dwgTag, dwgValue, pdfValue) = mapEntry.Value; - dwgOnlyWorksheet.Cells[row, 1] = fileName; - dwgOnlyWorksheet.Cells[row, 2] = mapKey; - dwgOnlyWorksheet.Cells[row, 3] = aiLabel; - dwgOnlyWorksheet.Cells[row, 4] = dwgTag; - dwgOnlyWorksheet.Cells[row, 5] = dwgValue; + data[row, 0] = fileName; + data[row, 1] = mapKey; + data[row, 2] = aiLabel; + data[row, 3] = dwgTag; + data[row, 4] = dwgValue; - row++; + row++; + } } + + // 한 번에 모든 데이터 입력 + Excel.Range dataRange = dwgOnlyWorksheet.Range[ + dwgOnlyWorksheet.Cells[2, 1], + dwgOnlyWorksheet.Cells[totalRows + 1, 5]]; + dataRange.Value = data; } // 컬럼 자동 크기 조정 @@ -918,8 +935,12 @@ namespace DwgExtractorManual.Models // 워크북 정리 dwgOnlyWorkbook.Close(false); - System.Runtime.InteropServices.Marshal.ReleaseComObject(dwgOnlyWorksheet); - System.Runtime.InteropServices.Marshal.ReleaseComObject(dwgOnlyWorkbook); + ReleaseComObject(dwgOnlyWorksheet); + ReleaseComObject(dwgOnlyWorkbook); + + // 가비지 컬렉션 강제 실행으로 메모리 해제 + GC.Collect(); + GC.WaitForPendingFinalizers(); } catch (System.Exception ex) { @@ -1372,6 +1393,29 @@ namespace DwgExtractorManual.Models } } + /// + /// 폴더 간 처리를 위해 누적된 데이터를 정리합니다. + /// + public void ClearAccumulatedData() + { + try + { + Debug.WriteLine("[DEBUG] 누적 데이터 정리 시작"); + + FileToMapkeyToLabelTagValuePdf.Clear(); + + titleBlockCurrentRow = 2; + textEntitiesCurrentRow = 2; + mappingDataCurrentRow = 2; + + Debug.WriteLine("✅ 누적 데이터 정리 완료"); + } + catch (System.Exception ex) + { + Debug.WriteLine($"❌ 누적 데이터 정리 중 오류: {ex.Message}"); + } + } + /// /// JSON 내용을 정리하여 파싱 가능한 상태로 만듭니다. /// 주석 제거 및 기타 무효한 문자 처리