"""534-2 — 내장 엑셀 내보내기: 인쇄 HTML(Node 번들 `printHtml`) · xlsx 되읽기 · SVG → PNG · PDF 쪽 수. 책 하나(시트 둘 · 병합 · 열 폭 · 숨긴 열 · 머리 행 · 쪽 나눔 둘 · 그림 · 식)로 셋을 함께 봄. """ import io import re import shutil import pytest from openpyxl import load_workbook from common_util import common_util_spreadsheet as spreadsheet from common_util.common_util_print_pdf import PrintError from common_util.common_util_svg_png import svgs_to_pngs from common_util.common_util_workbook_xlsx import workbook_to_xlsx pytestmark = pytest.mark.skipif(shutil.which("node") is None, reason="node 가 없음") SVG = ( '' '' ) BREAKS = [6, 12] def _book() -> dict: cells = {"A1": {"값": "제목", "서식": 1}, "A2": {"값": "측점", "서식": 2}, "B2": {"값": "Fs"}} for r in range(3, 31): cells[f"A{r}"] = {"값": f"No.{r}"} cells[f"B{r}"] = {"값": r / 10, "서식": 3} cells["C3"] = {"식": "SUM(B3:B30)", "서식": 3} cells["D3"] = {"값": "숨김"} return { "종류": "통합문서", "판": 1, "열": "stab_report", "서식": [ {}, {"크기": 14, "굵게": True}, {"채움": "#EEEEEE", "테두리": {"아래": {"선": "medium"}}}, {"형식": "0.00"}, ], "시트": [ { "id": "s1", "이름": "측점표", "칸": cells, "병합": ["A1:C1", "E5:E8"], "열": {"A": {"폭": 12}, "B": {"폭": 6}, "D": {"숨김": True}}, "행": {"1": {"높이": 24}}, "틀고정": {"행": 2}, "인쇄": { "방향": "landscape", "맞춤": {"폭": 1, "높이": 0}, "머리행": [2, 2], "쪽나눔": BREAKS, }, "그림": [{"열쇠": "fig/a.png", "닻": "F3:H10", "이름": "단면"}], }, {"id": "s2", "이름": "숨김", "칸": {"A1": {"값": 1}}, "숨김": True}, ], "활성": "s1", } @pytest.fixture(scope="module") def png() -> bytes: try: return svgs_to_pngs([SVG])[0] except PrintError as error: pytest.skip(f"브라우저 없음 — {error}") def test_svg_png_크기(png): from PIL import Image assert Image.open(io.BytesIO(png)).size == (240, 120) # scale 2 def test_인쇄_html(png): html = spreadsheet.print_htmls([{"book": _book(), "figures": {"fig/a.png": png}}])[0] sheets = re.findall(r'
')[1:] assert len(chunks) == len(BREAKS) + 1 for chunk in chunks: # 덩이마다 머리 행 한 줄 thead = re.search(r"(.*?)", chunk).group(1) assert thead.count("', chunks[0]) assert widths[:3] == ["89", "47", "64"] and len(widths) == 7 * 2 # 앞 표(제목) + 본 표 # 병합 A1:C1 · E5:E8 = 쪽 나눔(6 아래)에서 잘림 — 첫 덩이 5~6 · 둘째 덩이 7~8 assert 'colspan="3"' in chunks[0] and 'rowspan="2"' in chunks[0] and 'rowspan="2"' in chunks[1] assert "rowspan" not in chunks[2] assert html.count("46.20<" in html # 식 값 = 화면 엔진 · 형식 0.00(SUM 0.3..3.0) def test_xlsx_되읽기(png): data = workbook_to_xlsx(_book(), {"fig/a.png": png}) wb = load_workbook(io.BytesIO(data)) assert wb.sheetnames == ["측점표", "숨김"] ws = wb["측점표"] assert sorted(str(m) for m in ws.merged_cells.ranges) == ["A1:C1", "E5:E8"] assert [b.id for b in ws.row_breaks.brk] == BREAKS assert len(ws._images) == 1 assert ws.print_title_rows == "$2:$2" assert ws["C3"].value == "=SUM(B3:B30)" assert ws["B3"].number_format == "0.00" and ws["A1"].font.b assert ws.column_dimensions["A"].width == 12 and ws.column_dimensions["D"].hidden assert ws.row_dimensions[1].height == 24 and ws.freeze_panes == "A3" assert ws.page_setup.orientation == "landscape" and ws.page_setup.fitToWidth == 1 assert wb["숨김"].sheet_state == "hidden" def test_pdf_쪽수(png): book = _book() try: pdf = spreadsheet.workbook_pdf(book, {"fig/a.png": png}) except PrintError as error: pytest.skip(f"브라우저 없음 — {error}") from pypdf import PdfReader pages = PdfReader(io.BytesIO(pdf)).pages assert len(pages) == len(BREAKS) + 1 assert all(float(p.mediabox.width) > float(p.mediabox.height) for p in pages) # 가로 assert all("측점" in p.extract_text() for p in pages) # 머리 행 쪽마다