본문 바로가기
슬기로운 자바 개발자 생활/Java more

자바 PDF 파일 만들기

by 슬기로운 동네 형 2022. 12. 20.
반응형

자바 PDF 파일 만들기


itextpdf 라이브러리를 사용해 자바로 PDF 파일을 만드는 예제를 포스팅한다.
쓸만한 PDF 문서를 만들기 위해서는 Css와 Html을 이용해야 한다.

요구사항.

  • 1. 데이터베이스에서 PDF로 만들어낼 자료를 준비.
  • 2. 데이터베이스에서 꺼낸 자료를 HTML 소스 형태 String 변환해서 변수에 저장해는다.
  • 3. 회사 로고나 PDF에 심을 이미지도 있다면 미리 준비.
  • 4. itextpdf로 pdf를 만들고 파일에 css를 먹이고, html 소스를 붙인다. 이미지도 잘 붙인다.
  • 5. 후작업으로 파일을 SMTP 메일 발송 또는 FTP 등의 작업으로 전달, 또는 특정 폴더에 생성

zip 파일명은 nettyDemo 지만 파일안에 포스팅에 사용된 소스가 첨부되어 있다.
소스는 인텔리j 로 만들기는 했지만 이클립스라고 크게 다르지 않다.
아래 jar들을 lib 잡고 코딩을 하면 된다. 소스는 알기 쉽게 스크립트 형식으로 만든 상태다.

itext라이브러리 jar

nettyDemo.zip
8.19MB

1. 준비물

회사 이미지 : ci_logo.jpg <스프링부트 로고임>

스프링 부트 로그

글꼴 : malgun.ttf

맑은 고딕 글꼴

Css : pdf.css

p {font-weight: bold;}
h3 {font-size: 15px; font-weight: bold; color: #0082E9; padding:10px 0 10px 0px; margin:0 10px;}

이미지, 글꼴, CSS 파일은 모두 프로젝트 디렉터리 하단에 위치

소스코드

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.css.CssFile;
import com.itextpdf.tool.xml.css.StyleAttrCSSResolver;
import com.itextpdf.tool.xml.html.CssAppliers;
import com.itextpdf.tool.xml.html.CssAppliersImpl;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.css.CSSResolver;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;

import java.io.*;
import java.nio.charset.Charset;

public class Main {


    public static final String SRC = "ex_springboot.pdf";
    public static final String IMG = "ci_logo.jpg";
    public static final String DESC = "springboot.pdf";

    public static void main(String[] args) {

        Document document = new Document(PageSize.A4, 50, 50, 50, 50); // 용지 및 여백 설정

        try{

            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(SRC)); //현재상대경로에 ex_springboot.pdf 생성
            writer.setInitialLeading(12.5f);

            document.open(); //생성된 파일을 오픈
            XMLWorkerHelper helper = XMLWorkerHelper.getInstance();

            // 사용할 CSS 를 준비한다.
            CSSResolver cssResolver = new StyleAttrCSSResolver();
            CssFile cssFile = null;
            try {
                cssFile = helper.getCSS(new FileInputStream("pdf.css"));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            cssResolver.addCss(cssFile);

            // HTML 과 폰트준비
            XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
            fontProvider.register("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>itextpdf 라이브러리를 사용해 pdf 파일을 만들어 봅니다.</p>"
                    + "<p>1. pdf 파일을 만들고</p>"
                    + "<p>2. css도 붙이고</p>"
                    + "<p>3. html을 만들어서 pdf에 쓰는 형태입니다.</p>"
                    + "</body></head></html>";

            StringReader strReader = new StringReader(htmlStr);
            xmlParser.parse(strReader);
            document.close();
            writer.close();

        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //PFD 파일에 이미지를 넣어본다.
        try {
            
            PdfReader reader = new PdfReader(SRC);
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(DESC));
            Image image = Image.getInstance(IMG);
            PdfImage stream = new PdfImage(image, "", null);

            stream.put(new PdfName("logo"), new PdfName("logo"));
            
            PdfIndirectObject ref = stamper.getWriter().addToBody(stream);
            image.setDirectReference(ref.getIndirectReference());
            image.setAbsolutePosition(20, 600);
            PdfContentByte over = stamper.getOverContent(1);

            over.addImage(image);
            stamper.close();
            reader.close();

        } catch (BadElementException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (BadPdfFormatException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}


소스설명
1. Document 객체는 pdf를 생성한다.
2. document.open() 메서드로 pdf 생성된 파일을 연다.
3. css 파일을 읽어 들이고 폰트 파일을 읽어 들이고 htmlpipline 객체를 생성해 pdf에 내용을 적는다.
4. 이미지는 stamper 객체를 사용해서 바디에 넣는다.
5. 최초 생성된 pdf 파일명은 예제 상으로 ex_springboot.pdf 이고 이미지를 씌운 pdf 최종 파일은. springboot.pdf 이 된다.

실행 결과

프로젝트 디렉터리 밑으로 생성.
반응형

댓글