This commit is contained in:
myname 2025-10-22 17:42:29 +09:00
commit 0d5e79402e
10 changed files with 215 additions and 145 deletions

View File

@ -25,8 +25,6 @@
<script type="text/javascript" src="${pageContext.request.contextPath}/kccadrPb/usr/script/popup.js"></script>
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/reset.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/common.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/estimate.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/font.css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/publish/css/button.css">
@ -389,7 +387,23 @@ async function makePDF() {
const cloned = element.cloneNode(true);
const container = document.createElement('div');
container.style.position = 'fixed';
// pdf style 적용이 안되서 추가
const styleEl = document.createElement('style');
styleEl.innerHTML = `
.estimate{padding:30px 3%;}
.estimate *{font-family: 'HYgsrB', sans-serif !important; color:#222 !important;}
.est_body{position:relative; padding:50px 0; text-align:left;}
.est_body h2{font-size:4.4rem; -webkit-text-stroke-width:0.05px; -webkit-text-stroke-color:#222; text-align:center;}
.est_body .cont1>div p{width:100%;margin:0 0 0 30px;text-align:left;line-height: 1.5;}
.est_body .cont5 div{display:block;}
.est_body .cont5 div span:first-child{font-size:1.8rem; font-weight:700; line-height: 1.5; color:#222; margin:0 0 10px 30px; display:block;text-align:left;}
.est_body .cont5.substance>div{margin:100px 0; text-align:center;}
.est_body .cont5.substance>div p{font-size:2rem; font-weight:700; color:#222; margin:0 50px; line-height:1.5; text-align:justify; letter-spacing:1px;}
.est_body .cont5 .date{font-size:1.8rem; font-weight:700; color:#222; display:block; text-align:center; margin-bottom:10px;}
.est_body .cont5 .date+div span{font-size: 3.2rem;text-align:center;}`;
cloned.prepend(styleEl);
container.style.position = 'absolute';
container.style.top = '0';
container.style.left = '0';
container.style.width = element.scrollWidth + 'px';
@ -397,9 +411,13 @@ async function makePDF() {
container.style.background = 'white';
container.style.zIndex = '-1';
container.style.overflow = 'visible';
container.style.fontFamily = "'HYgsrB', sans-serif";
container.style.fontWeight = '700';
container.style.opacity = '0';
container.appendChild(cloned);
document.body.appendChild(container);
// 2⃣ 클론 기준으로 html2canvas 렌더링
const canvas = await html2canvas(cloned, {
scale: 2,
@ -408,7 +426,7 @@ async function makePDF() {
scrollY: 0,
windowWidth: cloned.scrollWidth,
windowHeight: cloned.scrollHeight,
backgroundColor: "#FFFFFF",
backgroundColor: "#ffffff",
});
// 3⃣ 임시 클론 제거
@ -416,35 +434,57 @@ async function makePDF() {
// 4⃣ PDF 생성
const imgData = canvas.toDataURL("image/png");
const watermarkImg = await loadImage('/ipedu/visitEdu/usr/publish/images/content/watermark.png'); // 추가
const pdf = new jsPDF("p", "mm", "a4");
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const imgProps = pdf.getImageProperties(imgData);
const imgWidth = pdfWidth;
const imgHeight = (imgProps.height * pdfWidth) / imgProps.width;
//alert(pdfWidth);
//alert(pdfHeight);
const imgWidth = pdfWidth;
const imgHeight = (canvas.height * pdfWidth) / canvas.width;
//const imgHeight = pdfHeight;
//alert(imgWidth);
//alert(imgHeight);
let heightLeft = imgHeight;
let position = 0;
const yOffset = (pdfHeight - imgHeight) / 2;
pdf.addImage(imgData, "PNG", 0, position, imgWidth, imgHeight);
/*
pdf.addImage(imgData, "PNG", 0, yOffset, imgWidth, imgHeight);
heightLeft -= pdfHeight;
*/
while (heightLeft > 0) {
position = heightLeft - imgHeight;
pdf.addPage();
pdf.addImage(imgData, "PNG", 0, position, imgWidth, imgHeight);
pdf.addImage(watermarkImg, 'PNG', pdfWidth / 2 - 40, pdfHeight / 2 - 40, 80, 80);
heightLeft -= pdfHeight;
if (heightLeft > 0) pdf.addPage();
}
pdf.save("divBody_전체.pdf");
}
// 워터마크 이미지 로드 함수
function loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "anonymous";
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
});
}
</script>
<!-- 일정 상세 -->
<form id="statusChgForm" name="statusChgForm" method="post">
@ -465,32 +505,33 @@ async function makePDF() {
<div class="popup_wrap popType01" tabindex="0" data-info="${vEEduChasiVO.eduAplctOrd}" data-tooltip-con="sub36_pop02" data-focus="sub36_pop02" data-focus-prev="sub36_pop02_close">
<div class="popup_tit">
<p>이수증 출력</p>
<button class="btn_popup_close tooltip-close" data-focus="sub36_pop02_close" title="팝업 닫기"><i></i></button>
</div>
<div class="popup_cont">
<div class="cont_body">
<div class="pop_tb_type02">
<div class="estimate" id="divBody">
<div class="cont2 clearfix">
<div class="est_head clearfix">
<!-- <div class="est_head clearfix">
<img src="/publish/images/CI.png" alt="문자온 CI">
<div class="clearfix">
<p>&nbsp;</p>
<p>&nbsp;</p>
</div>
</div>
</div> -->
<div class="est_body" style="border:1px solid black">
<div class="cont1 tb_ver2" style="margin-top:10px;">
<div>
<p style="margin-left:30px;"><기소유예-2025-00083></p>
<p><기소유예-2025-00083></p>
</div>
</div>
<h2>교 육 이 수 증</h2>
<div class="cont5">
<p><span>&nbsp;&nbsp;</p>
<div>
<span>수료과목 : 조건부 기소유예 10기</span>
</div>
@ -502,43 +543,36 @@ async function makePDF() {
</div>
</div>
<div class="cont5">
<p>&nbsp;</p>
<div class="cont5 substance">
<div>
<span>&nbsp;</span>
<p>
위 사람은 한국지식재산보호원 지식재산 보호 교육 시스템에서
진행하는 '조건부 기소유예 10기'를 수료 하였기에 위 교육이수증을 드립니다.
</p>
</div>
</div>
<div class="cont5">
<p>&nbsp;</p>
<p class="date">2025년 10월 7일</p>
<div>
<span>위 사람은 한국지식재산보호원............</span>
<span>한국지식재산보호원장</span>
<span class="big_stamp">
<!-- 직인 변경 예정 -->
<img src="/publish/images/content/big_stamp.png">
</span>
</div>
<!-- <div style="height:1500px;background:skyblue;">여러장 test</div> -->
</div>
<div class="cont5">
<p>&nbsp;</p>
<div>
<span>&nbsp;</span>
</div>
</div>
<div class="cont5">
<p><span>2025 년&nbsp;&nbsp;<span>10</span> 월&nbsp;&nbsp;<span>7</span> 일</p>
<div>
<span><font size="13">한국지식재산보호원</font></span>
<span class="big_stamp"><img src="/publish/images/content/big_stamp.png"></span>
</div>
</div>
</div>
<div class="pop_btn_wrap btn_layout01" id="est_btn_wrap">
<div class="btn_left"></div>
<div class="btn_center">
<button type="button" class="btnType btnType05" onclick="javascript:makePDF(); return false;">인쇄하기</button>
<button class="btn_popup_close btnType02 tooltip-close" data-focus="sub36_pop02_close" title="팝업 닫기">닫기</button>
</div>
</div>
<div class="est_btn_wrap" id="est_btn_wrap">
<button type="button" class="btnType" onclick="javascript:makePDF(); return false;"><i class="print_img"></i>인쇄하기</button>
<button class="btnType btn_popup_close tooltip-close" data-focus="sub36_pop02_close" title="팝업 닫기"><i class="print_img"></i>닫기</button>
<div class="btn_right"></div>
</div>
</div>

View File

@ -307,7 +307,7 @@ $(document).ready(function(){
<input type="hidden" name="qestnrId" id="qestnrId" value="${chasiSrvyList[0].qestnrId}">
<input type="hidden" name="qestmInfoSize" id="qestmInfoSize" value="${fn:length(chasiSrvyList)}">
<div class="popup_wrap popType01" tabindex="0" data-info="${vEEduChasiVO.eduAplctOrd}" data-tooltip-con="sub36_pop02" data-focus="sub36_pop02" data-focus-prev="sub36_pop02_close">
<div class="popup_wrap popType01 survey_popup" tabindex="0" data-info="${vEEduChasiVO.eduAplctOrd}" data-tooltip-con="sub36_pop02" data-focus="sub36_pop02" data-focus-prev="sub36_pop02_close">
<div class="popup_tit">
<p>설문 결과 등록</p> <button class="btn_popup_close tooltip-close" data-focus="sub36_pop02_close" title="팝업 닫기"><i></i></button>
</div>
@ -429,12 +429,12 @@ $(document).ready(function(){
<col style="width: auto;">
<col style="width: 50%;">
</colgroup>
<thead>
<!-- <thead>
<tr>
<th scope="col">평가문항</th>
<th scope="col"></th>
</tr>
</thead>
</thead> -->
<tbody>
<c:forEach items="${chasiSrvyList}" var="QestmInfo" varStatus="status1">
@ -445,7 +445,7 @@ $(document).ready(function(){
<tr>
<th scope="row" class="t_left">
${status1.count}) <c:out value="${QestmInfo.qestnCn}" escapeXml="false" />
<b>Q${status1.count}.</b> <c:out value="${QestmInfo.qestnCn}" escapeXml="false" />
<c:if test="${QestmInfo.mxmmChoiseCo > 1}">
<font color="red"><b>(최대선택건수 ${QestmInfo.mxmmChoiseCo})</b></font>
</c:if>
@ -454,9 +454,11 @@ $(document).ready(function(){
</th>
<td style="text-align:left;">
<div class="radio_wrap">
<c:if test="${not empty QestmInfo.answer5}">
<br/>
<label for="verySatisfied_${status1.index}" class="label">매우만족</label>
<span>
<input type="radio" numberOnly class="popupInput" style="width: 20px;padding:0 5px;text-align:center;"
title="매우만족" id="verySatisfied_${status1.index}" name="resultList[${status1.index}].responseRadio" value="5"
@ -465,16 +467,12 @@ $(document).ready(function(){
</c:if>
>
${QestmInfo.answer5}
<label for="verySatisfied_${status1.index}"><span class="label">매우만족</span>${QestmInfo.answer5}</label>
</span>
</c:if>
<c:if test="${not empty QestmInfo.answer4}">
<br/>
<label for="satisfied_${status1.index}" class="label">만족</label>
<span>
<input type="radio" numberOnly class="popupInput" style="width: 20px;padding:0 5px;text-align:center;"
title="만족" id="satisfied_${status1.index}" name="resultList[${status1.index}].responseRadio" value="4"
@ -483,15 +481,14 @@ $(document).ready(function(){
</c:if>
>
${QestmInfo.answer4}
<label for="satisfied_${status1.index}"><span class="label">만족</span>${QestmInfo.answer4}</label>
</span>
</c:if>
<c:if test="${not empty QestmInfo.answer3}">
<br/>
<label for="neither_${status1.index}" class="label">보통</label>
<span>
<input type="radio" numberOnly class="popupInput" style="width: 20px;padding:0 5px;text-align:center;"
title="보통" id="neither_${status1.index}" name="resultList[${status1.index}].responseRadio" value="3"
@ -500,14 +497,13 @@ $(document).ready(function(){
</c:if>
>
${QestmInfo.answer3}
<label for="neither_${status1.index}"><span class="label">보통</span>${QestmInfo.answer3}</label>
</span>
</c:if>
<c:if test="${not empty QestmInfo.answer2}">
<br/>
<label for="dissatisfied_${status1.index}" class="label">불만족</label>
<span>
<input type="radio" numberOnly class="popupInput" style="width: 20px;padding:0 5px;text-align:center;"
title="불만족" id="dissatisfied_${status1.index}" name="resultList[${status1.index}].responseRadio" value="2"
@ -516,15 +512,14 @@ $(document).ready(function(){
</c:if>
>
${QestmInfo.answer2}
<label for="dissatisfied_${status1.index}"><span class="label">불만족</span>${QestmInfo.answer2}</label>
</span>
</c:if>
<c:if test="${not empty QestmInfo.answer1}">
<br/>
<label for="veryDissatisfied_${status1.index}" class="label">매우불만족</label>
<span>
<input type="radio" numberOnly class="popupInput" style="width: 20px;padding:0 5px;text-align:center;"
title="매우불만족" id="veryDissatisfied_${status1.index}" name="resultList[${status1.index}].responseRadio" value="1"
@ -533,12 +528,10 @@ $(document).ready(function(){
</c:if>
>
${QestmInfo.answer1}
<label for="veryDissatisfied_${status1.index}"><span class="label">매우불만족</span>${QestmInfo.answer1}</label>
</span>
</c:if>
<br/>
<br/>
</div>
</td>
</tr>
</c:forEach>
@ -556,9 +549,7 @@ $(document).ready(function(){
<div class="btn_left">
</div>
<div class="btn_center">
<button type="button" class="btnType05" id="popupSubmin" onclick="popupSrvySendSubmit();">제출</button>
<button type="button" class="btnType02 tooltip-close" data-focus="sub36_pop02_close" data-focus-next="sub36_pop02">취소</button>
</div>
<div class="btn_right">

View File

@ -135,6 +135,10 @@ select.selType1.read-only{background: url(/ipedu/visitEdu/usr/publish/images/con
.select_wrap li{display:flex;align-items:center;gap:8px;}
.select_wrap label{font-size:1.8rem;color:#666;}
.radio_wrap{display:flex;gap:16px;}
.radio_wrap li{display:flex;align-items:center;gap:8px;}
.radio_wrap label{font-size:1.8rem;color:#666;}
.list_top .read-only:not(select){background:#888 !important;color:#fff !important;border:0 !important;}
/* tab */

View File

@ -91,3 +91,17 @@
font-style: normal;
font-display: swap;
}
/* 궁서체 */
@font-face {
font-family: 'HYgsrB';
src: url('/ipedu/visitEdu/usr/publish/css/font/HYgsrB.eot');
src: url('/ipedu/visitEdu/usr/publish/css/font/HYgsrB.eot?#iefix') format('embedded-opentype'),
url('/ipedu/visitEdu/usr/publish/css/font/HYgsrB.woff2') format('woff2'),
url('/ipedu/visitEdu/usr/publish/css/font/HYgsrB.woff') format('woff'),
url('/ipedu/visitEdu/usr/publish/css/font/HYgsrB.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}

View File

@ -13,6 +13,10 @@
.popup_cont .pagination {margin: 0 0 10px 0;}
.popup_cont .calendar_wrap{font-size:1.5rem;}
.popup_wrap .radio_wrap{gap:8px;flex-direction:column;}
.popup_wrap .radio_wrap li{gap:4px;}
.popup_wrap .radio_wrap label{font-size:1.5rem;color:#555;}
/* popup list top css 수정(학교명 검색) */
.popup_cont .list_top {padding: 14px 30px;}
.popup_cont .list_top .pop_list_top_left {width: 29%;}
@ -136,6 +140,28 @@
.popup_cont .cont_body .qr_wrap{margin-bottom: 0px; overflow-y: hidden;}
.popup_cont .cont_body .qr_wrap .qr_img img{margin: 0 auto; /*display: block;*/}
/* 이수증 출력 */
.popup_cont .estimate{padding:30px 3%;}
.btn_popup_close{width:auto;min-width:20px;}
.popup_cont .estimate *{font-family: 'HYgsrB';font-weight:700;}
.popup_cont .est_body{position:relative;padding:50px 0;}
.popup_cont .est_body::after{position:absolute;content:"";width:100%;height:100%;background:url(/ipedu/visitEdu/usr/publish/images/content/watermark.png) no-repeat center center;left:0;top:0;}
.popup_cont .est_body h2{font-size:4.4rem;-webkit-text-stroke-width: 0.05px;-webkit-text-stroke-color: #222;}
.popup_cont .est_body .cont1>div p{margin:0 0 0 30px;}
.popup_cont .est_body .cont5 div span:nth-child(1){font-size:1.8rem;font-weight:700;color:#222;margin:0 0 0 30px;}
.popup_cont .est_body .cont5>div{justify-content:flex-start;line-height:1.5;}
.popup_cont .est_body .cont5.substance>div{justify-content:center;margin:100px 0;}
.popup_cont .est_body .cont5.substance>div p{font-size:2rem;font-weight:700;color:#222;margin:0 50px;text-align:justify;letter-spacing:1px;}
.popup_cont .est_body .cont5 .date{font-size:1.8rem;font-weight:700;color:#222;}
.popup_cont .est_body .cont5 .date+div{justify-content:center;}
.popup_cont .est_body .cont5 .date+div span{font-size:3.2rem;-webkit-text-stroke-width: 0.05px;-webkit-text-stroke-color: #222;}
/* 설문조사 팝업 */
.survey_popup .pop_tb_type02 b{font-size:1.5rem;font-weight:bold;color:#2b68da;}
.survey_popup .pop_tb_type02>table>tbody>tr>th, .survey_popup .pop_tb_type02>table>tbody>tr>td{font-size:1.7rem;}
.survey_popup .pop_tb_type02>table>tbody>tr>th{font-weight:400;color:#333;}
.survey_popup .radio_wrap{padding:20px;margin:10px;border-radius:8px;background:#f8f9fa;}
@media all and (max-width: 767px){
.popup_cont {padding: 10px;}
@ -157,6 +183,7 @@
/* 교육신청자 대시보드 */
.text_greeting {margin:0 0 0 0;}
}
@media all and (max-width: 400px){

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB