Files
Pier_v1/Code/review_pipeline/make_review_xlsx.py
T
ahnyongjooandClaude Sonnet 5.5 964a841de1 chore(rebar): Pier_T_rebar 작업 폴더 초기 구성 및 외부 의존 파일 통합
- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환
- Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용
- pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관)
- worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md)
- D:\Rhino-MCP 경로 참조를 새 위치로 치환

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 11:20:18 +09:00

166 lines
8.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""운곡교 '대조표_C1-C16_도면모델_분류_V2.xlsx' 형식(분류 안내 / ① 도면↔모델 불일치(+캡처) / ② 전체 대조표 / ③ 미검토 / ④ 측정 근거)으로
교량별 검토 엑셀을 만든다. 사용: python -I make_review_xlsx.py <cfg.json> <out.xlsx>
cfg: bridge, title, purpose, legend_counts(자동), items[{code,mark,content,cmp,diff,drawing_side,action,kind,image}],
rows[{no,mark,item,table,detail,model,verdict,note,kind}], unchecked[{item,content,note,status}], basis[{item,content,note}]
도면 내부 불일치는 이 엑셀에 넣지 않는다(별도 보관 파일).
"""
import sys, json, os
sys.path.insert(0, r"C:\Users\User\AppData\Local\Temp\claude\D--Rhino-MCP-rhino-mcp-main\f46b47bc-9105-4079-9b62-fcbee31b26ae\scratchpad\pylib")
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.drawing.image import Image as XImage
from openpyxl.utils import get_column_letter
from PIL import Image as PImage
cfg = json.load(open(sys.argv[1], encoding="utf-8"))
OUT = sys.argv[2]
thin = Side(style="thin", color="999999")
BR = Border(left=thin, right=thin, top=thin, bottom=thin)
HF = PatternFill("solid", fgColor="D9D9D9")
FILL = {"도면↔모델": PatternFill("solid", fgColor="F8CBAD"), "기준↔모델": PatternFill("solid", fgColor="E6C84A"),
"도면 내부": PatternFill("solid", fgColor="FFF2CC"), "일치": PatternFill("solid", fgColor="E2F0D9"),
"미확인": PatternFill("solid", fgColor="D9D9D9")}
TOPW = Alignment(wrap_text=True, vertical="top")
CEN = Alignment(wrap_text=True, vertical="center", horizontal="center")
wb = Workbook()
# ------------------------------------------------ 분류 안내
ws = wb.active
ws.title = "분류 안내"
ws.append([cfg["title"]])
ws["A1"].font = Font(bold=True, size=14)
ws.append([cfg["purpose"]])
ws["A2"].alignment = TOPW
ws.merge_cells("A2:E2")
ws.row_dimensions[2].height = 64
ws.append([])
ws.append(["색", "구분", "뜻", "항목 수", "볼 시트"])
for c in range(1, 6):
ws.cell(row=4, column=c).font = Font(bold=True)
ws.cell(row=4, column=c).fill = HF
ws.cell(row=4, column=c).border = BR
cnt = {}
for r in cfg["rows"]:
cnt[r["kind"]] = cnt.get(r["kind"], 0) + 1
legend = [("주황", "도면↔모델", "도면에는 정보가 있거나 없는데 모델이 다르게 만들어졌거나 가정한 것 (모델 확인·수정 대상)", "① 도면↔모델 불일치"),
("진한 노랑", "기준↔모델", "설계기준(KDS 24 14 21)에 모델이 맞는지 (도면에는 정보 없음)", "① 도면↔모델 불일치"),
("초록", "일치", "도면(재료표·철근상세)과 모델이 일치", "② 전체 대조표"),
("회색", "미확인", "도면에 정보가 없어 확인하지 못한 것", "② 전체 대조표 · ③")]
for col, kind, mean, sheet in legend:
n = len([i for i in cfg["items"] if i["kind"] == kind]) if kind in ("도면↔모델", "기준↔모델") else cnt.get(kind, 0)
ws.append([col, kind, mean, str(n), sheet])
r = ws.max_row
ws.cell(row=r, column=2).fill = FILL[kind]
for c in range(1, 6):
ws.cell(row=r, column=c).border = BR
ws.cell(row=r, column=c).alignment = TOPW
ws.row_dimensions[r].height = 40
ws.append([])
ws.append(["※ 도면 내부 불일치(도면끼리 다른 것)는 이 파일에 넣지 않고 '도면내부_오류_보관.md' 에 따로 보관 — 요청 시 보고."])
ws.append(["※ ② 전체 대조표의 구분 열은 마크 행 수 기준, ① 의 항목 수는 코드(M-n) 수 기준."])
for i, w in enumerate([12, 14, 80, 10, 26], 1):
ws.column_dimensions[get_column_letter(i)].width = w
# ------------------------------------------------ ① 도면↔모델 불일치
w1 = wb.create_sheet("① 도면↔모델 불일치")
w1.append(["① 도면 ↔ 모델 불일치 (최우선 확인) — 주황 / 진한 노랑 / 회색"])
w1["A1"].font = Font(bold=True, size=13)
w1.append([cfg["sheet1_desc"]])
w1["A2"].alignment = TOPW
w1.merge_cells("A2:I2")
w1.row_dimensions[2].height = 48
w1.append([])
heads = ["번호", "마크", "내용", "비교", "차이 크기", "도면 쪽 상태", "확인·조치 필요 사항", "구분", "캡처 (왼쪽·위 도면 / 오른쪽·아래 모델)"]
w1.append(heads)
for c in range(1, 10):
cell = w1.cell(row=4, column=c)
cell.font = Font(bold=True)
cell.fill = HF
cell.border = BR
cell.alignment = CEN
w1.row_dimensions[4].height = 30
MAXH = 520
for it in cfg["items"]:
w1.append([it["code"], it["mark"], it["content"], it["cmp"], it["diff"], it["drawing_side"], it["action"], it["kind"], None])
r = w1.max_row
for c in range(1, 9):
cell = w1.cell(row=r, column=c)
cell.border = BR
cell.alignment = TOPW
w1.cell(row=r, column=8).fill = FILL[it["kind"]]
w1.cell(row=r, column=1).font = Font(bold=True)
if it.get("image") and os.path.exists(it["image"]):
im = PImage.open(it["image"])
h = MAXH
w = int(im.width * h / im.height)
xi = XImage(it["image"])
xi.width, xi.height = w, h
w1.add_image(xi, "I%d" % r)
w1.row_dimensions[r].height = h * 0.75 + 6
w1.column_dimensions["I"].width = max(w1.column_dimensions["I"].width or 0, w / 7.0)
w1.cell(row=r, column=9).border = BR
for i, w in enumerate([8, 12, 62, 24, 26, 34, 52, 12], 1):
w1.column_dimensions[get_column_letter(i)].width = w
w1.freeze_panes = "A5"
# ------------------------------------------------ ② 전체 대조표
w2 = wb.create_sheet("② 전체 대조표")
w2.append(["② 도면(재료표·철근상세) · 라이노 모델 대조표 — 전 마크"])
w2["A1"].font = Font(bold=True, size=13)
w2.append(["구분 열 색: 초록=일치 / 주황=도면↔모델 / 진한 노랑=기준↔모델 / 회색=미확인. 모델 치수는 중심선 꼭짓점 사이 거리(각진 치수), 길이는 모델 철근의 설계길이(user string)."])
w2.append([])
h2 = ["번호", "마크", "검토 항목", "도면 재료표 (L × N = 총길이)", "도면 철근상세 (치수)", "라이노 모델", "판정", "비고 / 근거", "구분"]
w2.append(h2)
for c in range(1, 10):
cell = w2.cell(row=4, column=c)
cell.font = Font(bold=True)
cell.fill = HF
cell.border = BR
cell.alignment = CEN
for r_ in cfg["rows"]:
w2.append([r_["no"], r_["mark"], r_["item"], r_["table"], r_["detail"], r_["model"], r_["verdict"], r_["note"], r_["kind"]])
r = w2.max_row
for c in range(1, 10):
cell = w2.cell(row=r, column=c)
cell.border = BR
cell.alignment = TOPW
w2.cell(row=r, column=9).fill = FILL[r_["kind"]]
n = max(len(str(r_["note"])) / 40.0, len(str(r_["model"])) / 34.0, len(str(r_["detail"])) / 30.0, 1)
w2.row_dimensions[r].height = max(32, 17 * (int(n) + 1))
for i, w in enumerate([6, 9, 26, 30, 32, 38, 14, 52, 12], 1):
w2.column_dimensions[get_column_letter(i)].width = w
w2.freeze_panes = "C5"
# ------------------------------------------------ ③ 미검토
w3 = wb.create_sheet("③ 미검토·확인 불가")
w3.append(["항목", "내용", "비고", "상태"])
for c in range(1, 5):
w3.cell(row=1, column=c).font = Font(bold=True)
w3.cell(row=1, column=c).fill = HF
for u in cfg["unchecked"]:
w3.append([u["item"], u["content"], u["note"], u["status"]])
for c in range(1, 5):
w3.cell(row=w3.max_row, column=c).alignment = TOPW
w3.row_dimensions[w3.max_row].height = 50
for i, w in enumerate([22, 80, 40, 12], 1):
w3.column_dimensions[get_column_letter(i)].width = w
# ------------------------------------------------ ④ 측정 근거
w4 = wb.create_sheet("④ 측정 근거")
w4.append(["항목", "측정/내용", "비고"])
for c in range(1, 4):
w4.cell(row=1, column=c).font = Font(bold=True)
w4.cell(row=1, column=c).fill = HF
for b in cfg["basis"]:
w4.append([b["item"], b["content"], b.get("note", "")])
for c in range(1, 4):
w4.cell(row=w4.max_row, column=c).alignment = TOPW
w4.row_dimensions[w4.max_row].height = 48
for i, w in enumerate([30, 95, 52], 1):
w4.column_dimensions[get_column_letter(i)].width = w
try:
wb.save(OUT)
print("saved", OUT)
except PermissionError:
print("열려 있어 저장 실패:", OUT)