Coder Social home page Coder Social logo

jsp-fop's Introduction

jsp-fop

What is this?

The idea of jsp-fop is to provide a simple and fast reporting tool by combining JSP and XSL-FO (Apache FOP). This is JSP tag library designed in the sense that every jsp-fop tag/attribute corresponds to XSL-FO tag/attribute.

Who is this for?

This is for Java developers who are developing in Servlet environment and are required to create reports.

Minimum requirements

Java SE 7 or above.

How to use it?

Add following dependency in your web application's pom.xml file:

<dependency>
    <groupId>io.github.pcrnkovic</groupId>
    <artifactId>jsp-fop</artifactId>
    <version>0.9</version>
</dependency>

Use https://github.com/pcrnkovic/jsp-fop namespace in your JSP document/page. The example of JSP document is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="https://github.com/pcrnkovic/jsp-fop">

  <fo:layoutMasterSet>
    <fo:simplePageMaster masterName="pages">
      <fo:regionBody marginTop="20mm" marginBottom="3mm"/>
    </fo:simplePageMaster>
  </fo:layoutMasterSet>
  
  <fo:pageSequence masterReference="pages">
    <fo:flow flowName="xsl-region-body">
      <fo:block fontSize="20pt">Hello world!</fo:block>
    </fo:flow>
  </fo:pageSequence>
  
</fo:root>

The above JSP document will be transformed into valid XSL-FO document by Servlet container as follows:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.w3.org/1999/XSL/Format">

  <layout-master-set>
    <simple-page-master master-name="pages">
      <region-body margin-top="20mm" margin-bottom="3mm"/>
    </simple-page-master>
  </layout-master-set>
  
  <page-sequence master-reference="pages">
    <flow flow-name="xsl-region-body">
      <block font-size="20pt">Hello world!</block>
    </flow>
  </page-sequence>
  
</root>

As you can see from the above, every jsp-fop tag/attribute (xxxXxx) transforms into corresponding XSL-FO tag/attribute (xxx-xxx).

Attributes

Runtime expressions

Besides literal (and valid XSL-FO) values, jsp-fop tag attribute can also take runtime expressions (attributeName = "${rt_expression}"), which is the main reason why this library was created.

rendered

In addition to standard XSL-FO-corresponding attributes, every tag can take rendered attribute which takes literal/rtexpression boolean value (default is true). The purpose of rendered attribute is to determine whether tag will be included in XSL-FO output or not. For instance the result of the following JSP document

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="https://github.com/pcrnkovic/jsp-fop">

  <fo:layoutMasterSet>
    <fo:simplePageMaster masterName="pages">
      <fo:regionBody/>
    </fo:simplePageMaster>
  </fo:layoutMasterSet>
  
  <fo:pageSequence masterReference="pages">
    <fo:flow flowName="xsl-region-body">
      <fo:block>You will see this.</fo:block>
      <fo:block rendered="false">You will not see this.</fo:block>
    </fo:flow>
  </fo:pageSequence>
  
</fo:root>

will be

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.w3.org/1999/XSL/Format">
  <layout-master-set>
    <simple-page-master master-name="pages">
      <region-body/>
    </simple-page-master>
  </layout-master-set>
  <page-sequence master-reference="pages">
    <flow flow-name="xsl-region-body">
      <block>You will see this.</block>
    </flow>
  </page-sequence>
</root>

Iterable tags

According to W3C's recommendation of XSL 1.1, some XSL-FO tags can have multiple child tag of an exact one type. JSP-FOP counterparts of these tags are:

  • bookmarkTree
  • declarations
  • flowMap
  • flowSourceList
  • flowTargetList
  • listBlock
  • multiSwitch
  • repeatablePageMasterAlternatives
  • tableBody
  • tableFooter
  • tableHeader
  • tableRow

For instance, list-block can have at least one child of a type list-item. Each of their JSP-FOP counterparts can take 3 additional attributes: iterable, iterableVar and itemCountVar.

itemCountVar

Sets the name of a variable which is used to store current number of children. It can be used for numbering children. For instance, the following segment

<fo:listBlock itemCountVar="c">
	<fo:listItem>
		<fo:listItemLabel>${c}</fo:listItemLabel>
		<fo:listItemBody>First item.</fo:listItemBody>
	</fo:listItem>
	<fo:listItem>
		<fo:listItemLabel>${c}</fo:listItemLabel>
		<fo:listItemBody>Second item.</fo:listItemBody>
	</fo:listItem>
	<fo:listItem>
		<fo:listItemLabel>${c}</fo:listItemLabel>
		<fo:listItemBody>Third item.</fo:listItemBody>
	</fo:listItem>
