fix: [approvals] 위촉증명서 인쇄/PDF A4 레이아웃 수직 배분 개선

- 인쇄 CSS: @page A4 적용, 상단 padding 100px로 확대
- HTML 미리보기: 제목/테이블/증명문구/날짜/서명 간격 확대
- PDF: 상단 여백 및 섹션 간 Ln 값 증가 (A4 수직 균등 배분)
This commit is contained in:
김보곤
2026-03-06 10:08:55 +09:00
parent b05daffedb
commit 10b3490d9c
3 changed files with 24 additions and 21 deletions

View File

@@ -78,17 +78,20 @@ public function generatePdfResponse(array $content): \Illuminate\Http\Response
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->SetMargins(20, 20, 20);
$pdf->SetMargins(20, 40, 20);
$pdf->SetAutoPageBreak(true, 20);
$font = $this->getKoreanFont();
$pdf->AddPage();
// 상단 여백
$pdf->Ln(20);
// 제목
$pdf->SetFont($font, 'B', 22);
$pdf->Cell(0, 20, '위 촉 증 명 서', 0, 1, 'C');
$pdf->Ln(8);
$pdf->Ln(20);
$pageWidth = $pdf->getPageWidth() - 40;
$thWidth = 30;
@@ -119,19 +122,19 @@ public function generatePdfResponse(array $content): \Illuminate\Http\Response
$this->addTableRow($pdf, $font, [
['용 도', $content['purpose'] ?? '-', 0],
]);
$pdf->Ln(12);
$pdf->Ln(30);
// 증명 문구
$pdf->SetFont($font, '', 12);
$pdf->Cell(0, 10, '위와 같이 위촉하였음을 증명합니다.', 0, 1, 'C');
$pdf->Ln(6);
$pdf->Ln(20);
// 발급일
$issueDate = $content['issue_date'] ?? date('Y-m-d');
$issueDateFormatted = $this->formatDate($issueDate);
$pdf->SetFont($font, 'B', 12);
$pdf->Cell(0, 10, $issueDateFormatted, 0, 1, 'C');
$pdf->Ln(12);
$pdf->Ln(30);
// 회사명 + 대표이사
$ceoName = $content['ceo_name'] ?? '';

View File

@@ -1282,10 +1282,10 @@ function printAppointmentCertPreview() {
const content = document.getElementById('appointment-cert-preview-content').innerHTML;
const win = window.open('', '_blank', 'width=800,height=1000');
win.document.write('<html><head><title>위촉증명서</title>');
win.document.write('<style>body{font-family:"Pretendard","Malgun Gothic",sans-serif;padding:48px 56px;margin:0;} table{border-collapse:collapse;width:100%;} th,td{border:1px solid #333;padding:10px 14px;font-size:14px;} th{background:#f8f9fa;font-weight:600;text-align:left;white-space:nowrap;width:120px;} @media print{body{padding:40px 48px;}}</style>');
win.document.write('</head><body>');
win.document.write('<style>@page{size:A4;margin:0;} body{font-family:"Pretendard","Malgun Gothic",sans-serif;margin:0;padding:0;} .cert-page{padding:100px 56px 60px;box-sizing:border-box;} table{border-collapse:collapse;width:100%;} th,td{border:1px solid #333;padding:10px 14px;font-size:14px;} th{background:#f8f9fa;font-weight:600;text-align:left;white-space:nowrap;width:120px;}</style>');
win.document.write('</head><body><div class="cert-page">');
win.document.write(content);
win.document.write('</body></html>');
win.document.write('</div></body></html>');
win.document.close();
win.onload = function() { win.print(); };
}
@@ -1296,9 +1296,9 @@ function buildAppointmentCertPreviewHtml(d) {
const tdStyle = 'border:1px solid #333; padding:10px 14px; font-size:14px;';
return `
<h1 style="text-align:center; font-size:28px; font-weight:700; letter-spacing:12px; margin-bottom:40px;">위 촉 증 명 서</h1>
<h1 style="text-align:center; font-size:28px; font-weight:700; letter-spacing:12px; margin-bottom:60px;">위 촉 증 명 서</h1>
<table style="border-collapse:collapse; width:100%; margin-bottom:20px;">
<table style="border-collapse:collapse; width:100%; margin-bottom:60px;">
<tr>
<th style="${thStyle}">성 명</th>
<td style="${tdStyle}" colspan="3">${e(d.name)}</td>
@@ -1325,15 +1325,15 @@ function buildAppointmentCertPreviewHtml(d) {
</tr>
</table>
<p style="text-align:center; font-size:15px; line-height:2; margin:36px 0;">
<p style="text-align:center; font-size:15px; line-height:2; margin:80px 0;">
위와 같이 위촉하였음을 증명합니다.
</p>
<p style="text-align:center; font-size:15px; font-weight:500; margin-bottom:48px;">
<p style="text-align:center; font-size:15px; font-weight:500; margin-bottom:80px;">
${e(d.issueDateFormatted)}
</p>
<div style="text-align:center; margin-top:32px;">
<div style="text-align:center; margin-top:60px;">
<p style="font-size:16px; font-weight:600; margin-bottom:8px;">${e(d.company)}</p>
<p style="font-size:14px; color:#555;">대표이사 &nbsp;&nbsp; ${e(d.ceoName)} &nbsp;&nbsp; (인)</p>
</div>

View File

@@ -599,10 +599,10 @@ function printAppointmentCertShowPreview() {
const content = document.getElementById('appointment-cert-show-preview-content').innerHTML;
const win = window.open('', '_blank', 'width=800,height=1000');
win.document.write('<html><head><title>위촉증명서</title>');
win.document.write('<style>body{font-family:"Pretendard","Malgun Gothic",sans-serif;padding:48px 56px;margin:0;} table{border-collapse:collapse;width:100%;} th,td{border:1px solid #333;padding:10px 14px;font-size:14px;} th{background:#f8f9fa;font-weight:600;text-align:left;white-space:nowrap;width:120px;} @media print{body{padding:40px 48px;}}</style>');
win.document.write('</head><body>');
win.document.write('<style>@page{size:A4;margin:0;} body{font-family:"Pretendard","Malgun Gothic",sans-serif;margin:0;padding:0;} .cert-page{padding:100px 56px 60px;box-sizing:border-box;} table{border-collapse:collapse;width:100%;} th,td{border:1px solid #333;padding:10px 14px;font-size:14px;} th{background:#f8f9fa;font-weight:600;text-align:left;white-space:nowrap;width:120px;}</style>');
win.document.write('</head><body><div class="cert-page">');
win.document.write(content);
win.document.write('</body></html>');
win.document.write('</div></body></html>');
win.document.close();
win.onload = function() { win.print(); };
}
@@ -613,17 +613,17 @@ function _buildAppointmentCertHtml(d) {
const tdStyle = 'border:1px solid #333; padding:10px 14px; font-size:14px;';
return `
<h1 style="text-align:center; font-size:28px; font-weight:700; letter-spacing:12px; margin-bottom:40px;">위 촉 증 명 서</h1>
<table style="border-collapse:collapse; width:100%; margin-bottom:20px;">
<h1 style="text-align:center; font-size:28px; font-weight:700; letter-spacing:12px; margin-bottom:60px;">위 촉 증 명 서</h1>
<table style="border-collapse:collapse; width:100%; margin-bottom:60px;">
<tr><th style="${thStyle}">성 명</th><td style="${tdStyle}" colspan="3">${e(d.name)}</td></tr>
<tr><th style="${thStyle}">주민등록번호</th><td style="${tdStyle}" colspan="3">${e(d.resident)}</td></tr>
<tr><th style="${thStyle}">소 속</th><td style="${tdStyle}">${e(d.department)}</td><th style="${thStyle}">연 락 처</th><td style="${tdStyle}">${e(d.phone)}</td></tr>
<tr><th style="${thStyle}">위촉(재직)기간</th><td style="${tdStyle}">${e(d.hireDate)} ~ ${e(d.resignDate)}</td><th style="${thStyle}">계약자격</th><td style="${tdStyle}">${e(d.contractType)}</td></tr>
<tr><th style="${thStyle}">용 도</th><td style="${tdStyle}" colspan="3">${e(d.purpose)}</td></tr>
</table>
<p style="text-align:center; font-size:15px; line-height:2; margin:36px 0;">위와 같이 위촉하였음을 증명합니다.</p>
<p style="text-align:center; font-size:15px; font-weight:500; margin-bottom:48px;">${e(d.issueDateFormatted)}</p>
<div style="text-align:center; margin-top:32px;">
<p style="text-align:center; font-size:15px; line-height:2; margin:80px 0;">위와 같이 위촉하였음을 증명합니다.</p>
<p style="text-align:center; font-size:15px; font-weight:500; margin-bottom:80px;">${e(d.issueDateFormatted)}</p>
<div style="text-align:center; margin-top:60px;">
<p style="font-size:16px; font-weight:600; margin-bottom:8px;">${e(d.company)}</p>
<p style="font-size:14px; color:#555;">대표이사 &nbsp;&nbsp; ${e(d.ceoName)} &nbsp;&nbsp; (인)</p>
</div>