Apache -FOPToPDF-Java对象输出实例代码

提示:此次文章主要记录关于使用FOP导出PDF的一个实例整理


前言

主要内容就是FOP的Example中的对象输出PDF

`提示:以下为实例中的代码和一部分注解

具体代码

1.pom.xml

代码如下(示例):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>Demo1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/fop -->
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>fop</artifactId>
            <version>2.7</version>
        </dependency>

    </dependencies>
</project>

2.AbstractObjectReader

代码如下(示例):



import org.xml.sax.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

//SAX

/**
 * This class can be used as base class for XMLReaders that generate SAX
 * events from Java objects.
 * 此类可用作生成 SAX 的 XML 读取器的基类来自 Java 对象的事件。
 * @author Administrator
 */
//抽象类只有被继承才可以使用

public abstract class AbstractObjectReader implements XMLReader {

    private static final String NAMESPACES =
            "http://xml.org/sax/features/namespaces";
    private static final String NS_PREFIXES =
            "http://xml.org/sax/features/namespace-prefixes";

    private Map features = new HashMap();
    private ContentHandler orgHandler;

    /** Proxy for easy SAX event generation */
    protected EasyGenerationContentHandlerProxy handler;
    /** Error handler */
    protected ErrorHandler errorHandler;
    //以上就是定义所需的一些方法名

    /**
     * Constructor for the AbstractObjectReader object
     * AbstractObjectReader对象的构造函数
     */
    public AbstractObjectReader() {
        setFeature(NAMESPACES, false);
        setFeature(NS_PREFIXES, false);
    }

    /* ============ XMLReader interface ============ */
    /* ============ XMLReader 接口 ==================*/

    /**
     * @see org.xml.sax.XMLReader#getContentHandler()
     * /@see可以实现跳转并且指向包.类等
     */
    @Override
    public ContentHandler getContentHandler() {
        return this.orgHandler;
    }
    //调用XMLReader中的getContentHandler进行重写
    //return this. 代表返回当前对象
    /**
     * @see org.xml.sax.XMLReader#setContentHandler(ContentHandler)
     */
    @Override
    public void setContentHandler(ContentHandler handler) {
        this.orgHandler = handler;
        this.handler = new EasyGenerationContentHandlerProxy(handler);
        //当前对象赋值
    }

    /**
     * @see org.xml.sax.XMLReader#getErrorHandler()
     */
    @Override
    public ErrorHandler getErrorHandler() {
        return this.errorHandler;
    }
    //错误处理器方法
    /**
     * @see org.xml.sax.XMLReader#setErrorHandler(ErrorHandler)
     */
    @Override
    public void setErrorHandler(ErrorHandler handler) {
        this.errorHandler = handler;
    }

    /**
     * @see org.xml.sax.XMLReader#getDTDHandler()
     */
    @Override
    public DTDHandler getDTDHandler() {
        return null;
    }

    /**
     * @see org.xml.sax.XMLReader#setDTDHandler(DTDHandler)
     */
    @Override
    public void setDTDHandler(DTDHandler handler) {
    }

    /**
     * @see org.xml.sax.XMLReader#getEntityResolver()
     */
    @Override
    public EntityResolver getEntityResolver() {
        return null;
    }

    /**
     * @see org.xml.sax.XMLReader#setEntityResolver(EntityResolver)
     */
    @Override
    public void setEntityResolver(EntityResolver resolver) {
    }

    /**
     * @see org.xml.sax.XMLReader#getProperty(String)
     */
    @Override
    public Object getProperty(String name) {
        return null;
    }

    /**
     * @see org.xml.sax.XMLReader#setProperty(String, Object)
     */
    @Override
    public void setProperty(String name, Object value) {
    }

    /**
     * @see org.xml.sax.XMLReader#getFeature(String)
     */
    @Override
    public boolean getFeature(String name) {
        return (Boolean) features.get(name);
    }

    /**
     * Returns true if the NAMESPACES feature is enabled.
     * 如果NAMESPACES功能启用那么就返回True
     * @return boolean true if enabled
     */
    protected boolean isNamespaces() {
        return getFeature(NAMESPACES);
    }

    /**
     * Returns true if the MS_PREFIXES feature is enabled.
     * 同上
     * @return boolean true if enabled
     */
    protected boolean isNamespacePrefixes() {
        return getFeature(NS_PREFIXES);
    }

    /**
     * @see org.xml.sax.XMLReader#setFeature(String, boolean)
     */
    @Override
    public void setFeature(String name, boolean value) {
        this.features.put(name, value);
    }

    /**
     * @see org.xml.sax.XMLReader#parse(String)
     */
    @Override
    public void parse(String systemId) throws IOException, SAXException {
        throw new SAXException(
                this.getClass().getName()
                        + " cannot be used with system identifiers (URIs)");
    }

    /**
     * @see org.xml.sax.XMLReader#parse(InputSource)
     */
    @Override
    public abstract void parse(InputSource input)
            throws IOException, SAXException;

}

3.EasyGenerationContentHandlerProxy

代码如下(示例):

//SAX
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

/**
 * This class is an implementation of ContentHandler which acts as a proxy to
 * another ContentHandler and has the purpose to provide a few handy methods
 * that make life easier when generating SAX events.
 * 此类是 ContentHandler 的实现,它充当另一个内容处理程序,目的是提供一些方便的方法在生成SAX事件时使生活更轻松。
 * <br>
 * Note: This class is only useful for simple cases with no namespaces.
 * 注意:此类仅对没有命名空间的简单情况有用。
 * @author Administrator
 */

public class EasyGenerationContentHandlerProxy implements ContentHandler {

    /* An empty Attributes object used when no attributes are needed. */
    /** 在不需要任何属性时使用的空属性对象*/
    public static final Attributes EMPTY_ATTS = new AttributesImpl();
    //私有变量target

    private ContentHandler target;


    /**
     * Main constructor.
     * 主构造
     * @param forwardTo ContentHandler to forward the SAX event to.
     */
    public EasyGenerationContentHandlerProxy(ContentHandler forwardTo) {
        this.target = forwardTo;
    }


    /**
     * Sends the notification of the beginning of an element.
     * 发送元素开始通知
     * @param name Name for the element.元素名称
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     * 任何的SAX异常都可能包含另一个异常
     */
    public void startElement(String name) throws SAXException {
        startElement(name, EMPTY_ATTS);
    }


    /**
     * Sends the notification of the beginning of an element.
     * @param name Name for the element.
     * @param atts The attributes attached to the element. If there are no
     * attributes, it shall be an empty Attributes object.附加到元素属性,如果没有属性那么应当是一个空属性对象
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     * 其余同上
     */

    //与上一个startElement看似是同样的命名,但其实是两种不同的方法,因为它里面的属性数量并不相同

    public void startElement(String name, Attributes atts) throws SAXException {
        startElement(null, name, name, atts);
    }
    /**
     * Send a String of character data.
     * 发送一个角色数据字符串
     * @param s The content String
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */



    public void characters(String s) throws SAXException {
        target.characters(s.toCharArray(), 0, s.length());
    }


    /**
     * Send the notification of the end of an element.
     * 发送元素结束信息
     * @param name Name for the element.
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void endElement(String name) throws SAXException {
        endElement(null, name, name);
        //方法
    }


    /**
     * Sends notifications for a whole element with some String content.
     * 发送包含某些字符串内容的整个元素的通知。
     * @param name Name for the element.
     * @param value Content of the element.
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, String value) throws SAXException {
        element(name, value, EMPTY_ATTS);
    }


    /**
     * Sends notifications for a whole element with some String content.
     * @param name Name for the element.
     * @param value Content of the element.
     * @param atts The attributes attached to the element. If there are no
     * attributes, it shall be an empty Attributes object.
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, String value, Attributes atts) throws SAXException {
        startElement(name, atts);
        if (value != null) {
            characters(value.toCharArray(), 0, value.length());
        }
        endElement(name);
    }

    /* =========== ContentHandler interface =========== */

    /**
     * @see org.xml.sax.ContentHandler#setDocumentLocator(Locator)
     */
    @Override
    public void setDocumentLocator(Locator locator) {
        target.setDocumentLocator(locator);
    }


    /**
     * @see org.xml.sax.ContentHandler#startDocument()
     */
    @Override
    public void startDocument() throws SAXException {
        target.startDocument();
    }


    /**
     * @see org.xml.sax.ContentHandler#endDocument()
     */
    @Override
    public void endDocument() throws SAXException {
        target.endDocument();
    }


    /**
     * @see org.xml.sax.ContentHandler#startPrefixMapping(String, String)
     */
    @Override
    public void startPrefixMapping(String prefix, String uri) throws SAXException {
        target.startPrefixMapping(prefix, uri);
    }


    /**
     * @see org.xml.sax.ContentHandler#endPrefixMapping(String)
     */
    @Override
    public void endPrefixMapping(String prefix) throws SAXException {
        target.endPrefixMapping(prefix);
    }


    /**
     * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
     */
    @Override
    public void startElement(String namespaceURI, String localName,
                             String qName, Attributes atts) throws SAXException {
        target.startElement(namespaceURI, localName, qName, atts);
    }


    /**
     * @see org.xml.sax.ContentHandler#endElement(String, String, String)
     */
    @Override
    public void endElement(String namespaceURI, String localName, String qName)
            throws SAXException {
        target.endElement(namespaceURI, localName, qName);
    }


    /**
     * @see org.xml.sax.ContentHandler#characters(char[], int, int)
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        target.characters(ch, start, length);
    }


    /**
     * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
     */
    @Override
    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
        target.ignorableWhitespace(ch, start, length);
    }


    /**
     * @see org.xml.sax.ContentHandler#processingInstruction(String, String)
     */
    @Override
    public void processingInstruction(String target, String data) throws SAXException {
        this.target.processingInstruction(target, data);
    }


    /**
     * @see org.xml.sax.ContentHandler#skippedEntity(String)
     */
    @Override
    public void skippedEntity(String name) throws SAXException {
        target.skippedEntity(name);
    }

}

4.ExampleObj2PDF

代码如下(示例):

import org.apache.fop.apps.*;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;

import javax.xml.transform.*;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;


public class ExampleObj2PDF {

    // configure fopFactory as desired
    private final FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());

    /**
     * Converts a ProjectTeam object to a PDF file.
     * @param team the ProjectTeam object
     * @param xslt the stylesheet file
     * @param pdf the target PDF file
     * @throws IOException In case of an I/O problem
     * @throws FOPException In case of a FOP problem
     * @throws TransformerException In case of a XSL transformation problem
     */
    public void convertProjectTeam2PDF(ProjectTeam team, File xslt, File pdf)
            throws IOException, FOPException, TransformerException, SAXNotRecognizedException, SAXNotSupportedException {

        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
        // configure foUserAgent as desired

        // Setup output
        OutputStream out = new java.io.FileOutputStream(pdf);
        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(xslt));

            // Setup input for XSLT transformation
            Source src = team.getSourceForProjectTeam();

            // 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();
        }
    }


    /**
     * Main method.
     * @param args command-line arguments
     */
    public static void main(String[] args) {
        try {
            System.out.println("FOP ExampleObj2PDF\n");
            System.out.println("Preparing...");

            // Setup directories
            File baseDir = new File(".");
            File outDir = new File(baseDir, "out");
            outDir.mkdirs();

            // Setup input and output
            File xsltfile = new File(baseDir, "projectteam2fo.xsl");
            File pdffile = new File(outDir, "ResultObj2PDF.pdf");

            System.out.println("Input: a ProjectTeam object");
            System.out.println("Stylesheet: " + xsltfile);
            System.out.println("Output: PDF (" + pdffile + ")");
            System.out.println();
            System.out.println("Transforming...");

            ExampleObj2PDF app = new ExampleObj2PDF();
            app.convertProjectTeam2PDF(ExampleObj2XML.createSampleProjectTeam(), xsltfile, pdffile);

            System.out.println("Success!");
        } catch (Exception e) {
            e.printStackTrace(System.err);
            System.exit(-1);
        }
    }
}

4.ExampleObj2XM

代码如下(示例):

//Hava
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;

import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;

//JAXP




/**
 * This class demonstrates the conversion of an arbitrary object file to an
 * XML file.
 */
public class ExampleObj2XML {

    /**
     * Converts a ProjectTeam object to XML.
     * @param team the ProjectTeam object
     * @param xml the target XML file
     * @throws IOException In case of an I/O problem
     * @throws TransformerException In case of a XSL transformation problem
     */
    public void convertProjectTeam2XML(ProjectTeam team, File xml)
            throws IOException, TransformerException, SAXNotRecognizedException, SAXNotSupportedException {

        //Setup XSLT
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer();
        /* Note:
           We use the identity transformer, no XSL transformation is done.
           The transformer is basically just used to serialize the
           generated document to XML. */

        //Setup input
        Source src = team.getSourceForProjectTeam();

        //Setup output
        Result res = new StreamResult(xml);

        //Start XSLT transformation
        transformer.transform(src, res);
    }


    /**
     * Creates a sample ProjectTeam instance for this demo.
     * @return ProjectTeam the newly created ProjectTeam instance
     */
    public static ProjectTeam createSampleProjectTeam() {
        ProjectTeam team = new ProjectTeam();
        team.setProjectName("Rule the Galaxy");
        team.addMember(new ProjectMember(
                "Emperor Palpatine", "lead", "palpatine@empire.gxy"));
        team.addMember(new ProjectMember(
                "Lord Darth Vader", "Jedi-Killer", "vader@empire.gxy"));
        team.addMember(new ProjectMember(
                "Grand Moff Tarkin", "Planet-Killer", "tarkin@empire.gxy"));
        team.addMember(new ProjectMember(
                "Admiral Motti", "Death Star operations", "motti@empire.gxy"));
        return team;
    }


    /**
     * Main method.
     * @param args command-line arguments
     */
    public static void main(String[] args) {
        try {
            System.out.println("FOP ExampleObj2XML\n");
            System.out.println("Preparing...");

            //Setup directories
            File baseDir = new File(".");
            File outDir = new File(baseDir, "out");
            outDir.mkdirs();

            //Setup input and output
            File xmlfile = new File(outDir, "ResultObj2XML.xml");

            System.out.println("Input: a ProjectTeam object");
            System.out.println("Output: XML (" + xmlfile + ")");
            System.out.println();
            System.out.println("Serializing...");

            ExampleObj2XML app = new ExampleObj2XML();
            app.convertProjectTeam2XML(createSampleProjectTeam(), xmlfile);

            System.out.println("Success!");
        } catch (Exception e) {
            e.printStackTrace(System.err);
            System.exit(-1);
        }
    }
}

5.ProjectMember

代码如下(示例):

/**
 * This bean represents a project member.
 */
public class ProjectMember {

    private String name;
    private String function;
    private String email;


    /**
     * Default no-parameter constructor.
     */
    public ProjectMember() {
    }


    /**
     * Convenience constructor.
     * @param name name of the project member
     * @param function function in the team
     * @param email email address
     */
    public ProjectMember(String name, String function, String email) {
        setName(name);
        setFunction(function);
        setEmail(email);
    }

    /**
     * Returns the name.
     * @return String the name
     */
    public String getName() {
        return name;
    }


    /**
     * Returns the function.
     * @return String the function
     */
    public String getFunction() {
        return function;
    }


    /**
     * Returns the email address.
     * @return String the email address
     */
    public String getEmail() {
        return email;
    }


    /**
     * Sets the name.
     * @param name The name to set
     */
    public void setName(String name) {
        this.name = name;
    }


    /**
     * Sets the function.
     * @param function The function to set
     */
    public void setFunction(String function) {
        this.function = function;
    }


    /**
     * Sets the email address.
     * @param email The email address to set
     */
    public void setEmail(String email) {
        this.email = email;
    }

}

6.ProjectTeam

代码如下(示例):

import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;

import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXSource;
import java.util.List;

/**
 * This bean represents a ProjectTeam.
 */
public class ProjectTeam {

    private String projectName;
    private List members = new java.util.ArrayList();


    /**
     * Returns a list of project members.
     * @return List a list of ProjectMember objects
     */
    public List getMembers() {
        return this.members;
    }


    /**
     * Adds a ProjectMember to this project team.
     * @param member the member to add
     */
    public void addMember(ProjectMember member) {
        this.members.add(member);
    }


    /**
     * Returns the name of the project
     * @return String the name of the project
     */
    public String getProjectName() {
        return projectName;
    }


    /**
     * Sets the name of the project.
     * @param projectName the project name to set
     */
    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }


    /**
     * Resturns a Source object for this object so it can be used as input for
     * a JAXP transformation.
     * @return Source The Source object
     */
    public Source getSourceForProjectTeam() throws SAXNotRecognizedException, SAXNotSupportedException {
        return new SAXSource(new ProjectTeamXMLReader(),
                new ProjectTeamInputSource(this));
    }


}

7.ProjectTeamInputSource

代码如下(示例):


import org.xml.sax.InputSource;

/**
 * This class is a special InputSource decendant for using ProjectTeam
 * instances as XML sources.
 */
public class ProjectTeamInputSource extends InputSource {

    private ProjectTeam projectTeam;

    /**
     * Constructor for the ProjectTeamInputSource
     * @param projectTeam The ProjectTeam object to use
     */
    public ProjectTeamInputSource(ProjectTeam projectTeam) {
        this.projectTeam = projectTeam;
    }

    /**
     * Returns the projectTeam.
     * @return ProjectTeam
     */
    public ProjectTeam getProjectTeam() {
        return projectTeam;
    }

    /**
     * Sets the projectTeam.
     * @param projectTeam The projectTeam to set
     */
    public void setProjectTeam(ProjectTeam projectTeam) {
        this.projectTeam = projectTeam;
    }

}

8.ProjectTeamXMLReader

代码如下(示例):

//Java
import org.xml.sax.DTDHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import java.io.IOException;

//SAX



/**
 * XMLReader implementation for the ProjectTeam class. This class is used to
 * generate SAX events from the ProjectTeam class.
 */
public class ProjectTeamXMLReader extends AbstractObjectReader {

    @Override
    public DTDHandler getDTDHandler() {
        return super.getDTDHandler();
    }

    /**
     * @see org.xml.sax.XMLReader#parse(InputSource)
     */
    @Override
    public void parse(InputSource input) throws IOException, SAXException {
        if (input instanceof ProjectTeamInputSource) {
            parse(((ProjectTeamInputSource)input).getProjectTeam());
        } else {
            throw new SAXException("Unsupported InputSource specified. "
                    + "Must be a ProjectTeamInputSource");
        }
    }


    /**
     * Starts parsing the ProjectTeam object.
     * @param projectTeam The object to parse
     * @throws SAXException In case of a problem during SAX event generation
     */
    public void parse(ProjectTeam projectTeam) throws SAXException {
        if (projectTeam == null) {
            throw new NullPointerException("Parameter projectTeam must not be null");
        }
        if (handler == null) {
            throw new IllegalStateException("ContentHandler not set");
        }

        //Start the document
        handler.startDocument();

        //Generate SAX events for the ProjectTeam
        generateFor(projectTeam);

        //End the document
        handler.endDocument();
    }


    /**
     * Generates SAX events for a ProjectTeam object.
     * @param projectTeam ProjectTeam object to use
     * @throws SAXException In case of a problem during SAX event generation
     */
    protected void generateFor(ProjectTeam projectTeam) throws SAXException {
        if (projectTeam == null) {
            throw new NullPointerException("Parameter projectTeam must not be null");
        }
        if (handler == null) {
            throw new IllegalStateException("ContentHandler not set");
        }

        handler.startElement("projectteam");
        handler.element("projectname", projectTeam.getProjectName());
        for (Object o : projectTeam.getMembers()) {
            ProjectMember member = (ProjectMember) o;
            generateFor(member);
        }
        handler.endElement("projectteam");
    }

    /**
     * Generates SAX events for a ProjectMember object.
     * @param projectMember ProjectMember object to use
     * @throws SAXException In case of a problem during SAX event generation
     */
    protected void generateFor(ProjectMember projectMember) throws SAXException {
        if (projectMember == null) {
            throw new NullPointerException("Parameter projectMember must not be null");
        }
        if (handler == null) {
            throw new IllegalStateException("ContentHandler not set");
        }

        handler.startElement("member");
        handler.element("name", projectMember.getName());
        handler.element("function", projectMember.getFunction());
        handler.element("email", projectMember.getEmail());
        handler.endElement("member");
    }

}

9.projectteam2fo.xsl

代码如下(示例):

<?xml version="1.0" encoding="UTF-8"?>

<!-- $Id$ -->
<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="versionParam" select="'1.0'"/> 
  <!-- ========================= -->
  <!-- root element: projectteam -->
  <!-- ========================= -->
  <xsl:template match="projectteam">
    <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" font-weight="bold" space-after="5mm">Project: <xsl:value-of select="projectname"/>
          </fo:block>
          <fo:block font-size="12pt" space-after="5mm">Version <xsl:value-of select="$versionParam"/>
          </fo:block>
          <fo:block font-size="10pt">
            <fo:table table-layout="fixed" width="100%" border-collapse="separate">
              <fo:table-column column-width="4cm"/>
              <fo:table-column column-width="4cm"/>
              <fo:table-column column-width="5cm"/>
              <fo:table-body>
                <xsl:apply-templates select="member"/>
              </fo:table-body>
            </fo:table>
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>
  <!-- ========================= -->
  <!-- child element: member     -->
  <!-- ========================= -->
  <xsl:template match="member">
    <fo:table-row>
      <xsl:if test="function = 'lead'">
        <xsl:attribute name="font-weight">bold</xsl:attribute>
      </xsl:if>
      <fo:table-cell>
        <fo:block>
          <xsl:value-of select="name"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell>
        <fo:block>
          <xsl:value-of select="function"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell>
        <fo:block>
          <xsl:value-of select="email"/>
        </fo:block>
      </fo:table-cell>
    </fo:table-row>
  </xsl:template>
</xsl:stylesheet>

总结

以上就是本次PDF输出功能的实例代码(其实就是一次样例的整理和学习),希望大家可以一起讨论学习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值