From 115b0253c229d5a7aac38fc1412449491057f392 Mon Sep 17 00:00:00 2001 From: "DESKTOP-6ARNG1Q\\dlsgk" Date: Tue, 11 Mar 2025 17:33:44 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B0=9C=EC=A0=84=EC=8B=9C=EB=AE=AC=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=97=91=EC=85=80/pdf=20=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC(=EA=B0=80?= =?UTF-8?q?=EB=A1=9C=20=EC=B2=98=EB=A6=AC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pwrGnrSimulation/PwrGnrSimController.java | 19 +- .../pwrGnrSimulation/PwrGnrSimService.java | 116 +++- .../com/interplug/qcast/util/PdfUtil.java | 27 +- ...l_download_simulation_detail_template.xlsx | Bin 0 -> 19574 bytes ...f_download_simulation_detail_template.html | 494 ++++++++++++++++++ 5 files changed, 646 insertions(+), 10 deletions(-) create mode 100644 src/main/resources/template/excel/excel_download_simulation_detail_template.xlsx create mode 100644 src/main/resources/template/pdf/pdf_download_simulation_detail_template.html diff --git a/src/main/java/com/interplug/qcast/biz/pwrGnrSimulation/PwrGnrSimController.java b/src/main/java/com/interplug/qcast/biz/pwrGnrSimulation/PwrGnrSimController.java index 8015e0a5..4b32092c 100644 --- a/src/main/java/com/interplug/qcast/biz/pwrGnrSimulation/PwrGnrSimController.java +++ b/src/main/java/com/interplug/qcast/biz/pwrGnrSimulation/PwrGnrSimController.java @@ -1,17 +1,17 @@ package com.interplug.qcast.biz.pwrGnrSimulation; +import com.interplug.qcast.biz.estimate.dto.EstimateRequest; import com.interplug.qcast.biz.pwrGnrSimulation.dto.PwrGnrSimGuideResponse; import com.interplug.qcast.biz.pwrGnrSimulation.dto.PwrGnrSimRequest; import com.interplug.qcast.biz.pwrGnrSimulation.dto.PwrGnrSimResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @Slf4j @RestController @@ -36,4 +36,15 @@ public class PwrGnrSimController { public PwrGnrSimGuideResponse selectPwrGnrSimulationGuideInfo() throws Exception { return pwrGnrSimService.selectPwrGnrSimulationGuideInfo(); } + + @Operation(description = "견적서를 엑셀로 다운로드한다.") + @PostMapping("/excel-download") + @ResponseStatus(HttpStatus.OK) + public void excelDownload( + HttpServletRequest request, + HttpServletResponse response, + @RequestBody EstimateRequest estimateRequest) + throws Exception { + pwrGnrSimService.excelDownload(request, response, estimateRequest); + } } diff --git a/src/main/java/com/interplug/qcast/biz/pwrGnrSimulation/PwrGnrSimService.java b/src/main/java/com/interplug/qcast/biz/pwrGnrSimulation/PwrGnrSimService.java index 48e3e567..23f89998 100644 --- a/src/main/java/com/interplug/qcast/biz/pwrGnrSimulation/PwrGnrSimService.java +++ b/src/main/java/com/interplug/qcast/biz/pwrGnrSimulation/PwrGnrSimService.java @@ -2,23 +2,28 @@ package com.interplug.qcast.biz.pwrGnrSimulation; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.interplug.qcast.biz.estimate.dto.*; import com.interplug.qcast.biz.pwrGnrSimulation.dto.*; import com.interplug.qcast.config.Exception.ErrorCode; import com.interplug.qcast.config.Exception.QcastException; +import com.interplug.qcast.config.message.Messages; +import com.interplug.qcast.util.ExcelUtil; import com.interplug.qcast.util.InterfaceQsp; +import com.interplug.qcast.util.PdfUtil; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.*; import java.nio.charset.StandardCharsets; import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; +import java.text.SimpleDateFormat; +import java.util.*; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; @@ -29,6 +34,8 @@ import org.springframework.stereotype.Service; public class PwrGnrSimService { private final InterfaceQsp interfaceQsp; + @Autowired Messages message; + @Value("${qsp.url}") private String qspUrl; @@ -1484,4 +1491,105 @@ public class PwrGnrSimService { return (int) Math.ceil(value / place) * place; } + + public void excelDownload( + HttpServletRequest request, HttpServletResponse response, EstimateRequest estimateRequest) + throws Exception { + + // Validation + if (StringUtils.isEmpty(estimateRequest.getObjectNo())) { + throw new QcastException( + ErrorCode.INVALID_INPUT_VALUE, + message.getMessage("common.message.required.data", "Object No")); + } + if (StringUtils.isEmpty(estimateRequest.getPlanNo())) { + throw new QcastException( + ErrorCode.INVALID_INPUT_VALUE, + message.getMessage("common.message.required.data", "Plan No")); + } + + try { + + EstimateResponse estimateResponse = new EstimateResponse(); + estimateResponse.setObjectNo(estimateRequest.getObjectNo()); + estimateResponse.setPlanNo(estimateRequest.getPlanNo()); + + // file Name 명이 없는경우 + if (estimateRequest.getFileName() == null || "".equals(estimateRequest.getFileName())) { + estimateRequest.setFileName( + estimateResponse.getObjectNo() + + "_" + + new SimpleDateFormat("yyyyMMdd").format(new Date())); + } + + // 발전시뮬레이션 계산 + PwrGnrSimRequest pwrGnrSimRequest = new PwrGnrSimRequest(); + pwrGnrSimRequest.setObjectNo(estimateResponse.getObjectNo()); + pwrGnrSimRequest.setPlanNo(estimateResponse.getPlanNo()); + + PwrGnrSimResponse pwrGnrSimResponse = this.selectPwrGnrSimulation(pwrGnrSimRequest); + pwrGnrSimResponse.setPwrGnrSimType(estimateRequest.getPwrGnrSimType()); + + // 발전시뮬레이션 타입에 따른 list 셋팅 + if ("A".equals(estimateRequest.getPwrGnrSimType())) { + pwrGnrSimResponse.setFrcPwrGnrList(pwrGnrSimResponse.getHatsudenryouAll()); + } else if ("B".equals(estimateRequest.getPwrGnrSimType())) { + pwrGnrSimResponse.setFrcPwrGnrList(pwrGnrSimResponse.getHatsudenryouAllSnow()); + } else if ("C".equals(estimateRequest.getPwrGnrSimType())) { + pwrGnrSimResponse.setFrcPwrGnrList(pwrGnrSimResponse.getHatsudenryouPeakcutAll()); + } else if ("D".equals(estimateRequest.getPwrGnrSimType())) { + pwrGnrSimResponse.setFrcPwrGnrList(pwrGnrSimResponse.getHatsudenryouPeakcutAllSnow()); + } + + pwrGnrSimResponse.setIntFrcPwrGnrList( + Arrays.stream(pwrGnrSimResponse.getFrcPwrGnrList()) + .map(s -> s.replace(",", "")) // , 제거 + .mapToInt(Integer::parseInt) // 문자열을 int로 변환 + .toArray()); + + if (pwrGnrSimResponse != null) { + try { + // 발전시뮬레이션 안내사항 조회 + PwrGnrSimGuideResponse pwrGnrSimGuideInfo = this.selectPwrGnrSimulationGuideInfo(); + if (pwrGnrSimGuideInfo != null) { + pwrGnrSimResponse.setGuideInfo(pwrGnrSimGuideInfo.getData()); + } + } catch (Exception e) { + } + } + + estimateResponse.setPwrGnrSim(pwrGnrSimResponse); + + if ("PDF".equals(estimateRequest.getSchDownload())) { // PDF 다운로드 + String[] arrSection = {"div.section3"}; + String templateFilePath = "pdf_download_simulation_detail_template.html"; + + // 템플릿 html 조회 + Document doc = PdfUtil.getPdfDoc(request, templateFilePath); + + // 발전시뮬레이션 pdf Html 생성 + doc = this.pwrGnrSimPdfHtml(doc, pwrGnrSimResponse); + + // pdf 다운로드 + PdfUtil.pdfDownload(request, response, doc, estimateRequest.getFileName(), null, true); + + } else { + + String excelTemplateName = "excel_download_simulation_detail_template.xlsx"; + + ExcelUtil excelUtil = new ExcelUtil(); + excelUtil.download( + request, + response, + excelUtil.convertVoToMap(estimateResponse), + null, + estimateRequest.getFileName(), + excelTemplateName); + } + + } catch (Exception e) { + e.printStackTrace(); + throw new QcastException(ErrorCode.INTERNAL_SERVER_ERROR); + } + } } diff --git a/src/main/java/com/interplug/qcast/util/PdfUtil.java b/src/main/java/com/interplug/qcast/util/PdfUtil.java index 22ae5735..da65672a 100644 --- a/src/main/java/com/interplug/qcast/util/PdfUtil.java +++ b/src/main/java/com/interplug/qcast/util/PdfUtil.java @@ -3,6 +3,7 @@ package com.interplug.qcast.util; import com.itextpdf.html2pdf.ConverterProperties; import com.itextpdf.html2pdf.HtmlConverter; import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider; +import com.itextpdf.kernel.geom.PageSize; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfWriter; @@ -60,6 +61,7 @@ public class PdfUtil { * @param doc * @param pdfFileName 파일명 * @param arrSection 노출 Section + * @param isLandscape 가로/세로 설정 * @throws IOException */ public static void pdfDownload( @@ -67,9 +69,13 @@ public class PdfUtil { HttpServletResponse response, Document doc, String pdfFileName, - String[] arrSection) + String[] arrSection, + boolean isLandscape) throws IOException { + // 가로 세로 설정 + PageSize pageSize = isLandscape ? PageSize.A4.rotate() : PageSize.A4; + // 응답에 PDF 설정 response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "attachment; filename=\"" + pdfFileName + "\".pdf"); @@ -79,6 +85,8 @@ public class PdfUtil { PdfWriter writer = new PdfWriter(os); PdfDocument pdfDoc = new PdfDocument(writer)) { + pdfDoc.setDefaultPageSize(pageSize); + // 폰트 설정 ConverterProperties properties = new ConverterProperties(); String fontPath = "template/pdf/BIZUDPGothic-Regular.ttf"; @@ -88,7 +96,9 @@ public class PdfUtil { if (arrSection == null || arrSection.length == 0) { // HTML 전체를 pdfDoc에 직접 변환 HtmlConverter.convertToPdf( - new ByteArrayInputStream(doc.html().getBytes(StandardCharsets.UTF_8)), os, properties); + new ByteArrayInputStream(doc.html().getBytes(StandardCharsets.UTF_8)), + pdfDoc, + properties); os.flush(); } else { // arrSection이 있는 경우 각 섹션을 개별적으로 변환 후 병합 @@ -108,6 +118,8 @@ public class PdfUtil { PdfWriter tempWriter = new PdfWriter(tempOutputStream); PdfDocument tempPdfDoc = new PdfDocument(tempWriter)) { + tempPdfDoc.setDefaultPageSize(pageSize); + HtmlConverter.convertToPdf( new ByteArrayInputStream(sectionHtml.getBytes(StandardCharsets.UTF_8)), tempPdfDoc, @@ -161,4 +173,15 @@ public class PdfUtil { } return fontProvider; } + + public static void pdfDownload( + HttpServletRequest request, + HttpServletResponse response, + Document doc, + String pdfFileName, + String[] arrSection) + throws IOException { + + pdfDownload(request, response, doc, pdfFileName, arrSection, false); // 기본값은 세로 + } } diff --git a/src/main/resources/template/excel/excel_download_simulation_detail_template.xlsx b/src/main/resources/template/excel/excel_download_simulation_detail_template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..bd9240708a031b0f36e7540e2e390178e9e2e647 GIT binary patch literal 19574 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 G_WuFi^}v1r literal 0 HcmV?d00001 diff --git a/src/main/resources/template/pdf/pdf_download_simulation_detail_template.html b/src/main/resources/template/pdf/pdf_download_simulation_detail_template.html new file mode 100644 index 00000000..ba5e6fcd --- /dev/null +++ b/src/main/resources/template/pdf/pdf_download_simulation_detail_template.html @@ -0,0 +1,494 @@ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
物件番号作成日都道府県日射量観測地点
システム容量年間予測発電量積雪条件風速条件
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
1月2月3月4月5月6月7月8月9月10月11月12月
+
+ +
+ ● 予測発電量[kWh] +
+ + + + + + + + + + + + + + + + + + + + + + +
1月2月3月4月5月6月7月8月9月10月11月12月合計
+
+ +
+ + + + + + + + + + + + +
屋根面傾斜角度方位角(度)太陽電池モジュール枚数(枚)
+ + + + + + + + + +
パワーコンディショナー
+
+
+
+ ● Hanwha Japan 年間発電量シミュレーション案内事項 +
+
+

+    
+
+ + \ No newline at end of file