오. PDF 출력할 때 화면에 창 띄우는 게
알고보니 GET 요청으로 하고 있었다 ^-^
(사실 주소 보고 알았지만 괜찮은 줄 알고 넘어감)
이번에 POST 요청으로 변경하라는 피드백을 받고.
난 모르니까 GPT 에게 도움을 청함.ㅠ
1. 변경 후 Post요청 코드
vue
// PDF 문서 출력.
function doOpenPDF(orderSeq) {
const form = document.createElement("form");
form.method = "post";
form.action = '../../report/reportPDF.do';
form.target = '_blank';
const params = {
orderSeq: orderSeq,
startDate: startDate.value || '',
endDate: endDate.value || ''
};
for(const key in params) {
const input = document.createElement("input");
input.type = "hidden";
input.name = key;
input.value = params[key];
form.appendChild(input);
}
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
controller 는 PostMapping 으로 변경.
잘 뜬다~

2. 기존 Get요청 코드
기존 .vue
// PDF 문서 출력.
function doOpenPDF(orderSeq) {
const params = {
orderSeq: orderSeq,
startDate: startDate.value || '',
endDate: endDate.value || ''
};
const queryString = new URLSearchParams(params).toString();
const url = `../../report/reportPDF.do?${queryString}`;
window.open(url, '_blank');
}
기존 controller
package dev.kloz.weborder.common.controller;
import java.sql.Connection;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import dev.kloz.common.utils.ReportUtils;
import dev.kloz.weborder.common.config.ApplicationContextProvider;
import dev.kloz.weborder.common.session.SessionKeys;
import dev.kloz.weborder.common.session.SessionManager;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor
@Controller
@RequestMapping("/report")
public class ReportController {
private String signImg = ""; // 대표자 서명 이미지 넣어야 함.
/**
* PDF 문서 출력.
* @param request 클라이언트 요청 객체. 시작일, 종료일.
* @param response 서버 응답 객체. 거래명세서.
* @return PDF 파일이 byte 배열 형태로 포함된 ResponseEntity
* @throws Exception PDF 생성 과정에서 예외 발생 시
*/
@PostMapping("/reportPDF.do")
public ResponseEntity<byte[]> reportPDF(HttpServletRequest request, HttpServletResponse response) throws Exception {
Map<String, Object> param = new HashMap<String, Object>();
// String loginUserId = (String) session.getAttribute("s_userId");
Integer userSeq = Integer.parseInt(String.valueOf(SessionManager.get(SessionKeys.session_user_seq)));
// String baseUrl = request.getScheme() + "://" +
// request.getServerName() + ":" +
// request.getServerPort() +
// request.getContextPath();
//
// String signImgUrl = baseUrl + signImg;
String startDate = request.getParameter("startDate");
String endDate = request.getParameter("endDate");
String orderSeq = request.getParameter("orderSeq");
System.out.println(orderSeq);
// GMT 부분 제거
if (startDate != null && startDate.contains(" GMT")) {
startDate = startDate.split(" GMT")[0];
}
if (endDate != null && endDate.contains(" GMT")) {
endDate = endDate.split(" GMT")[0];
}
DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
try {
if (startDate != null && !"undefined".equals(startDate) && !startDate.trim().isEmpty()) {
// ZonedDateTime.parse로 날짜를 파싱 (ISO 8601 형식 지원)
ZonedDateTime parsedStartDate = ZonedDateTime.parse(startDate, formatter);
param.put("start_date", java.sql.Date.valueOf(parsedStartDate.toLocalDate())); // java.sql.Date로 변환
} else {
param.put("start_date", null);
}
if (endDate != null && !"undefined".equals(endDate) && !endDate.trim().isEmpty()) {
// ZonedDateTime.parse로 날짜를 파싱 (ISO 8601 형식 지원)
ZonedDateTime parsedEndDate = ZonedDateTime.parse(endDate, formatter);
param.put("end_date", java.sql.Date.valueOf(parsedEndDate.toLocalDate())); // java.sql.Date로 변환
} else {
param.put("end_date", null);
}
} catch (Exception e) {
// 예외 발생 시 null 처리 또는 예외 메시지 반환
log.error("날짜 파싱 중 오류 발생 : startDate={}, endDate={}", startDate, endDate, e);
}
// param.put("sign_img", signImgUrl);
param.put("order_seq", orderSeq);
param.put("user_seq", userSeq);
java.time.LocalDate today = java.time.LocalDate.now();
// 원하는 날짜 포맷 지정: yyyy-MM-dd
java.time.format.DateTimeFormatter df = java.time.format.DateTimeFormatter.ofPattern("yyyy년 MM월 dd일");
String formattedToday = today.format(df);
// JRXML에서 사용할 파라미터 이름: REPORT_CURRENT_DATE
param.put("currDate", formattedToday);
String mstReportUri = String.valueOf(
ResourceUtils.getFile("classpath:static/report/order_list.jrxml"));
log.debug("mstReportUri ====>>>> {}", mstReportUri);
DataSource ds = (DataSource)ApplicationContextProvider.getApplicationContext().getBean("dataSource");
try (Connection con = ds.getConnection()) {
JasperReport report = JasperCompileManager.compileReport(mstReportUri);
JasperPrint print = JasperFillManager.fillReport(report, param, con);
return ReportUtils.exportPDF(print, "order_list_");
} catch (Exception e) {
log.error("거래명세서 PDF 생성 중 오류 발생", e);
throw e;
}
}
}
'웹 개발 > [KLOZ] 웹 프로젝트' 카테고리의 다른 글
| [WebOrder] IBSheet 포함 페이지에 IBSheet 참조할 때 loader.config 타이밍 문제 해결. (Qna.vue) (0) | 2025.12.22 |
|---|---|
| [WebOrder] Vuetify scrollable, 스크롤 시 버튼 고정 방법 (0) | 2025.11.26 |
| [WebOrder] vueper-slides : 트랜지션 transition 조건부 처리. (0) | 2025.11.20 |
| [WebOrder] Vue컴포넌트에서 세션 (session) 가져다 쓰기 / 백단에서 가져다쓰기 (0) | 2025.11.16 |
| [WebOrder] 다국어 처리 (VueDatePicker, IBSheet) (0) | 2025.10.21 |