</fo:listBlock>

will be evaluated to:

<list-block>
	<list-item>
		<list-item-label>1</list-item-label>
		<list-item-body>First item.</list-item-body>
	</list-item>
	<list-item>
		<list-item-label>2</list-item-label>
		<list-item-body>Second item.</list-item-body>
	</list-item>
	<list-item>
		<list-item-label>3</list-item-label>
		<list-item-body>Third item.</list-item-body>
	</list-item>
</list-block>

iterable and itemVar

Iterable tag can work in 2 modes, default mode and iterable mode. The latter one can be activated by setting both iterable and itemVar attribute values. The iterable takes runtime expression value which must be evaluated to non-null object of a type java.lang.Iterable, while the value of itemVar is the name of the variable used to store current item reference. Iterable tag in iterable mode evaluates it's body for each element found by Iterable's iterator. Let's assume you have list of person objects of a class like

public class Person {
	private final String name;
	private final int age;
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return this.name;
	}
	public int getAge() {
		return this.age;
	}
}

stored as a javax.servlet.ServletRequest attribute under name of personList and the entries (name (age)) in the list are Victor (20), Sandra (30) and Martin (40). The following segment

<fo:table>
	<fo:tableHeader>
		<fo:tableCell><fo:block>#</fo:block></fo:tableCell>
		<fo:tableCell><fo:block>Name</fo:block></fo:tableCell>
		<fo:tableCell><fo:block>Age</fo:block></fo:tableCell>
	</fo:tableHeader>
	<fo:tableBody iterable="${personList}" itemVar="p" itemCountVar="c">
		<fo:tableRow>
			<fo:tableCell><fo:block>${c}</fo:block></fo:tableCell>
			<fo:tableCell><fo:block>${p.name}</fo:block></fo:tableCell>
			<fo:tableCell><fo:block>${p.age}</fo:block></fo:tableCell>
		</fo:tableRow>
	</fo:tableBody>
</fo:table>

will be evaluated to

<table>
	<table-header>
		<table-cell><block>#</block></table-cell>
		<table-cell><block>Name</block></table-cell>
		<table-cell><block>Age</block></table-cell>
	</table-header>
	<table-body>
		<table-row>
			<table-cell><block>1</block></table-cell>
			<table-cell><block>Victor</block></table-cell>
			<table-cell><block>20</block></table-cell>
		</table-row>
		<table-row>
			<table-cell><block>2</block></table-cell>
			<table-cell><block>Sandra</block></table-cell>
			<table-cell><block>30</block></table-cell>
		</table-row>
		<table-row>
			<table-cell><block>3</block></table-cell>
			<table-cell><block>Martin</block></table-cell>
			<table-cell><block>40</block></table-cell>
		</table-row>
	</table-body>
</table>

PDF filter

Most likely, the report which is served to the end-user should be in human-readable format like PDF. This is the point where you might find 2 servlet filter classes defined in io.github.pcrnkovic.jspfop.filter package useful.

Default PDF filter (io.github.pcrnkovic.jspfop.filter.DefaultJspFopPdfFilter)

The easiest way to use default pdf filter is to add content like this to your web application web.xml file:

<filter>
  <filter-name>fop</filter-name>
  <filter-class>io.github.pcrnkovic.jspfop.filter.DefaultJspFopPdfFilter</filter-class>
</filter>
    
<filter-mapping>
  <filter-name>fop</filter-name>
  <url-pattern>/pdf/*</url-pattern>
</filter-mapping>

If you want to override default Apache FOP configuration file, use fop_config_path_param filter configuration parameter like this:

<filter>
  <filter-name>fop</filter-name>
  <filter-class>io.github.pcrnkovic.jspfop.filter.DefaultJspFopPdfFilter</filter-class>
  <init-param>
    <param-name>fop_config_path_param</param-name>
    <param-value>/WEB-CONTEXT-RELATIVE-PATH/TO/CONFIGURATION_XML</param-value>
  </init-param>
</filter>

Custom PDF filter (io.github.pcrnkovic.jspfop.filter.JspFopPdfFilter)

To make your custom pdf filter, you can extend JspFopPdfFilter class from io.github.pcrnkovic.jspfop.filter package. This is an abstract class with one abstract method:

protected abstract org.apache.fop.apps.FopFactory 
	acquireFopFactory(javax.servlet.FilterConfig config) throws ServletException;

This method is invoked during filter initialization and should be implemented in a way it never returns null. If for some reason FopFactory cannot be acquired, method should throw javax.servlet.ServletException.

jsp-fop's People

Contributors

pcrnkovic avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.