이전 작성글에서 spire.pdf.free 라이브러리를 이용하여 HTML 을 pdf 로 변환했었는데 페이지수 등에 제약이 있어. 오픈소스인 openhtmltopdf 라이브러리로 구현해보았다.
<!-- OpenHtmlToPDF -->
<dependency>
<groupId>com.openhtmltopdf</groupId>
<artifactId>openhtmltopdf-core</artifactId>
<version>1.0.10</version>
</dependency>
<dependency>
<groupId>com.openhtmltopdf</groupId>
<artifactId>openhtmltopdf-pdfbox</artifactId>
<version>1.0.10</version>
</dependency>
테이블이나 스타일, 폰트, 이미지가 제대로 표시되는지 확인 할 것입니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
<link type="text/css" rel="stylesheet" href="http://localhost:8080/css/pdfStyle.css"/>
<style>
.red{color: red;}
</style>
</head>
<body class="border">
<h1>html to pdf</h1>
<p class="green">샘플 테이블</p>
<table class="border">
<thead>
<tr>
<th class="red">th1</th>
<th>th2</th>
</tr>
</thead>
<tbody>
<tr>
<td>td1</td>
<td>td2</td>
</tr>
<tr>
<td>한글한글</td>
<td>한글</td>
</tr>
</tbody>
</table>
<p class="NotoSansKR">noto-sans-kr 서체 적용 테스트</p>
<p class="NotoSansKR-Bold">noto-sans-kr-bold 서체 적용 테스트</p>
<p class="NanumGothic">나눔고딕</p>
<p class="YnPeople-Gothic">유앤피플 고딕체</p>
<p>기본폰트(NotoSansKR)</p>
<img src="http://localhost:8080/img/icon.png" alt="icon" height="80"/>
</body>
</html>
@font-face {
font-family: "NanumGothic";
src: url("http://localhost:8080/font/NanumGothic/NanumGothic-Regular.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "NanumGothic";
src: url("http://localhost:8080/font/NanumGothic/NanumGothic-Bold.ttf") format("truetype");
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: "Noto Sans KR";
src: url("http://localhost:8080/font/Noto_Sans_KR/static/NotoSansKR-Regular.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "Noto Sans KR Bold";
src: url("http://localhost:8080/font/Noto_Sans_KR/static/NotoSansKR-Bold.ttf") format("truetype");
font-weight: bold;
font-style: normal;
}
*{ font-family: Arial,"Noto Sans KR" , serif;font-size: 16pt;}
.border{border: 1px solid #AAAAAA;}
td{border: 1px solid gray;border-collapse: collapse;}
.NotoSansKR{font-family: NotoSansKR, "Noto Sans KR", serif}
.NotoSansKR-Bold{font-family: "Noto Sans KR Bold",serif;}
.NanumGothic{font-family: NanumGothic, "NanumGothic",serif;}
.YnPeople-Gothic{font-family: "유앤피플 고딕", serif}
.green{color: #4CAF50;}
package com.pdf.pdfbox;
import com.openhtmltopdf.css.parser.property.PageSize;
import com.openhtmltopdf.outputdevice.helper.BaseRendererBuilder;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
@Slf4j
@Controller
public class PdfController {
@RequestMapping("/")
public void generatePdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
try (
OutputStream os = response.getOutputStream();
InputStream inputStream = getClass().getResourceAsStream("/static/html/template/pdf/pdfSample.html")
) {
String html = new String(Objects.requireNonNull(inputStream).readAllBytes(), StandardCharsets.UTF_8);
PdfRendererBuilder builder = new PdfRendererBuilder();
// ttf , otf 만 가능
builder.useFont(() -> getClass().getResourceAsStream("/static/font/유앤피플 고딕 UNI.ttf"), "유앤피플 고딕");
builder.useFont(() -> getClass().getResourceAsStream("/static/font/NanumGothic/NanumGothic-Regular.ttf"), "NanumGothic");
builder.useFont(() -> getClass().getResourceAsStream("/static/font/Noto_Sans_KR/static/NotoSansKR-Regular.ttf"), "NotoSansKR");
builder.useFont(() -> getClass().getResourceAsStream("/static/font/Noto_Sans_KR/static/NotoSansKR-Bold.ttf"), "NotoSansKR-Bold");
float a4Width = PageSize.A4.getPageWidth().getFloatValue((short) 0);
float a4Height = PageSize.A4.getPageHeight().getFloatValue((short) 0);
builder.useDefaultPageSize(a4Width,a4Height, BaseRendererBuilder.PageSizeUnits.MM);
builder.withHtmlContent(html, "");
builder.toStream(os);
builder.run();
} catch (RuntimeException e) {
log.error(e.getMessage(),e);
}
}
@GetMapping("/pdf/pdfSample")
String sampleHtmlView() {
return "/html/template/pdf/pdfSample.html";
}
}