1차 완료

This commit is contained in:
horu2day
2025-08-13 13:57:46 +09:00
parent f114b8b642
commit 52fbc1c967
3 changed files with 167 additions and 73 deletions

View File

@@ -422,39 +422,53 @@ namespace DwgExtractorManual.Models
int maxTableRow = 0;
foreach (var cellBoundary in noteEntity.CellBoundaries)
{
var (cellRow, cellCol) = ParseRowColFromLabel(cellBoundary.Label);
Debug.WriteLine($"[DEBUG] CellBoundary 처리: {cellBoundary.Label} → Row={cellRow}, Col={cellCol}, Text='{cellBoundary.CellText}'");
var (sRow, sCol, eRow, eCol) = ParseCellRangeFromLabel(cellBoundary.Label);
Debug.WriteLine($"[DEBUG] CellBoundary 처리: {cellBoundary.Label} → Range=R{sRow}C{sCol}:R{eRow}C{eCol}, Text='{cellBoundary.CellText}'");
if (cellRow > 0 && cellCol > 0)
if (sRow > 0 && sCol > 0 && eRow > 0 && eCol > 0)
{
// Excel에서 테이블 위치 계산:
// R1 → Note의 현재 행 (currentRow)
// R2 → Note의 다음 행 (currentRow + 1)
// C1 → G열(7), C2 → H열(8)
int excelRow = currentRow + (cellRow - 1); // R1=currentRow, R2=currentRow+1, ...
int excelCol = 7 + (cellCol - 1); // C1=G열(7), C2=H열(8), ...
// 병합된 영역의 셀 개수 계산: (eRow - sRow) × (eCol - sCol)
int rowCount = eRow - sRow; // 행 개수 (bottomRight - topLeft)
int colCount = eCol - sCol; // 열 개수 (bottomRight - topLeft)
Debug.WriteLine($"[DEBUG] Excel 위치: {cellBoundary.Label} → Excel[{excelRow},{excelCol}]");
Debug.WriteLine($"[DEBUG] 병합 영역 크기: {rowCount+1}행 × {colCount+1}열");
// Excel 범위 체크 (최대 20개 컬럼까지)
if (excelCol <= 26) // Z열까지
// 병합된 영역의 모든 셀에 텍스트 복사 (topLeft부터 bottomRight-1까지)
for (int r = sRow; r < eRow; r++) // < eRow (bottomRight 제외)
{
// CellText가 비어있어도 일단 배치해보기 (디버그용)
var cellValue = string.IsNullOrEmpty(cellBoundary.CellText) ? "[빈셀]" : cellBoundary.CellText;
worksheet.Cells[excelRow, excelCol] = cellValue;
Debug.WriteLine($"[DEBUG] ✅ 셀 배치 완료: {cellBoundary.Label} → Excel[{excelRow},{excelCol}] = '{cellValue}'");
for (int c = sCol; c < eCol; c++) // < eCol (bottomRight 제외)
{
// Excel에서 테이블 위치 계산:
// R1 → Note의 현재 행 (currentRow)
// R2 → Note의 다음 행 (currentRow + 1)
// C1 → G열(7), C2 → H열(8)
int excelRow = currentRow + (r - 1); // R1=currentRow, R2=currentRow+1, ...
int excelCol = 7 + (c - 1); // C1=G열(7), C2=H열(8), ...
// Excel 범위 체크 (최대 20개 컬럼까지)
if (excelCol <= 26) // Z열까지
{
// CellText가 비어있어도 일단 배치해보기 (디버그용)
var cellValue = string.IsNullOrEmpty(cellBoundary.CellText) ? "[빈셀]" : cellBoundary.CellText;
// 텍스트 형식으로 설정하여 "0:0" 같은 값이 시간으로 포맷되지 않도록 함
var cell = (Excel.Range)worksheet.Cells[excelRow, excelCol];
cell.NumberFormat = "@"; // 텍스트 형식
cell.Value = cellValue;
Debug.WriteLine($"[DEBUG] ✅ 셀 복사: R{r}C{c} → Excel[{excelRow},{excelCol}] = '{cellValue}'");
}
else
{
Debug.WriteLine($"[DEBUG] ❌ Excel 컬럼 범위 초과: {excelCol} > 26");
}
// 테이블이 차지하는 최대 행 수 추적
maxTableRow = Math.Max(maxTableRow, r);
}
}
else
{
Debug.WriteLine($"[DEBUG] ❌ Excel 컬럼 범위 초과: {excelCol} > 26");
}
// 테이블이 차지하는 최대 행 수 추적
maxTableRow = Math.Max(maxTableRow, cellRow);
}
else
{
Debug.WriteLine($"[DEBUG] ❌ 잘못된 Row/Col: {cellBoundary.Label} → Row={cellRow}, Col={cellCol}");
Debug.WriteLine($"[DEBUG] ❌ 잘못된 Range: {cellBoundary.Label} → R{sRow}C{sCol}:R{eRow}C{eCol}");
}
}
@@ -479,7 +493,10 @@ namespace DwgExtractorManual.Models
for (int cellIndex = 0; cellIndex < Math.Min(tableCells.Length, 15); cellIndex++)
{
var cellValue = tableCells[cellIndex].Trim().Trim('"'); // 따옴표 제거
worksheet.Cells[currentRow, 7 + cellIndex] = cellValue; // G열(7)부터 시작
// 텍스트 형식으로 설정하여 "0:0" 같은 값이 시간으로 포맷되지 않도록 함
var cell = (Excel.Range)worksheet.Cells[currentRow, 7 + cellIndex];
cell.NumberFormat = "@"; // 텍스트 형식
cell.Value = cellValue; // G열(7)부터 시작
}
// 표의 첫 번째 행이 아니면 새로운 Excel 행 추가
@@ -551,30 +568,59 @@ namespace DwgExtractorManual.Models
/// <summary>
/// 라벨에서 Row, Col 정보를 파싱합니다.
/// 예: "R1C2" → (1, 2) 또는 "R2C2→R3C4" → (2, 2) (시작 위치 사용)
/// 라벨에서 셀 범위 정보를 파싱합니다.
/// 예: "R1C2" → (1, 2, 1, 2) 또는 "R2C2→R3C4" → (2, 2, 3, 4)
/// </summary>
private (int row, int col) ParseRowColFromLabel(string label)
private (int sRow, int sCol, int eRow, int eCol) ParseCellRangeFromLabel(string label)
{
try
{
if (string.IsNullOrEmpty(label))
return (0, 0);
return (0, 0, 0, 0);
// "R2C2→R3C4" 형태인 경우 시작 부분만 사용
var startPart = label;
if (label.Contains("→"))
{
startPart = label.Split('→')[0];
// "R2C2→R3C4" 형태 - 범위 파싱
var parts = label.Split('→');
if (parts.Length == 2)
{
var (sRow, sCol) = ParseSingleCell(parts[0]);
var (eRow, eCol) = ParseSingleCell(parts[1]);
return (sRow, sCol, eRow, eCol);
}
}
else
{
// "R1C2" 형태 - 단일 셀
var (row, col) = ParseSingleCell(label);
return (row, col, row, col);
}
return (0, 0, 0, 0);
}
catch
{
return (0, 0, 0, 0);
}
}
var rIndex = startPart.IndexOf('R');
var cIndex = startPart.IndexOf('C');
/// <summary>
/// 단일 셀 위치를 파싱합니다. (예: "R2C3" → (2, 3))
/// </summary>
private (int row, int col) ParseSingleCell(string cellStr)
{
try
{
if (string.IsNullOrEmpty(cellStr))
return (0, 0);
var rIndex = cellStr.IndexOf('R');
var cIndex = cellStr.IndexOf('C');
if (rIndex >= 0 && cIndex > rIndex)
{
var rowStr = startPart.Substring(rIndex + 1, cIndex - rIndex - 1);
var colStr = startPart.Substring(cIndex + 1);
var rowStr = cellStr.Substring(rIndex + 1, cIndex - rIndex - 1);
var colStr = cellStr.Substring(cIndex + 1);
if (int.TryParse(rowStr, out int row) && int.TryParse(colStr, out int col))
{