- 서버: xlsx 시트 XML 열 폭 · 숨김을 보냄(엑셀 보기 격자 `열`) - 화면: 폭 없는 열은 글 길이로 처음 폭(최소 6 · 최대 60 · 여러 열 병합 제목 칸은 뺌) - 읽기 전용 격자도 열 폭 끌기 · 경계 두 번 누름 맞춤(보기만 · 저장 · 되돌리기 · onChange 없음) - 열 경계 오른쪽 반에서도 경계로 읽음 · 단가 카드 미리보기는 사본으로 보임 - 시험: test_741_sheet_widths · test_stage2_autofit(esbuild 묶어 node) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
50 lines
1.6 KiB
Python
50 lines
1.6 KiB
Python
"""741-1 지킴 — 일위대가 엑셀 보기 열 폭: xlsx 도 파일 열 폭을 서버가 보냄 · 열 끌기 · 두 번 눌러
|
|
맞춤은 읽기 전용에서도 열림(화면 수치 판정은 tmp 일회 검증)."""
|
|
|
|
import io
|
|
from pathlib import Path
|
|
|
|
import openpyxl
|
|
|
|
from M02_MasterTemplete import M02_Hopyo_Grid as grid
|
|
|
|
ROOT = Path(__file__).parents[2]
|
|
SS = ROOT / "A00_Common/spreadsheet"
|
|
|
|
|
|
def _xlsx(widths: dict[str, float]) -> bytes:
|
|
wb = openpyxl.Workbook()
|
|
ws = wb.active
|
|
ws.title = "일위대가"
|
|
ws["A1"] = "x"
|
|
for letter, width in widths.items():
|
|
ws.column_dimensions[letter].width = width
|
|
ws.column_dimensions["E"].hidden = True
|
|
out = io.BytesIO()
|
|
wb.save(out)
|
|
return out.getvalue()
|
|
|
|
|
|
def test_xlsx_widths_read_from_cols():
|
|
got = grid._xlsx_widths(_xlsx({"A": 30, "C": 12.5}))["일위대가"]
|
|
assert got["A"] == {"폭": 30.0} and got["C"] == {"폭": 12.5}
|
|
assert got["E"].get("숨김") is True
|
|
|
|
|
|
def test_xlsx_without_widths_is_empty_and_garbage_is_safe():
|
|
assert grid._xlsx_widths(_xlsx({}))["일위대가"].keys() <= {"E"}
|
|
assert grid._xlsx_widths(b"not a zip") == {}
|
|
|
|
|
|
def test_xlsx_sheet_carries_widths():
|
|
data = _xlsx({"A": 30})
|
|
sheets = grid._xlsx("a.xlsx", data)["시트"]
|
|
assert sheets and sheets[0]["열"]["A"]["폭"] == 30.0
|
|
|
|
|
|
def test_readonly_still_resizes_columns():
|
|
spread = (SS / "spreadsheet.ts").read_text(encoding="utf-8")
|
|
assert 'readOnly && command.종류 !== "열폭"' in spread
|
|
mouse = (SS / "spreadsheet_mouse.ts").read_text(encoding="utf-8")
|
|
assert 'ctx.readOnly && hit.kind !== "colEdge"' in mouse
|