기본 콘텐츠로 건너뛰기

xsl-fo를 이용한 pdf 생성기술


1. PDF 생성 기술 개발을 위해 적용가능한 오픈소스

1) pdfbox
- http://pdfbox.apache.org/
- License : Apache License Version 2.0

2) iText
- http://itextpdf.com/
- License : APGL License

3) Apache FOP
- http://xmlgraphics.apache.org/fop/

-> 유지보수 비용은 높지만, 무료이며 한글이 출력 가능한 Apache FOP를 적용

2. XSL-FO를 이용하여 PDF를 어떻게 생성 하는지 설명



* XSL-FO의 기본 프로세스

용어 설명

1) XSLT
- XML 문서를 다른 XML 문서로 변환하는데 사용하는 XML 기반의 언어
- 원본 문서는 변경되지 않으며, 원본 문서를 기반으로 새로운 문서를 생성

2) XSL-FO
- XSL-FO는 종이, 화면 등 다양한 매체에 출력 하기 위한 XML 기반의 마크업 언어
- 사용자는 XSL-FO를 통해 어떻게 정보가 PDF에 출력되는지 확인 가능

3) XSL-FO Formatter
- XSL-FO 문서를 최종 결과물인 PDF(다른 매체도 가능)문서로 변환할 수 있는 Formatter

간략하게 애기하면, XSL-FO를 Formatter로 변환하게 되면 PDF가 생성되며, XSL-FO는 사용자가 직접 작성할 수도 있고 XML source와 XSLT stylesheet를 이용하여 동적으로 생성 가능하다.

3. 간단한 예제로 정리

1) 필요한 데이터를 XML에 기술한다.

XML file 

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <name>홍길동</name>
</root>
  
2) XSLT stylesheet를 이용하여 XML 데이터를 변환(XSLT-engine) 하면 XSL-FO가 생성된다.

XSLT stylesheet file 

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
     <xsl:output method="xml" indent="yes" />
     <xsl:template match="/">
     ... 중략 ...
          <fo:block space-before="12pt" space-after="12pt" font-family="NanumGothic">
               Hello, <xsl:value-of select="root/name" />     !
           </fo:block>             
     ... 중략 ...   
     </xsl:template>
</xsl:stylesheet>

<xsl:value-of> 엘리먼트는 특정 엘리먼트의 값을 얻을때 사용한다.
root/name은 XPath 표현식이며, 의미는 root 엘리먼트 아래에 있는 모든 name 엘리먼트를 선택한다.
변환시 <xsl:value-of select="root/name" />을 사용하여 XML 문서에 '홍길동'을 얻을 수 있다.

XPath를 이용하면 XML 데이터의 특정 엘리먼트, 어트리뷰트 등 접근 할 수 있다.
XSLT를 이용하면 특정 엘리먼트를  추출(value-of), 비교(if, choose), 루프(for-each) 등 조작 할 수 있다.

3) 생성된 XSL-FO를 Formatter를 이용하여 PDF 문서로 변환 시킨다.

XSL-FO file

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
     <fo:layout-master-set>
     <fo:simple-page-master margin="2cm" page-width="21.0cm" page-height="29.7cm" master-name="A4-portrait">
          <fo:region-body/>
     </fo:simple-page-master>
     </fo:layout-master-set>
     <fo:page-sequence master-reference="A4-portrait">
          <fo:flow flow-name="xsl-region-body">
               <fo:block font-family="NanumGothic" space-after="12pt" space-before="12pt">
                     Hello, 홍길동     !
               </fo:block>
          </fo:flow>
        </fo:page-sequence>
</fo:root>

PDF 생성 기술의 핵심은 표준 포맷의 XML을 정의하고 어떤 데이터를 입력하더라도 일정 포맷의 XSL-FO를 생성 하는 것이며 이렇게 하면 동적인 데이터를 갖는 일정 포맷의 PDF를 생성하는 것을 자동화 할 수 있다.

만약 입력 데이터가 '홍길동'이 아닌 다른 데이터로 위 과정을 반복하면 같은 포맷의 다른 PDF를 생성할 수 있다.


4. Reference

1) Apache FOP
 - http://xmlgraphics.apache.org/fop/        
3) XSLT 문법
4) XPath 문법 

댓글

이 블로그의 인기 게시물

[JPA] deleted instance passed to merge

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.ObjectDeletedException:   deleted instance passed to merge: 위와 같은 에러가 발생... em.remove(user)를 호출하면 user는 영속성 컨텍스트에서 제거된다. (Object is already marked for being deleted) 이후 트랜잭션을 커믹해서 플러시를 호출하면 실제 데이터베이스에 삭제 쿼리를 전달한다. 하지만 삭제된 엔티티를 한 트랜잭션내에서 다시 삭제할려고하면 해당 익셉션이 발생한다. 참조 : 자바 ORM 표준 JPA 프로그래밍

Spring Redis Cluster Configuration

# build.gradle compile  'org.springframework.data:spring-data-redis' compile  'biz.paluch.redis:lettuce:4.5.0.Final' #RedisConfiguration @Configuration @ EnableRedisRepositories ( basePackageClasses  = { MyAppDomains. class  }) public class  RedisConfiguration {      @Value ( "${spring.redis.host}" )      private  String  redisHost ;      @Value ( "${spring.redis.port}" )      private int  redisPort ;      @Bean          public  RedisConnectionFactory  myRedisConnectionFactory () {         RedisClusterConfiguration clusterConfig =  new  RedisClusterConfiguration() ;          clusterConfig.clusterNode( redisHost ,  redisPort ) ;         re...