Bài tập IXJ – FO sử dụng Apache FOP chuyển XML sang PDF


XSL-FO (XSL Formatting Objects) chuyển đổi dữ liệu XML sang các định dạng khác.
XSL - FO
Trong bài thực hành này chúng ta sẽ sử dụng thư viện FOP của Apache tích hợp vào chương trình Java để chuyển tài liệu XML chứa CustomerOrders mua sản phẩm sang biểu mẩu PDF.

CustomerOrders

Snap 2015-09-21 at 13.34.42

Các thư viện hỗ trợ –>> đây

Mã nguồn tham khảo như sau:

package fop_ex;
import java.io.File;
import java.io.OutputStream;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
public class FOP_EX {
    public static void main(String[] args) {
        try {
            // Setup directories
            File baseDir = new File(".");
            File outDir = new File(baseDir, "src/out");
            outDir.mkdirs();
            // Setup input and output files
            File xmlfile = new File(baseDir, "src/xml/CustomerOrders.xml");
            File xsltfile = new File(baseDir, "src/xslt/Customer_fo.xsl");
            File pdffile = new File(outDir, "CustomerOrders.pdf");
            // configure fopFactory as desired
            final FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
            // configure foUserAgent as desired
            FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
            // Setup output
            OutputStream out = new java.io.FileOutputStream(pdffile);
            out = new java.io.BufferedOutputStream(out);
            try {
                // Construct fop with desired output format
                Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
                // Setup XSLT
                TransformerFactory factory = TransformerFactory.newInstance();
                Transformer transformer = factory.newTransformer(new StreamSource(xsltfile));
                // Set the value of a <param> in the stylesheet
                transformer.setParameter("author", "Nguyen Van Mit");
                // Setup input for XSLT transformation
                Source src = new StreamSource(xmlfile);
                // Resulting SAX events (the generated FO) must be piped through to FOP
                Result res = new SAXResult(fop.getDefaultHandler());
                // Start XSLT transformation and FOP processing
                transformer.transform(src, res);
            } finally {
                out.close();
            }
        } catch (Exception e) {
            e.printStackTrace(System.err);
            System.exit(-1);
        }
    }
}

File XSL-FO như sau:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo">
    <xsl:output method="xml" version="1.0" omit-xml-declaration="no" indent="yes"/>
    <xsl:param name="author" select="'Tran Van Cam'"/> 
    <xsl:template match="customers">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="simpleA4" page-height="29.7cm" page-width="21cm" margin-top="2cm" margin-bottom="2cm" margin-left="2cm" margin-right="2cm">
                    <fo:region-body/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="simpleA4">
                <fo:flow flow-name="xsl-region-body">
                    <fo:block font-size="16pt" text-align="center" font-weight="bold" space-after="5mm">CUSTOMER ORDER LIST<xsl:value-of select="customers"/>
                    </fo:block>
                    <fo:block font-size="12pt" text-align="center" space-after="5mm">----oOo----</fo:block>
                    <fo:block font-size="10pt">
                        <fo:table table-layout="fixed" width="100%"  
                                  border-collapse="separate" border="solid"
                                  border-separation="3pt">
                            <xsl:attribute-set name="table.cell.padding">
                                <xsl:attribute name="padding-left">2pt</xsl:attribute>
                                <xsl:attribute name="padding-right">2pt</xsl:attribute>
                                <xsl:attribute name="padding-top">2pt</xsl:attribute>
                                <xsl:attribute name="padding-bottom">2pt</xsl:attribute>
                            </xsl:attribute-set>
                            <fo:table-column column-width="2cm"/>
                            <fo:table-column column-width="5cm"/>
                            <fo:table-column column-width="5cm"/>
                            <fo:table-column column-width="2cm"/>
                            <fo:table-column column-width="3cm"/>
                            <fo:table-header>
                                <fo:table-row background-color="#0000FF" color="#FFFFFF">
                                    <fo:table-cell text-align="center">
                                        <fo:block>Order.</fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>Customer name</fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>Product name</fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell text-align="right">
                                        <fo:block>Quantity</fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell text-align="right">
                                        <fo:block>Price</fo:block>
                                    </fo:table-cell>
                                </fo:table-row>
                            </fo:table-header>                            
                            <fo:table-body>
                                <xsl:apply-templates select="customer"/>
                            </fo:table-body>
                        </fo:table>
                    </fo:block>
                    <fo:block font-size="12pt" text-align="right" space-before="1cm">Signature</fo:block>
                    <fo:block font-size="12pt" text-align="right" space-before="2cm" space-after="5mm"> <xsl:value-of select="$author"/> </fo:block>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>
    <xsl:template match="customer">         
        <xsl:variable name="bgclr">
            <xsl:choose>
                <xsl:when test="position() mod 2">#A7BFDE</xsl:when>
                <xsl:otherwise>#EDF2F8</xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <fo:table-row background-color="{$bgclr}">                      
            <xsl:if test="item='Laptop'">
                <xsl:attribute name="font-weight">bold</xsl:attribute>                
            </xsl:if>
            <fo:table-cell text-align="center">
                <fo:block>
                    <xsl:value-of select="position()" format="1."/>
                </fo:block>
            </fo:table-cell>
            <fo:table-cell>
                <fo:block>
                    <xsl:value-of select="name"/>
                </fo:block>
            </fo:table-cell>
            <fo:table-cell>
                <fo:block>
                    <xsl:value-of select="item"/>
                </fo:block>
            </fo:table-cell>
            <fo:table-cell text-align="right">
                <fo:block>
                    <xsl:value-of select="quantity"/>
                </fo:block>
            </fo:table-cell>
            <fo:table-cell text-align="right">
                <xsl:attribute name="font-weight">bold</xsl:attribute>
                <fo:block>
                    <xsl:value-of select="price"/>
                </fo:block>
            </fo:table-cell>
        </fo:table-row>
    </xsl:template>
</xsl:stylesheet>

Căn bản là vậy !!!

Advertisements

Phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s