[iText] HTML을 PDF로 변환하기

꿈꾸는자린이·2024년 3월 28일

PDF 변환

목록 보기
1/1
post-thumbnail

이번에 모두의싸인과 비슷한 계약관련 프로젝트를 맡아서 하는 중 PDF 변환 과정을 작업하게되었다. 오늘 포스팅 할 내용은 에디터로 만들어진 HTML을 PDF 파일로 변환하는 작업이다.

📎사용 라이브러리


implementation 'com.itextpdf:itext7-core:7.1.2'
implementation 'com.itextpdf:html2pdf:3.0.2'

pdf 작업하는 자바의 유명 라이브러리가 크게 itext와 pdfbox 두개가 있었다.
나는 여기서 itext를 선택하였는대 그 이유는 itext가 Pdfbox 보다 보다 더 고급 기능을 사용할 수 있기 때문이지만 공식문서가 그닥.. 친절하지않아 고생을 좀 많이했다.. 주워가는 사람은 복받은것이다.. 나는 징짜너무힘들어서 다신 보고싶지않앙..

📎구현 기능

  • 인라인CSS 가 아닌 CssFile을 렌더링 하여 적용
  • 한글 출력을 위한 폰트 적용

📎코드

public void transferHtml(String html) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ConverterProperties properties = new ConverterProperties();

        //css 파일지정
        properties.setBaseUri("./src/main/resources");

        PdfWriter writer = new PdfWriter(outputStream);

        //폰트지정
        try {
            FontProvider fontProvider = new DefaultFontProvider(false, false, false);
            FontProgram font = FontProgramFactory.createFont("/font/gulimR.ttf");
            fontProvider.addFont(font);
            FontProgram boldFont = FontProgramFactory.createFont("/font/gulimB.ttf");
            fontProvider.addFont(boldFont);
            properties.setFontProvider(fontProvider);
        } catch (IOException e) {
            log.error("[ContractFileService] Fail transferHtml File : {}", e.getMessage());
            throw new CustomRuntimeException(ErrorResponseCode.CONTRACT_FILE_CONVERSION_FAIL);
        }

        HtmlConverter.convertToPdf(html, writer, properties);
    }

📎삽질일기

  1. iText version
    : 실행 시 NoClassException이 떳다.. 다른 라이브러리와 버전충돌이 나는 것으로 판단되고 7.1.2 버전으로 낮추니 정상작동되었다. 8버전은 아직 베타버전이라 그런 것 같다.
  2. CssFile Not Found
    : CssFile 경로를 설정하는 properties.setBaseUri("./src/main/resources"); 해당코드에서

Unable to retrieve stream with given base URI (file:/Users/kwonyeji/Documents/project/techsign-api/main/resources) and source path (css/content.css)

FileNotFoundException: /경로/content.css (No such file or directory) 에러가 발생했다.

- 테스트 html - 

"<head>\n" +
            "<link rel=\"stylesheet\" type=\"text/css\" href=\"css/content.css\">\n" +
            "</head>\n" +
            "<body>\n" +
            "<p><strong>볼드</strong></p><p><strong>bold</strong></p><p>&nbsp;</p><p><i>이태릭</i></p><p><i>italic</i></p><p>&nbsp;" +
                "</p><figure class=\"table\"><table><tbody><tr><td>table</td><td>테이블</td></tr></tbody></table></figure><blockquote>"
                + "<p>따옴표</p></blockquote><blockquote><p>quote</p></blockquote><ul><li>bulletList</li><li>리스트1</li></ul><p>&nbsp;"
                + "</p><ol><li>orderList</li><li>리스트2</li></ol>" +
            "</body>";

baseuri와 link의 href의 경로 문제였는대
setbaseuri()는 HTML 변환 시 상대 경로를 해석하는 데 사용된다.
즉 setBaseUri("/resources")로 설정하면 href=\"css/content.css\" 이 부분에서 CSS파일을
/resources/css/contect.css를 렌더링 하게되는 것이다.
여기까지는 알겠는대 계속 오류가 나서 확인해보니 setBaseUti는 절대경로를 반영하기떄문에 setBaseUrl("./src/main/resource")로 변경하여 해결하였다.


<PDF 적용된 모습>

- CSS FILE -

.content {
    background-color: lightgray;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

h1 {
    color: blue;
}

p {
    font-size: 16px;
}

table {
    border-collapse: collapse;
    width: 100%;
}

th, td {
    padding: 8px;
    text-align: left;
    border-bottom: 1px solid #ddd;
}

th {
    background-color: lightblue;
    font-weight: bold;
}
profile
자바린이

1개의 댓글

comment-user-thumbnail
2024년 3월 28일

저도 비슷한거 하다가 고민 중인데 보고 시도해볼게요 감사합니다

답글 달기