io.github.pcrnkovic:jsp-fop

The idea of jsp-fop is to provide a simple and fast reporting tool by combining JSP and XSL-FO (Apache FOP).

License

License

Categories

Categories

Jakarta Server Pages Jakarta EE The Web Tier Crnk Program Interface REST Frameworks
GroupId

GroupId

io.github.pcrnkovic
ArtifactId

ArtifactId

jsp-fop
Last Version

Last Version

0.9
Release Date

Release Date

Type

Type

jar
Description

Description

io.github.pcrnkovic:jsp-fop
The idea of jsp-fop is to provide a simple and fast reporting tool by combining JSP and XSL-FO (Apache FOP).
Project URL

Project URL

https://github.com/pcrnkovic/jsp-fop
Source Code Management

Source Code Management

https://github.com/pcrnkovic/jsp-fop

Download jsp-fop

How to add to project

<!-- https://jarcasting.com/artifacts/io.github.pcrnkovic/jsp-fop/ -->
<dependency>
    <groupId>io.github.pcrnkovic</groupId>
    <artifactId>jsp-fop</artifactId>
    <version>0.9</version>
</dependency>
// https://jarcasting.com/artifacts/io.github.pcrnkovic/jsp-fop/
implementation 'io.github.pcrnkovic:jsp-fop:0.9'
// https://jarcasting.com/artifacts/io.github.pcrnkovic/jsp-fop/
implementation ("io.github.pcrnkovic:jsp-fop:0.9")
'io.github.pcrnkovic:jsp-fop:jar:0.9'
<dependency org="io.github.pcrnkovic" name="jsp-fop" rev="0.9">
  <artifact name="jsp-fop" type="jar" />
</dependency>
@Grapes(
@Grab(group='io.github.pcrnkovic', module='jsp-fop', version='0.9')
)
libraryDependencies += "io.github.pcrnkovic" % "jsp-fop" % "0.9"
[io.github.pcrnkovic/jsp-fop "0.9"]

Dependencies

compile (1)

Group / Artifact Type Version
org.apache.xmlgraphics : fop jar 2.5

provided (2)

Group / Artifact Type Version
javax.servlet.jsp : javax.servlet.jsp-api jar 2.2.1
javax.servlet : javax.servlet-api jar 3.0.1

Project Modules

There are no modules declared in this project.

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.

Versions

Version
0.9
0.8
0.7
0.6