LanguagesXMLImplementing XSL-Formatting Objects

Implementing XSL-Formatting Objects

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Everyone loves a well-designed Web page, but I hope you never tried to print one and found out that it resulted in a big mess and maybe some unhappy users. There are many technologies that you can use to solve this problem, but the majority of them require spending some money and time.

Today we are going to talk about the FOP (http://xml.apache.org/fop) Formatting Objects Processor. You can download the code from the Web site free of charge, but it requires some time to learn how to use it and how to create good solutions. Essentially, FOP is based on the W3C recommendation http://www.w3.org/TR/2001/REC-xsl-20011015/.

The best way to learn how to use FOP is to create a sample. For example, let’s imagine that we need to generate a PDF file with the price list of the ACME Corporation. It should look like the following:

First of all, we need to start our document as follows:

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

<fo:root xmlns_fo="http://www.w3.org/1999/XSL/Format">

This helps us to define the correct namespace (http://www.w3.org/TR/REC-xml-names/) that we need to use.

After that, we will need to define the size of the output page that we want to use.

  <!-- defines page layout -->
  <fo:layout-master-set>
    <!-- layout for the first page -->
    <fo:simple-page-master master-name="first"
                  page-height="29.7cm"
                  page-width="21cm"
                  margin-top="1cm"
                  margin-bottom="2cm"
                  margin-left="2.5cm"
                  margin-right="2.5cm">
      <fo:region-body margin-top="3cm"/>
    </fo:simple-page-master>
  </fo:layout-master-set>
  <!-- end: defines page layout -->

With this information available, we just create a standard, letter-sized page. After this, we need to create a section with the actual layout of the document that we need to generate.

  <fo:page-sequence master-reference="first" initial-page-number="1">
    <fo:flow flow-name="xsl-region-body">

This statement will match with the layout defined above and it will set the page number to 1. To print out any message, we need to define <fo:block>.

      <fo:block font-size="18pt"
                font-family="sans-serif"
                line-height="24pt"
                space-after.optimum="15pt"
                background-color="blue"
                color="white"
                text-align="center"
                padding-top="0pt">
       Implementing FOP
      </fo:block>

This block will generate a 24pt line with blue background and white letters, centered, and with the title Implementing FOP.

Now, let’s include a table with the products’ numbers, descriptions, and prices. This is the header of the table:

<fo:table table-layout="fixed" >
  <fo:table-column column-width="5cm"/>
  <fo:table-column column-width="7cm"/>
  <fo:table-column column-width="2cm"/>
  <fo:table-body>
  <fo:table-row>
      <fo:table-cell>
        <fo:block font-family="sans-serif" font-size="10pt"
                  background-color="gray">
        Product Number
        </fo:block>
      </fo:table-cell>
      <fo:table-cell>
        <fo:block font-family="sans-serif" font-size="10pt"
                  background-color="gray">
        Description
        </fo:block>
      </fo:table-cell>
      <fo:table-cell>
        <fo:block font-family="sans-serif" font-size="10pt"
                  background-color="gray">
        Price
        </fo:block>
      </fo:table-cell>
      </fo:table-row>

One important issue is that we need to include a prefixed size of the column. Right now, FOP does not allow you to define automatic layouts.

      <fo:table-row>
        <fo:table-cell>
          <fo:block></fo:block>
        </fo:table-cell>
</fo:table-row>

We use the same approach as HTML by using <tr><td></td></tr>. Here is how it looks after we include the table.

***************************sample.fo *********************************
<?xml version="1.0" encoding="utf-8"?>
<fo:root xmlns_fo="http://www.w3.org/1999/XSL/Format">
  <!-- defines page layout -->
  <fo:layout-master-set>
    <!-- layout for the first page -->
    <fo:simple-page-master master-name="first" page-height="29.7cm"
        page-width="21cm" margin-top="1cm" margin-bottom="2cm"
        margin-left="2.5cm" margin-right="2.5cm">
      <fo:region-body margin-top="3cm"/>
    </fo:simple-page-master>
  </fo:layout-master-set>
  <!-- end: defines page layout -->
  <!-- actual layout -->
  <fo:page-sequence master-reference="first" initial-page-number="1">
    <fo:flow flow-name="xsl-region-body">
      <!-- defines text title level 1-->
      <fo:block font-size="18pt" font-family="sans-serif"
          line-height="24pt" space-after.optimum="15pt"
          background-color="blue" color="white" text-align="center"
          padding-top="0pt">
      ACME Corporation
      </fo:block>
      <fo:table table-layout="fixed" >
        <fo:table-column column-width="5cm"/>
        <fo:table-column column-width="7cm"/>
        <fo:table-column column-width="2cm"/>
        <fo:table-body>
          <fo:table-row>
            <fo:table-cell>
              <fo:block font-family="sans-serif" font-size="10pt"
                        background-color="gray">
              Product Number
              </fo:block>
            </fo:table-cell>
            <fo:table-cell>
              <fo:block font-family="sans-serif" font-size="10pt"
                        background-color="gray">
              Description
              </fo:block>
            </fo:table-cell>
            <fo:table-cell>
              <fo:block font-family="sans-serif"
                        font-size="10pt" background-color="gray">
              Price
              </fo:block>
            </fo:table-cell>
          </fo:table-row>
          <fo:table-row>
            <fo:table-cell>
              <fo:block font-family="sans-serif" font-size="10pt">
              12345
              </fo:block>
            </fo:table-cell>
            <fo:table-cell>
              <fo:block font-family="sans-serif" font-size="10pt">
              Rocket
              </fo:block>
            </fo:table-cell>
            <fo:table-cell>
              <fo:block font-family="sans-serif"
                        font-size="10pt" text-align="right">
              $250.00
              </fo:block>
            </fo:table-cell>
          </fo:table-row>
          <fo:table-row>
            <fo:table-cell>
              <fo:block font-family="sans-serif" font-size="10pt">
              67890
              </fo:block>
            </fo:table-cell>
            <fo:table-cell>
              <fo:block font-family="sans-serif" font-size="10pt">
              TNT
              </fo:block>
            </fo:table-cell>
            <fo:table-cell>
              <fo:block font-family="sans-serif" font-size="10pt"
                        text-align="right">
              $120.00
              </fo:block>
            </fo:table-cell>
          </fo:table-row>
          <fo:table-row>
            <fo:table-cell>
              <fo:block font-family="sans-serif" font-size="10pt">
              11223344
              </fo:block>
            </fo:table-cell>
            <fo:table-cell>
              <fo:block font-family="sans-serif" font-size="10pt">
              Anvil
              </fo:block>
            </fo:table-cell>
            <fo:table-cell>
              <fo:block font-family="sans-serif" font-size="10pt"
                        text-align="right">
              $50.00
              </fo:block>
            </fo:table-cell>
          </fo:table-row>
        </fo:table-body>
      </fo:table>
    </fo:flow>
  </fo:page-sequence>
</fo:root>
***************************sample.fo *********************************

To test it, we need to run it using the command prompt. From the fop directory, type Fop.bat sample.fo sample.pdf. If everything is set correctly, this operation should generate a PDF file named sample.pdf. Open the file sample.pdf from Acrobat Reader and you should see something like the figure above.

References

Reference for XSL-FO:
Apache FOP project
http://xml.apache.org/fop
Java implementation

RenderX
Commercial solution for XSL-FO Implementation
http://www.renderx.com/
Java

XMLSpy
XML editor that includes fo tags—really easy to use.
http://www.xmlspy.com/

About the Author

Gerardo Garcia works as a Technical Specialist with Spherion Corporation. His areas of interest include Java, XML, and Web- enabled applications. You can contact him at GerardoGarcia@spherion.com.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories