-
[Java] iText를 이용하여 HTML 텍스트를 PDF로 변환하기.java 2022. 7. 7. 13:20728x90반응형
https://zero-gravity.tistory.com/251
[Java] iText를 이용하여 HTML 텍스트를 PDF로 변환하기.
iText라는 라이브러리를 사용했다. 필요한 라이브러리 파일은 2개다. - itextpdf (필자는 5.5.4 버전을 사용) http://sourceforge.net/projects/itext/ - xmlworker (5.5.4 버전 사용) http://sourceforge.n..
zero-gravity.tistory.com
고맙네요..
iText라는 라이브러리를 사용했다.
필요한 라이브러리 파일은 2개다.
- itextpdf (필자는 5.5.4 버전을 사용) http://sourceforge.net/projects/itext/
- xmlworker (5.5.4 버전 사용) http://sourceforge.net/projects/itextsharp/files/xmlworker/
iText로 HTML->PDF 변환 기능을 구현하면서 가장 애먹었던 작업은 한글과 CSS 문제였다.
한글 변환은 어떻게 해야 한다..라는 참고할 만한 사이트가 별로 없었고(외국 애들은 영어쓰니까 ㅠㅠ), 국내 사이트 중에는 어떤 블로거 분이 http://shonm.tistory.com/450 한글이 되는 소스를 올려주셨는데 문제는 이 소스로 CSS는 어떻게 해야 하는지 모른다는 거였다.
텍스트 자체를 PDF로 변환하는 것은 간단한데, 한글이 온전히 보이면서 CSS까지 먹이려니 여간 짜증나는 작업이 아닐 수 없었다.
(쉬웠던 방법은 StyleSheet로 일일히 속성을 코딩하는 것이었는데, 그짓거리는 하고 싶지 않았다)
한글이 되니까 CSS가 안되고, CSS가 되니까 한글이 안되는 돌아버릴 것 같은 상황의 연속이었지만... 결국엔 해냈다. (self 쓰담쓰담)
iText의 API도 뒤져보고 다른 사람들이 올려놓은 소스들도 죄다 살펴보면서 하나하나 조각을 끼워맞췄다.결정적으로 도움이 됐던 사이트는 http://www.wenda.io/questions/4902142/how-to-export-vietnamese-text-to-pdf-using-itext.html 여기였다.베트남 사람한테 도움을 받게 될 줄이야..ㄷㄷ 이 사람도 한자를 PDF로 넣어야 하는데 그 부분에서 막혔던 거다. 영어로 질답해줘서 감사 또 감사...ㅠㅠ
자 그럼,, 아래는 소스다.
3일 동안 개고생해서 정리한 것이니, 감사한 마음으로 가져가 쓰시기를...
Document document = new Document(PageSize.A4, 50, 50, 50, 50); // 용지 및 여백 설정 // PdfWriter 생성 //PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("d:/test.pdf")); // 바로 다운로드. PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream()); writer.setInitialLeading(12.5f); // 파일 다운로드 설정 response.setContentType("application/pdf"); String fileName = URLEncoder.encode("한글파일명", "UTF-8"); // 파일명이 한글일 땐 인코딩 필요 response.setHeader("Content-Transper-Encoding", "binary"); response.setHeader("Content-Disposition", "inline; filename=" + fileName + ".pdf"); // Document 오픈 document.open(); XMLWorkerHelper helper = XMLWorkerHelper.getInstance(); // CSS CSSResolver cssResolver = new StyleAttrCSSResolver(); CssFile cssFile = helper.getCSS(new FileInputStream("C:/eGovFrame/workspace/projectName/src/main/webapp/css/pdf.css")); cssResolver.addCss(cssFile); // HTML, 폰트 설정 XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS); fontProvider.register("C:/eGovFrame/workspace/projectName/src/main/webapp/font/MALGUN.TTF", "MalgunGothic"); // MalgunGothic은 alias, CssAppliers cssAppliers = new CssAppliersImpl(fontProvider); HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers); htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory()); // Pipelines PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer); HtmlPipeline html = new HtmlPipeline(htmlContext, pdf); CssResolverPipeline css = new CssResolverPipeline(cssResolver, html); XMLWorker worker = new XMLWorker(css, true); XMLParser xmlParser = new XMLParser(worker, Charset.forName("UTF-8")); // 폰트 설정에서 별칭으로 줬던 "MalgunGothic"을 html 안에 폰트로 지정한다. String htmlStr = "<html><head><body style='font-family: MalgunGothic;'>" + "<p>PDF 안에 들어갈 내용입니다.</p>" + "<h3>한글, English, 漢字.</h3>" + "</body></head></html>"; StringReader strReader = new StringReader(htmlStr); xmlParser.parse(strReader); document.close(); writer.close();
↓ pdf.css
p {font-weight: bold;} h3 {font-size: 15px; font-weight: bold; color: #0082E9; padding:10px 0 10px 0px; margin:0 10px;}
폰트는 한글이 되는 폰트로 특정 경로에 해당 폰트 파일을 넣고, 위 소스에 경로를 설정해주면 된다.
CSS는 디자이너 분 붙잡고 이것저것 다 해본 결과, 클래스나 div는 안먹고 p태그 h태그 같은 아~~주 원초적이고 순수한 것들만 적용됨을 확인할 수 있었다. ㅋㅋㅋ
그 외... API 찾아보면 PDF 문서를 세부적으로 설정해주는 방법들도 있으니 그런 것들은 알아서....
아래는 위 소스의 결과물,,
**** 내용 추가>>> PDF 워터마크, 쪽 번호, 우측 상단 머릿말 넣기.
아래의 클래스 만든다.
import com.itextpdf.text.Document; import com.itextpdf.text.Element; import com.itextpdf.text.Font; import com.itextpdf.text.Font.FontFamily; import com.itextpdf.text.Paragraph; import com.itextpdf.text.Phrase; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.CMYKColor; import com.itextpdf.text.pdf.ColumnText; import com.itextpdf.text.pdf.GrayColor; import com.itextpdf.text.pdf.PdfPageEventHelper; import com.itextpdf.text.pdf.PdfWriter; public class PdfPageEvent extends PdfPageEventHelper { // Watermark 폰트 설정 // Font FONT = new Font(FontFamily.HELVETICA, 52, Font.BOLD, new GrayColor(0.75f)); Font FONT = new Font(FontFamily.HELVETICA, 52, Font.BOLD, new CMYKColor(64, 11, 0, 0)); Phrase[] header = new Phrase[2]; int pagenumber; @Override public void onOpenDocument(PdfWriter writer, Document document) { header[0] = new Phrase("2015. 01. 07"); // 헤더 머릿말에 넣을 텍스트 } @Override public void onChapter(PdfWriter writer, Document document, float paragraphPosition, Paragraph title) { header[1] = new Phrase(title.getContent()); pagenumber = 1; } @Override public void onStartPage(PdfWriter writer, Document document) { pagenumber++; } @Override public void onEndPage(PdfWriter writer, Document document) { Rectangle rect = writer.getBoxSize("boxName"); // boxName을 PdfWriter.setBoxSize의 boxname 매개 변수와 같게 해야 함. switch (writer.getPageNumber() % 2) { // 쪽수 쪽, 홀수 쪽 구분해서 속성 적용. case 0: // 짝수 쪽 ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_RIGHT, header[0], rect.getRight(), rect.getTop(), 0); break; case 1: // 홀수 쪽 ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, header[1], rect.getLeft(), rect.getTop(), 0); break; } // Watermark ColumnText.showTextAligned(writer.getDirectContentUnder(), Element.ALIGN_CENTER, new Phrase("CONFIDENTIAL DOCUMENT", FONT), // 워터마크로 넣을 텍스트 297.5f, 421, writer.getPageNumber() % 2 == 1 ? 45 : -45); // 쪽 번호 매기기 ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, new Phrase(String.format("%d", pagenumber)), // %d의 앞 뒤에 "-" 추가하면 "-1-" 이런 식.. (rect.getLeft() + rect.getRight()) / 2, rect.getBottom() - 18, 0); } }
그리고나서, PDF를 변환해주는 코드 부분에 아래 코드를 추가한다.
PdfPageEvent event = new PdfPageEvent(); // Pdf 속성 설정. writer.setBoxSize("boxName", new Rectangle(36, 54, 559, 788)); writer.setPageEvent(event);
속성 적용해주는 건 여기서 ☞ http://itextpdf.com/examples/iia.php?id=103 참고했음.
728x90반응형'java' 카테고리의 다른 글
Java - 문자열(String)에서 숫자(int)만 추출하는 방법 (0) 2022.08.17 Split a PDF file (using iText) (0) 2022.07.07 Guava 요약 4-Cache (0) 2022.05.24 Guava Cache 메모리 캐 시 사용 실천 - 정시 비동기 리 셋 및 단순 추상 패키지 (6) 2022.05.24 Guava Cache (구아바 캐시) (0) 2022.05.24