feat(malaysia): 랙 엑셀에 아이템별 합계 표 추가
상세 표 아래(한 줄 띄움)에 아이템 코드별 수량 합계 표를 추가. 컬럼: 아이템 코드/이름/합계 수량, 코드순 정렬. 자동필터는 상세 표 범위에만 적용(합계 표 제외). 열너비 자동은 그대로. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -495,26 +495,47 @@ async def rack_export(request: Request) -> StreamingResponse:
|
|||||||
from openpyxl.styles import Alignment, Font, PatternFill # noqa: WPS433
|
from openpyxl.styles import Alignment, Font, PatternFill # noqa: WPS433
|
||||||
from openpyxl.utils import get_column_letter # noqa: WPS433
|
from openpyxl.utils import get_column_letter # noqa: WPS433
|
||||||
|
|
||||||
|
# 아이템별 합계(코드 기준 수량 합산). 코드→이름 보존, 코드순 정렬.
|
||||||
|
summary: dict[str, int] = {}
|
||||||
|
for code, _name, qty, _cell in rows:
|
||||||
|
summary[code] = summary.get(code, 0) + qty
|
||||||
|
summary_rows = sorted(
|
||||||
|
((code, names.get(code, code), total) for code, total in summary.items()),
|
||||||
|
key=lambda r: r[0],
|
||||||
|
)
|
||||||
|
|
||||||
|
fill = PatternFill(start_color="FF4472C4", end_color="FF4472C4", fill_type="solid")
|
||||||
|
font = Font(color="FFFFFFFF", bold=True)
|
||||||
|
center = Alignment(horizontal="center", vertical="center")
|
||||||
|
|
||||||
|
def _style_header(row_idx: int, ncols: int) -> None:
|
||||||
|
for col in range(1, ncols + 1):
|
||||||
|
cell = ws.cell(row=row_idx, column=col)
|
||||||
|
cell.fill = fill
|
||||||
|
cell.font = font
|
||||||
|
cell.alignment = center
|
||||||
|
|
||||||
wb = Workbook()
|
wb = Workbook()
|
||||||
ws = wb.active
|
ws = wb.active
|
||||||
ws.title = "rack"
|
ws.title = "rack"
|
||||||
|
|
||||||
|
# ── 상세 표 ──
|
||||||
header = ["아이템 코드", "이름", "수량", "랙번호"]
|
header = ["아이템 코드", "이름", "수량", "랙번호"]
|
||||||
ws.append(header)
|
ws.append(header)
|
||||||
for code, name, qty, cell in rows:
|
for code, name, qty, cell in rows:
|
||||||
ws.append([code, name, qty, cell])
|
ws.append([code, name, qty, cell])
|
||||||
|
_style_header(1, len(header))
|
||||||
|
detail_last = ws.max_row # 자동필터 범위(상세표만)
|
||||||
|
ws.auto_filter.ref = f"A1:{get_column_letter(len(header))}{detail_last}"
|
||||||
|
|
||||||
# 제목행: 파랑 배경 + 흰색 굵은글씨 + 가운데 정렬
|
# ── 아이템별 합계 표 (상세표 아래, 한 줄 띄움) ──
|
||||||
fill = PatternFill(start_color="FF4472C4", end_color="FF4472C4", fill_type="solid")
|
ws.append([])
|
||||||
font = Font(color="FFFFFFFF", bold=True)
|
sum_header_row = ws.max_row + 1
|
||||||
center = Alignment(horizontal="center", vertical="center")
|
sum_header = ["아이템 코드", "이름", "합계 수량"]
|
||||||
for col in range(1, len(header) + 1):
|
ws.append(sum_header)
|
||||||
cell = ws.cell(row=1, column=col)
|
for code, name, total in summary_rows:
|
||||||
cell.fill = fill
|
ws.append([code, name, total])
|
||||||
cell.font = font
|
_style_header(sum_header_row, len(sum_header))
|
||||||
cell.alignment = center
|
|
||||||
|
|
||||||
# 표 전체 자동필터
|
|
||||||
ws.auto_filter.ref = ws.dimensions
|
|
||||||
|
|
||||||
# 열너비 자동(내용 길이 기준, 한글 폭 보정). 최소 8 ~ 최대 50.
|
# 열너비 자동(내용 길이 기준, 한글 폭 보정). 최소 8 ~ 최대 50.
|
||||||
for col in range(1, len(header) + 1):
|
for col in range(1, len(header) + 1):
|
||||||
|
|||||||
Reference in New Issue
Block a user