티스토리 뷰

   iText라는 라이브러리를 사용했다.

 

 

 

   필요한 라이브러리 파일은 2개다.

 

- itextpdf (필자는 5.5.4 버전을 사용) http://sourceforge.net/projects/itext/

 

- xmlworker (5.5.4 버전 사용) http://sourceforge.net/projects/itextsharp/files/xmlworker/

 

 

 

 

 

 

itext-5.5.6.zip
다운로드

 

xmlworker-5.5.6.zip
다운로드

 

 

 

 

   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 참고했음.

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
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
글 보관함