Notice
Recent Posts
Recent Comments
Link
250x250
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- javaspring
- 웹앱
- springboot
- Spring Boot
- 마이바티스
- 코딩
- 처음만나는자바스크립트
- 자바스크립트기초
- 구글 oauth
- mybatis
- 자바스크립트
- CSS
- 리액트초기세팅
- spring
- Javascript
- 리액트세팅
- react
- 기초코딩
- 자바스크립트 기초
- 기초 코딩
- 웹
- java
- 구글캘린더api
- 자바스크립트기초문법
- HTML
- 리액트프로젝트세팅
- 전자정부 서버세팅
- 자바
- 스프링부트
- js
Archives
- Today
- Total
인생 디벨로퍼
[Spring boot] HTML 파일 -> PDF 전환 본문
728x90
코드 순서가 아닌, 실행순서 위주로 정리했습니다.
1. 라이브러리 설정
// Thymeleaf 사용, HTML 파일 기반 동적 콘텐츠 생성 가능
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
// XHTML 및 CSS를 기반으로 PDF를 생성할 수 있는 라이브러리. 내부적으로 iText 라이브러리를 사용
implementation 'org.xhtmlrenderer:flying-saucer-pdf:9.9.5'
2. 파일 저장 경로 설정
static String userDir() {
String userDir = System.getProperty("user.dir").toString();
logger.info("userDir"+userDir);
if (userDir.contains("root")) { //서버에 올라갔을때
userDir = "/root";
}else{
Path paths = Paths.get(userDir);
userDir = paths.getParent().toString();
}
return userDir;
}
프로젝트 밖에 저장 되도록 기본 루트를 정합니다.
상황에 따라 다른 디렉토리를 생성해야할 수 있을거 같아, 디렉토리 생성은 하단 메소드에서 실행했습니다.
3. HTML 을 String 으로 변환
private static String parseHtmlFileToString(String templateCode, Map<String, Object> map){
// 타임리프 템플릿을 로딩 리졸버 (경로 : src/main/resources/)
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
resolver.setPrefix("templates/");
resolver.setSuffix(".html"); // 템플릿 파일 확장자 지정
resolver.setCharacterEncoding("UTF-8"); // 템플릿 파일 문자열 인코딩
resolver.setForceTemplateMode(true); //파일 확장자나 내용에 관계없이 강제로 설정된 템플릿 모드를 사용
resolver.setTemplateMode(TemplateMode.HTML); //템플릿을 HTML 모드로 렌더링
//템플릿엔진 생성, 위의 ClassLoaderTemplateResolver 연결
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(resolver);
// 템플릿 렌더링, 문자열 반환
Context context = new Context();
context.setVariables(map);
return engine.process(templateCode, context);
}
- String templateCode: 사용할 템플릿 HTML 파일 명, (당연히 /templates 경로 안에 있어야함)
- Map<String, Object> map: 사용할 변수. 다음 메소드로 넘겨줄꺼다
지정한 html 파일과 context 를 읽어 String 으로 반환 해줍니다.
4. 변수 설정, 폰트 설정
private static ITextRenderer getRenderer(String html, Map<String, Object> pMap) throws IOException, DocumentException{
// 폰트 설정. 해줘야 한글이 나옴
ClassPathResource fontResource = new ClassPathResource("static/font/SpoqaHanSansNeo-Regular.ttf");
if (fontResource.exists()) {
System.out.println("Font file exists at: " + fontResource.getPath());
} else {
System.out.println("Font file does not exist.");
}
// 변수 데이터 넣어주기
for (String key : pMap.keySet()) {
html = html.replaceAll("@" + key + "@", pMap.get(key).toString());
}
// 이미지 변환 메소드로 던진다
B64ImgReplacedElementFactory b64ImgReplacedElementFactory = new B64ImgReplacedElementFactory();
ITextRenderer renderer = new ITextRenderer();
renderer.getSharedContext().setReplacedElementFactory(b64ImgReplacedElementFactory);
renderer.setDocumentFromString(html);
// System.out.println(renderer.getFontResolver().toString());
renderer.getFontResolver()
.addFont(new ClassPathResource("static/font/NotoSansKR-Regular.ttf").getURL().toString(),
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED);
renderer.layout();
return renderer;
}
- String html: string 으로 변환시킨 html 템플릿
- Map<String, Object> pMap: 변수에 설정해줄 데이터
"@" + key + "@" 로 변수를 넣어줌
5. 이미지 변환
public class B64ImgReplacedElementFactory implements ReplacedElementFactory {
public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, UserAgentCallback uac, int cssWidth, int cssHeight) {
Element e = box.getElement();
if (e == null) {
return null;
}
String nodeName = e.getNodeName();
// <img> 태그를 찾아서, src 주소에 있는 이미지 파일 찾아옴
if (nodeName.equals("img")) {
String attribute = e.getAttribute("src");
FSImage fsImage;
try {
fsImage = buildImage(attribute, uac);
} catch (BadElementException e1) {
fsImage = null;
} catch (IOException e1) {
fsImage = null;
}
if (fsImage != null) {
if (cssWidth != -1 || cssHeight != -1) {
fsImage.scale(cssWidth, cssHeight);
}
return new ITextImageElement(fsImage);
}
}
return null;
}
protected FSImage buildImage(String srcAttr, UserAgentCallback uac)
throws IOException, BadElementException {
FSImage fsImage;
if (srcAttr.startsWith("data:image/")) {
String b64encoded =
srcAttr.substring(
srcAttr.indexOf("base64,") + "base64,".length(), srcAttr.length());
byte[] decodedBytes = Base64.getDecoder().decode(b64encoded);
fsImage = new ITextFSImage(Image.getInstance(decodedBytes));
} else {
fsImage = uac.getImageResource(srcAttr).getImage();
}
return fsImage;
}
public void remove(Element e) {}
public void reset() {}
@Override
public void setFormSubmissionListener(FormSubmissionListener listener) {}
}
<img> 태그를 찾아 src 경로에있는 이미지 파일을 base64 로 변환해 리턴
6. String 을 PDF 로 출력
public static void generateFromHtml(Map<String, Object> pMap,String templateCode, String fileName) throws DocumentException, IOException {
// String templateCode = "pdf_test";
Map<String, Object> variables = new HashMap<>();
variables.put("name", "User");
// String filename = "oo 재직증명서.pdf"; // PDF 파일 확장자를 포함한 기본 파일명
String directoryPath = userDir() + "/pdf/"; // 디렉터리 경로
String filepath = directoryPath + fileName;
File file = new File(filepath);
// 경로가 없으면 생성한다.
File directory = new File(directoryPath);
if (!directory.exists()) {
directory.mkdirs();
}
// 해당 경로로 pdf 파일 작성됨
FileOutputStream fos = new FileOutputStream(file);
// 메서드 호출
String result = PdfGenerator.parseHtmlFileToString(templateCode, variables);
// System.out.println(result);
// String 으로 변환된 HTML 내용을 렌더링하여 ITextRenderer 객체를 반환
ITextRenderer renderer = getRenderer(result, pMap);
renderer.createPDF(fos);
fos.close();
}
변수, 폰트, 이미지 설정이 끝난 string 을 pdf 로 변환해 저장.
728x90
'JAVA Spring' 카테고리의 다른 글
K6 부하 테스트 사용법 (설치) (0) | 2025.05.21 |
---|---|
[Google API] 구글 캘린더 일정 List 불러오기 (0) | 2024.11.01 |
[Google API] 구글 캘린더 프로젝트 생성, api 키 생성 (0) | 2024.10.30 |
Spring security + my batis (0) | 2024.03.11 |
myBatis 검색 연습, 검색 쿼리 (.feat 페이징) (0) | 2023.06.23 |