# 견적서 / 발전시뮬레이션 / Excel·PDF 출력 인수인계서 > 작성일: 2026-05-06 > 대상: 후임 AI 엔지니어 또는 개발 관리자 > 작업 브랜치: `dev_ysCha` > **이 문서의 범위**: Excel/PDF 출력물 관련 작업만 다룹니다. > 다른 트랙은 `HANDOVER_INDEX.md` 참조. --- ## 0. 한 줄 요약 견적서·중량 시트·구조도·계통도 등 **출력물에서 보이는 거의 모든 이슈**가 이 트랙으로 들어옵니다. 정렬·파일명·이미지·전각문자·도면 비율·폰트 등이 반복적으로 나오는 영역이며, **Excel(jxls + POI)** 과 **PDF(iText html2pdf)** 두 출력 경로를 동시에 봐야 합니다. --- ## 1. 출력 시스템 개요 ### 1.1 두 가지 출력 경로 | 출력 종류 | 사용 라이브러리 | 템플릿 위치 | |----------|----------------|-------------| | **Excel** | Apache POI + jxls | `src/main/resources/template/excel/` | | **PDF** | iText html2pdf | (HTML 템플릿 → PDF 변환) | > **중요**: 같은 견적서라도 Excel과 PDF는 **별도 경로**입니다. 한쪽만 고치면 다른 쪽이 어긋납니다. "정렬을 왼쪽으로" 같은 표시 변경은 양쪽을 함께 손대야 합니다. ### 1.2 자주 나오는 출력 종류 - 견적서 (Quotation) - 발전시뮬레이션 결과 - 중량 계산 시트 - 배치도 / 계통도 / 구조도 --- ## 2. 정렬 (Alignment) 변경 작업 ### 2.1 한 일 | 티켓 | 내용 | 커밋 | |------|------|------| | `[1508]` | 견적서 [품명][형번] 가운데 → **왼쪽 정렬** (Excel + PDF 둘 다) | `11d2acb2` | | `[2133]` | 중량 계산 시트 [품명][모델명] **왼쪽 정렬** (Excel) | `1c22880c` | ### 2.2 주의 - 정렬은 사용자 가독성에 직접 영향. 변경 전 항상 **현 상태 스크린샷**을 떠 두세요. - Excel만 바꾸고 PDF를 안 바꿔서 보고가 들어오는 경우가 잦습니다. --- ## 3. 파일명 / 다운로드명 포맷 ### 3.1 한 일 | 티켓 | 내용 | 커밋 | |------|------|------| | `[2133]` | 다운로드 파일명 포맷에 `planNo` 추가 → `objectNo_planNo_날짜` (견적서/발전시뮬레이션 통일) | `fc6655f9` | ### 3.2 정책 - 파일명 포맷은 견적서·발전시뮬레이션이 **동일 규칙**으로 가야 함 (사용자 요청). - 새 다운로드를 추가할 때도 같은 패턴을 따르세요. --- ## 4. 전각문자 / unknown 처리 ### 4.1 한 일 | 티켓 | 내용 | 커밋 | |------|------|------| | `[1827]` | 엑셀/PDF 다운로드 시 파일명이 `unknown` 으로 나오는 문제 — **전각문자 처리** | `dd2b3e4d` | ### 4.2 배경 - 일본어 전각문자(예: `ABC`)가 파일명/HTTP 헤더에 들어가면 인코딩 문제로 `unknown` 으로 떨어집니다. - 파일명 인코딩 단계에서 전각 → 반각 변환 또는 URL 인코딩 강화로 처리. ### 4.3 일반화 가능한 교훈 - **이 시스템은 일본어 환경**입니다. 새 출력에서 파일명을 만들 때 항상 전각문자 가능성을 의심하세요. --- ## 5. 등록상표 ® 처리 (카카오 시리즈) ### 5.1 한 일 PDF 출력 시 등록상표 기호 `®` 가 `?` 로 깨지는 문제. 단계별로 변경: | 단계 | 내용 | 커밋 | |------|------|------| | 1차 | `®` → `Ⓡ` 로 치환 | `47f18b50` | | 2차 | `®` → `(R)` + PDF 폰트 변경 | `57d52c7c` | | 3차 | PDF 폰트 복구 | `33555619` | ### 5.2 교훈 - PDF 폰트는 **글리프 지원 범위**를 항상 확인. 안 되는 글리프는 텍스트 치환으로 우회하는 게 안전. - 폰트를 바꾸면 다른 글자(특히 한자/일본어)가 깨지는 부작용이 생기므로, **폰트 변경은 최후의 수단**. --- ## 6. 도면 비율 / 화질 개선 ### 6.1 한 일 | 티켓 | 내용 | 커밋 | |------|------|------| | `[1427]` | 출력한 견적서 도면의 가로/세로 비율이 화면과 다른 문제 (+ 로컬 실행 가능 조정) | `3048076d` | | `[1470]` | 배치도·계통도·구조도 화질 개선 (cell 이미지 추가) | `4468d3f9`, `1a4becd1`, `512cdd5c` 등 다수 | | `[1268][1295]` | PDF 출력 세로 → 가로 혼합 | `abf1f91a`, `3612c50d` | ### 6.2 주의 - 화질 개선 작업은 같은 티켓에 여러 커밋이 따라옵니다(이미지 교체 반복). 한 번에 안 되는 게 정상. - 도면 비율은 **DPI / 픽셀 단위 / mm 단위** 가 섞여 있어 한 곳만 고치면 다른 출력이 어긋납니다. --- ## 7. 견적서 주소 (가장 험난했던 시리즈) — `[1379]` ### 7.1 무슨 일이 있었나 견적서 주소 표시 조건을 바꿨다가 → 원복 → 다시 수정 → 또 원복 → 재수정 의 반복이 있었습니다. | 단계 | 커밋 | |------|------| | 견적서 주소 수정 | `a430ce64` | | 견적서 출력 쿼리 수정 | `c28eeee2` | | 1차 원복 | `1fcd2dac` | | 2차 원복 | `32e6237f` | | 3/9 이전 원복 | `35584228` | | 최초 원복 | `c735263d` | | 최초 원시 원복 | `150b64b0` | | 재수정 | `b5e3012d` | ### 7.2 경고 - **이 영역은 손대기 전에 반드시 사용자에게 현재 정책을 재확인**하세요. - 견적서 주소는 일본 거래처별로 표시 요건이 다를 수 있어 케이스가 많습니다. --- ## 8. 지붕/사 각도 출력 관련 | 티켓 | 내용 | 커밋 | |------|------|------| | `[1765]` | 출력한 견적서 지붕 면이 이중 표시 | `9dce727f`, `dc7eb154` | | `[1480]` | 사(斜)의 각도 설정을 "각도"로 했을 때 출력물 문제 | `709b1f1f`, `f407079f`, `3e64d8a2` | 지붕·각도 관련 출력은 프론트(qcast-front)의 SK(Straight Skeleton) 트랙과 맞물립니다. 프론트의 `SK_MOVEMENT_HANDOVER.md` 도 같이 보세요. --- ## 9. 핵심 파일 / 위치 | 위치 | 역할 | |------|------| | `src/main/resources/template/excel/` | Excel 템플릿(jxls) | | `src/main/resources/mappers/` | 출력에 쓰이는 SQL 매퍼 | | `com.interplug.qcast.biz.quotation.*` | 견적서 도메인 (Controller/Service/Mapper/DTO) | | `com.interplug.qcast.biz.simulation.*` | 발전시뮬레이션 도메인 | | (PDF 관련) Service/Util 클래스 | iText html2pdf 변환 로직 | > 파일 경로는 패키지 변경 가능성이 있으므로 항상 현재 트리에서 다시 확인하세요. --- ## 10. 인수 직후 권장 절차 1. 이 문서 통독. 2. `template/excel/` 폴더 안 템플릿 한두 개 열어 jxls 태그 사용법 확인. 3. 견적서 도메인 Controller → Service → Mapper → 템플릿 한 번 따라가 보기. 4. 로컬에서 견적서 Excel/PDF 한 번 출력해보고 결과 확인. --- ## 11. 미해결 / 추적 중 - `[1379]` 견적서 주소 정책은 **여전히 변동 가능성** 있음. 추가 요청 들어오면 신중히. - 화질 개선(`[1470]`) 은 일단락됐지만 같은 종류의 이미지 깨짐 보고가 또 들어올 수 있음. --- ## 12. 旧見積書書式(EXCEL2) 출력 시트 정책 — 2026-05-06 ### 12.1 무슨 일이 있었나 일본에서 다음 요청이 옴. > 旧見積書書式 선택 시에도 [図面/シミュレーションファイルを含む] 옵션이면 `割付図・系統図`/`架台図`/`発電シミュレーション` 시트를, [架台重量表付き] 옵션이면 `重量算出シート` 시트를 함께 출력해 달라. 결국 **신(통상) 견적서와 동일한 시트 출력 사양**으로 통일 요구. 기존 코드(`EstimateService.java` `excelDownload()` 내 `EXCEL2` 분기)는 旧見積書書式 선택 시 **schDrawingFlg/schWeightFlg 옵션과 무관하게** 부속 시트를 모두 강제 제거하고 `見積書.` 한 장만 남기고 있었음. ### 12.2 한 일 `EstimateService.java` 1915~1925 (수정 후) 영역을 다음 정책으로 단순화. - `schDrawingFlg`/`schWeightFlg`로 시트를 골라내는 1단계 분기는 그대로 유지 (= 신 양식과 동일하게 작동). - 양식 분기는 **견적서 시트만 교체** 책임으로 축소: - `EXCEL2` (旧書式) → `見積書` 제거 + `見積書.`을 첫 번째 시트로 이동 - 그 외 (신 양식) → `見積書.` 제거 - `特異事項` 시트는 두 양식 모두 항상 제거. 결과적으로 旧書式 출력 순서: ``` 見積書. → 発電シミュレーション → 割付図・系統図 → 架台図 → 重量算出シート → P1 → P2 ``` (옵션에 따라 일부 시트 빠짐) ### 12.3 견적서 시트 두 종류 차이 (혼동 주의) | 항목 | `見積書` (신/통상) | `見積書.` (구) | |---|---|---| | 템플릿 sheet 번호 | sheet1.xml | sheet7.xml | | 영역 | A1:AP46 (가로) | A1:V104 (세로 길쭉) | | 병합셀 | 61 | 343 | | 아이템 출력 | 인덱스 고정 (`list[0]~list[26]`) | JXLS each 반복 (`item.itemName`) | → "이름이 거의 같으니 같은 시트 아니냐"라는 인상과 달리 **레이아웃·바인딩 키가 완전히 다른 별개 양식**. 한쪽 손볼 때 다른 쪽도 자동 적용된다고 착각하지 말 것. ### 12.4 후속 확인 포인트 (다음 작업 시 체크) 1. **프론트(qcast-front)** 가 旧書式 선택 시 `schDrawingFlg`/`schWeightFlg` 값을 함께 전송하는지 확인. 안 보내면 백엔드만 고쳐도 효과 없음. 2. `EstimateRequest.schWeightFlg` 필드는 정의되어 있으나 분기에서는 `schDrawingFlg.indexOf("4")`만 보고 있음. 프론트가 별도 키로 보내는 경우 백엔드 분기 조건도 함께 손봐야 함. 3. 旧書式 템플릿(`excel_download_quotation_detail_template2.xlsx`) 시트 구성은 신 양식 템플릿(`excel_download_quotation_detail_template.xlsx`)과 동일. 旧書式 전용으로 부속 시트 디자인을 다르게 가져갈 일이 생기면 템플릿 자체를 분리해야 함. ### 12.5 활성 시트 `setSheetOrder("見積書.", 0)`로 옮겨도 POI는 active sheet 인덱스를 자동 보정하지 않을 수 있음. 열었을 때 다른 시트가 먼저 보이면 `workbook.setActiveSheet(0)` 한 줄을 추가. 끝.