From 3885a218bcd555decefe5ce4476e0adc2ee0dfe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=84=B1=EC=98=81?= Date: Fri, 5 Dec 2025 14:19:58 +0900 Subject: [PATCH] =?UTF-8?q?=EB=AF=B8=ED=95=84=20=EC=9E=91=EC=97=85=20?= =?UTF-8?q?=EC=A7=84=ED=96=89=20=EC=A4=91...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/CarFfnlgTrgtIncmpServiceImpl.java | 105 ++++++++++++++++-- .../registrationOm/list.jsp | 2 +- 2 files changed, 95 insertions(+), 12 deletions(-) diff --git a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/CarFfnlgTrgtIncmpServiceImpl.java b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/CarFfnlgTrgtIncmpServiceImpl.java index b7c5834..97cedee 100644 --- a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/CarFfnlgTrgtIncmpServiceImpl.java +++ b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/CarFfnlgTrgtIncmpServiceImpl.java @@ -20,6 +20,7 @@ import org.springframework.web.multipart.MultipartFile; import java.io.BufferedReader; import java.io.InputStreamReader; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.ArrayList; @@ -282,30 +283,68 @@ public class CarFfnlgTrgtIncmpServiceImpl extends EgovAbstractServiceImpl implem StringBuilder sb = new StringBuilder(); - // 헤더 구성 - sb.append("검사미필 과태료부과대상 리스트\r\n"); - sb.append("------------------------------------\r\n"); + // 1번째 줄: 제목 (가운데 정렬) + String title = "자동차 검사 경과 안내서 대상차량 대장"; + sb.append(padLeftBytes(title, 159, encoding)).append("\r\n"); + + // 2번째 줄: 구분선 (가운데 정렬) + String titleLine = "---------------------------------------"; + sb.append(padLeftBytes(titleLine, 159, encoding)).append("\r\n"); + + // 3번째 줄: 프로그램 ID + String prgrmId = vo.getPrgrmId() != null ? vo.getPrgrmId() : "VGD01B"; + sb.append(" 프로그램 ID : ").append(prgrmId); + sb.append(padRightBytes("", 159 - (" 프로그램 ID : " + prgrmId).getBytes(encoding).length, encoding)); sb.append("\r\n"); - // 데이터 라인 생성 + // 4번째 줄: 처리일자 및 출력일시 + String today = LocalDate.now().format(DATE_FORMATTER); + String todayFormatted = String.format("%s년%s월%s일", today.substring(0, 4), today.substring(4, 6), today.substring(6, 8)); + String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy년MM월dd일HH시mm분")); + + String line4 = String.format(" 처 리 일 자 : %s~%s", todayFormatted, todayFormatted); + String line4Right = String.format("출 력 일 시 : %s", now); + + int line4LeftBytes = line4.getBytes(encoding).length; + int line4RightBytes = line4Right.getBytes(encoding).length; + int paddingBytes = 159 - line4LeftBytes - line4RightBytes; + + sb.append(line4); + sb.append(padRightBytes("", paddingBytes, encoding)); + sb.append(line4Right).append("\r\n"); + + // 5번째 줄: 긴 구분선 + sb.append(repeatChar('-', 159, encoding)).append("\r\n"); + + // 6번째 줄: 컬럼 헤더 + sb.append("번호 자동차번호 소유자명 주민등록번호 차 명 사용 본거지 주소 검사유효기간 \r\n"); + + // 7번째 줄: 긴 구분선 + sb.append(repeatChar('-', 159, encoding)).append("\r\n"); + + // 8번째 줄부터: 데이터 (2줄 1세트) + int rowNum = 1; for (CarFfnlgTrgtIncmpVO row : list) { + // 첫 번째 줄 String firstLine = - padRightBytes(nvl(row.getNo()), 6, encoding) + - padRightBytes(nvl(row.getVhclno()), 14, encoding) + - padRightBytes(nvl(row.getOwnrNm()), 16, encoding) + + padRightBytes(String.valueOf(rowNum), 6, encoding) + + padRightBytes(nvl(row.getVhclno()), 16, encoding) + + padRightBytes(nvl(row.getOwnrNm()), 32, encoding) + padRightBytes(nvl(row.getCarNm()), 22, encoding) + - padRightBytes(nvl(row.getUseStrhldAddr()), 62, encoding) + - padRightBytes(nvl(row.getInspVldPrd()), 23, encoding); + padRightBytes(nvl(row.getUseStrhldAddr()), 61, encoding) + + padRightBytes(nvl(row.getInspVldPrd()), 21, encoding); sb.append(firstLine).append("\r\n"); + // 두 번째 줄 (주민번호와 주소 계속) String secondLine = padRightBytes("", 38, encoding) + padRightBytes(nvl(row.getRrno()), 16, encoding) + - padRightBytes(nvl(row.getUseStrhldAddr()), 62, encoding); + padRightBytes(nvl(row.getUseStrhldAddr()), -1, encoding); // 나머지 전체 sb.append(secondLine).append("\r\n"); - sb.append("\r\n"); + + rowNum++; } return sb.toString().getBytes(encoding); @@ -314,6 +353,50 @@ public class CarFfnlgTrgtIncmpServiceImpl extends EgovAbstractServiceImpl implem } } + /** + * 왼쪽 패딩 (가운데 정렬 효과) + */ + private static String padLeftBytes(String s, int totalByteLen, String encoding) throws Exception { + if (totalByteLen <= 0) return nvl(s); + String v = nvl(s); + byte[] b = v.getBytes(encoding); + + if (b.length >= totalByteLen) { + return truncateToBytes(v, totalByteLen, encoding); + } + + int paddingBytes = (totalByteLen - b.length) / 2; + StringBuilder sb = new StringBuilder(); + + // 왼쪽 패딩 + for (int i = 0; i < paddingBytes; i++) { + sb.append(' '); + } + sb.append(v); + + // 오른쪽 패딩 (남은 공간 채우기) + while (sb.toString().getBytes(encoding).length < totalByteLen) { + sb.append(' '); + } + + return sb.toString(); + } + + /** + * 문자 반복 + */ + private static String repeatChar(char c, int totalByteLen, String encoding) throws Exception { + StringBuilder sb = new StringBuilder(); + while (sb.toString().getBytes(encoding).length < totalByteLen) { + sb.append(c); + } + // 바이트 길이 정확히 맞추기 + while (sb.toString().getBytes(encoding).length > totalByteLen) { + sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } + /** * 선택된 목록에 대해 API 호출 및 기본정보/등록원부 비교 * 미필의 경우 부과일자 = 검사유효기간 종료일 + OM_DAY_CD의 D 코드값(145일) diff --git a/src/main/webapp/WEB-INF/views/carInspectionPenalty/registrationOm/list.jsp b/src/main/webapp/WEB-INF/views/carInspectionPenalty/registrationOm/list.jsp index 1b1dfa5..c15874b 100644 --- a/src/main/webapp/WEB-INF/views/carInspectionPenalty/registrationOm/list.jsp +++ b/src/main/webapp/WEB-INF/views/carInspectionPenalty/registrationOm/list.jsp @@ -356,7 +356,7 @@ { header: '자동차명', name: 'carNm', align: 'left', width: 150 }, { header: '사용본거지주소', name: 'useStrhldAddr', align: 'left', width: 250 }, { header: '검사유효기간', name: 'inspVldPrd', align: 'center', width: 200 }, - { header: '부과일자', name: 'levyCrtrYmd', align: 'center', width: 100, + { header: 'API 호출 부과일자', name: 'levyCrtrYmd', align: 'center', width: 100, formatter: function(e) { return e.value ? moment(e.value, 'YYYYMMDD').format('YYYY-MM-DD') : ''; }