blob: a0e6ce408467ebd499e0c0906adec24942728f0d [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="Date-Revision-yyyymmdd" content="20140918"/>
<meta http-equiv="Content-Language" content="en"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Getting started</title>
<link href="//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,400italic,600italic,700italic" rel="stylesheet" type="text/css">
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link href="/css/main.css" rel="stylesheet">
<link href="/css/custom.css" rel="stylesheet">
<link href="/css/syntax.css" rel="stylesheet">
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="/bootstrap/js/bootstrap.js"></script>
<script type="text/javascript" src="/js/community.js"></script>
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
/* We explicitly disable cookie tracking to avoid privacy issues */
_paq.push(['disableCookies']);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//analytics.apache.org/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '41']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head>
<body>
<a href="https://github.com/apache/struts" class="github-ribbon">
<img decoding="async" loading="lazy" style="position: absolute; right: 0; border: 0;" width="149" height="149" src="https://github.blog/wp-content/uploads/2008/12/forkme_right_red_aa0000.png?resize=149%2C149" class="attachment-full size-full" alt="Fork me on GitHub" data-recalc-dims="1">
</a>
<header>
<nav>
<div role="navigation" class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" data-toggle="collapse" data-target="#struts-menu" class="navbar-toggle">
Menu
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="/index.html" class="navbar-brand logo"><img src="/img/struts-logo.svg"></a>
</div>
<div id="struts-menu" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Home<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/index.html">Welcome</a></li>
<li><a href="/download.cgi">Download</a></li>
<li><a href="/releases.html">Releases</a></li>
<li><a href="/announce-2024.html">Announcements</a></li>
<li><a href="http://www.apache.org/licenses/">License</a></li>
<li><a href="https://www.apache.org/foundation/thanks.html">Thanks!</a></li>
<li><a href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
<li><a href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy Policy</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Support<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/mail.html">User Mailing List</a></li>
<li><a href="https://issues.apache.org/jira/browse/WW">Issue Tracker</a></li>
<li><a href="/security.html">Reporting Security Issues</a></li>
<li><a href="/commercial-support.html">Commercial Support</a></li>
<li class="divider"></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Migration+Guide">Version Notes</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Security+Bulletins">Security Bulletins</a></li>
<li class="divider"></li>
<li><a href="/maven/project-info.html">Maven Project Info</a></li>
<li><a href="/maven/struts2-core/dependencies.html">Struts Core Dependencies</a></li>
<li><a href="/maven/struts2-plugins/modules.html">Plugin Dependencies</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Documentation<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/birdseye.html">Birds Eye</a></li>
<li><a href="/primer.html">Key Technologies</a></li>
<li><a href="/kickstart.html">Kickstart FAQ</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Home">Wiki</a></li>
<li class="divider"></li>
<li><a href="/getting-started/">Getting Started</a></li>
<li><a href="/security/">Security Guide</a></li>
<li><a href="/core-developers/">Core Developers Guide</a></li>
<li><a href="/tag-developers/">Tag Developers Guide</a></li>
<li><a href="/maven-archetypes/">Maven Archetypes</a></li>
<li><a href="/plugins/">Plugins</a></li>
<li><a href="/maven/struts2-core/apidocs/index.html">Struts Core API</a></li>
<li><a href="/tag-developers/tag-reference.html">Tag reference</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/FAQs">FAQs</a></li>
<li><a href="http://cwiki.apache.org/S2PLUGINS/home.html">Plugin registry</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Contributing<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/youatstruts.html">You at Struts</a></li>
<li><a href="/helping.html">How to Help FAQ</a></li>
<li><a href="/dev-mail.html">Development Lists</a></li>
<li class="divider"></li>
<li><a href="/submitting-patches.html">Submitting patches</a></li>
<li><a href="/builds.html">Source Code and Builds</a></li>
<li><a href="/coding-standards.html">Coding standards</a></li>
<li><a href="/contributors/">Contributors Guide</a></li>
<li class="divider"></li>
<li><a href="/release-guidelines.html">Release Guidelines</a></li>
<li><a href="/bylaws.html">PMC Charter</a></li>
<li><a href="/volunteers.html">Volunteers</a></li>
<li><a href="https://gitbox.apache.org/repos/asf?p=struts.git">Source Repository</a></li>
<li><a href="/updating-website.html">Updating the website</a></li>
</ul>
</li>
<li class="apache"><a href="http://www.apache.org/"><img src="/img/apache.png"></a></li>
</ul>
</div>
</div>
</div>
</nav>
</header>
<article class="container">
<section class="col-md-12">
<a class="edit-on-gh" href="https://github.com/apache/struts-site/edit/master/source/getting-started/jasper-reports-tutorial.md" title="Edit this page on GitHub">Edit on GitHub</a>
<a href="index.html" title="back to Getting started"><< back to Getting started</a>
<h1 class="no_toc" id="jasperreports-tutorial">JasperReports Tutorial</h1>
<ul id="markdown-toc">
<li><a href="#our-person-class" id="markdown-toc-our-person-class">Our Person class</a></li>
<li><a href="#jasperreports-libraries" id="markdown-toc-jasperreports-libraries">JasperReports libraries</a></li>
<li><a href="#creating-the-action" id="markdown-toc-creating-the-action">Creating the Action</a></li>
<li><a href="#our-jasper-template" id="markdown-toc-our-jasper-template">Our Jasper template</a> <ul>
<li><a href="#registering-the-action" id="markdown-toc-registering-the-action">Registering the Action</a></li>
<li><a href="#conclusion" id="markdown-toc-conclusion">Conclusion</a></li>
</ul>
</li>
</ul>
<p>The Struts 2 JasperReports plugin is a bridge from Struts 2 to JasperReports and does not include JasperReports itself,
which must be downloaded separately.</p>
<p><a href="http://jasperreports.sourceforge.net">JasperReports</a> is one of the leading open-source Java reporting libraries.
It compiles <code class="language-plaintext highlighter-rouge">.jrxml</code> (XML source) to <code class="language-plaintext highlighter-rouge">.jasper</code> (compiled) files, which in turn can be transformed into several output
types including PDF, HTML, CSV, and XLS.</p>
<p>In the following example, we will use the framework to create a PDF with a list of persons. Our action will be used
to create a List with <code class="language-plaintext highlighter-rouge">Person</code> objects, and our JasperReports Result will use this list to fill our template, and return
the PDF.</p>
<h2 id="our-person-class">Our Person class</h2>
<p>We start by defining a simple <code class="language-plaintext highlighter-rouge">Person</code> POJO class.</p>
<p><strong>com.acme.test.Person.java</strong></p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">com.acme.test</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Person</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">Long</span> <span class="n">id</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">name</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">lastName</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">Person</span><span class="o">()</span> <span class="o">{</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nf">Person</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">,</span> <span class="nc">String</span> <span class="n">lastName</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">lastName</span> <span class="o">=</span> <span class="n">lastName</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nf">Person</span><span class="o">(</span><span class="nc">Long</span> <span class="n">id</span><span class="o">,</span> <span class="nc">String</span> <span class="n">name</span><span class="o">,</span> <span class="nc">String</span> <span class="n">lastName</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">id</span> <span class="o">=</span> <span class="n">id</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">lastName</span> <span class="o">=</span> <span class="n">lastName</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">Long</span> <span class="nf">getId</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">id</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setId</span><span class="o">(</span><span class="nc">Long</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">id</span> <span class="o">=</span> <span class="n">id</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getLastName</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">lastName</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setLastName</span><span class="o">(</span><span class="nc">String</span> <span class="n">lastName</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">lastName</span> <span class="o">=</span> <span class="n">lastName</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setName</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h2 id="jasperreports-libraries">JasperReports libraries</h2>
<p>Before we can continue, we need to add the JR libraries to our classpath. You can download the JR project here:
<a href="http://www.sourceforge.net/projects/jasperreports">http://www.sourceforge.net/projects/jasperreports</a></p>
<p>Save the <code class="language-plaintext highlighter-rouge">jasperreports-X-project.zip</code> to your harddisk, and extract the files.</p>
<p>We need the following files:</p>
<ul>
<li>dist/jasperreports-X.jar</li>
<li>lib/commons-*.jar (all the commons - except maybe for commons-logging)</li>
<li>lib/itext-X.jar</li>
<li>lib/jdt-compiler.jar</li>
</ul>
<p>Copy these jars over to your <code class="language-plaintext highlighter-rouge">S2_WABAPP/WEB-INF/lib</code> directory, and add them to your classpath.</p>
<h1 id="creating-the-action">Creating the Action</h1>
<p><strong>com.acme.test.action.JasperAction</strong></p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">com.acme.test.action</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.ArrayList</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.List</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">net.sf.jasperreports.engine.JasperCompileManager</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.acme.test.Person</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.opensymphony.xwork.ActionSupport</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">JasperAction</span> <span class="kd">extends</span> <span class="nc">ActionSupport</span> <span class="o">{</span>
<span class="cm">/** List to use as our JasperReports dataSource. */</span>
<span class="kd">private</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Person</span><span class="o">&gt;</span> <span class="n">myList</span><span class="o">;</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">execute</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
<span class="c1">// Create some imaginary persons.</span>
<span class="nc">Person</span> <span class="n">p1</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span><span class="k">new</span> <span class="nc">Long</span><span class="o">(</span><span class="mi">1</span><span class="o">),</span> <span class="s">"Patrick"</span><span class="o">,</span> <span class="s">"Lightbuddie"</span><span class="o">);</span>
<span class="nc">Person</span> <span class="n">p2</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span><span class="k">new</span> <span class="nc">Long</span><span class="o">(</span><span class="mi">2</span><span class="o">),</span> <span class="s">"Jason"</span><span class="o">,</span> <span class="s">"Carrora"</span><span class="o">);</span>
<span class="nc">Person</span> <span class="n">p3</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span><span class="k">new</span> <span class="nc">Long</span><span class="o">(</span><span class="mi">3</span><span class="o">),</span> <span class="s">"Alexandru"</span><span class="o">,</span> <span class="s">"Papesco"</span><span class="o">);</span>
<span class="nc">Person</span> <span class="n">p4</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span><span class="k">new</span> <span class="nc">Long</span><span class="o">(</span><span class="mi">4</span><span class="o">),</span> <span class="s">"Jay"</span><span class="o">,</span> <span class="s">"Boss"</span><span class="o">);</span>
<span class="c1">// Store people in our dataSource list (normally they would come from a database).</span>
<span class="n">myList</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;</span><span class="nc">Person</span><span class="o">&gt;();</span>
<span class="n">myList</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">p1</span><span class="o">);</span>
<span class="n">myList</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">p2</span><span class="o">);</span>
<span class="n">myList</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">p3</span><span class="o">);</span>
<span class="n">myList</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">p4</span><span class="o">);</span>
<span class="c1">// Normally we would provide a pre-compiled .jrxml file</span>
<span class="c1">// or check to make sure we don't compile on every request.</span>
<span class="k">try</span> <span class="o">{</span>
<span class="nc">JasperCompileManager</span><span class="o">.</span><span class="na">compileReportToFile</span><span class="o">(</span>
<span class="s">"S2_WEBAPP/jasper/our_jasper_template.jrxml"</span><span class="o">,</span>
<span class="s">"S2_WEBAPP/jasper/our_compiled_template.jasper"</span><span class="o">);</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
<span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
<span class="k">return</span> <span class="no">ERROR</span><span class="o">;</span>
<span class="o">}</span>
<span class="k">return</span> <span class="no">SUCCESS</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">List</span><span class="o">&lt;</span><span class="nc">Person</span><span class="o">&gt;</span> <span class="nf">getMyList</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">myList</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Our JasperAction creates a list of several People. The JasperCompileManager compiles the jrxml template to a .jasper file.</p>
<blockquote>
<p>Again, don’t use this in production code. You should of course either provide compiled templates, or do some sort
of checking to avoid compiling the template on every request. But for our demonstration, or development, this suits
our needs just fine.</p>
</blockquote>
<h1 id="our-jasper-template">Our Jasper template</h1>
<p>JR uses XML configuration to define templates which are compiled to .jasper files. These templates define the resulting
report. This is a handwritten version - for more complex versions I seriously suggest taking a look a the various GUI designers.</p>
<p><strong>our_jasper_template.jrxml</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0"?&gt;</span>
<span class="cp">&lt;!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;</span>
<span class="nt">&lt;jasperReport</span> <span class="na">name=</span><span class="s">"jasper_test"</span><span class="nt">&gt;</span>
<span class="c">&lt;!-- Our fields from the Person class. --&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">"name"</span> <span class="na">class=</span><span class="s">"java.lang.String"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">"lastName"</span> <span class="na">class=</span><span class="s">"java.lang.String"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;title&gt;</span>
<span class="nt">&lt;band</span> <span class="na">height=</span><span class="s">"50"</span><span class="nt">&gt;</span>
<span class="nt">&lt;staticText&gt;</span>
<span class="nt">&lt;reportElement</span> <span class="na">x=</span><span class="s">"0"</span> <span class="na">y=</span><span class="s">"0"</span> <span class="na">width=</span><span class="s">"180"</span> <span class="na">height=</span><span class="s">"15"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;textElement/&gt;</span>
<span class="nt">&lt;text&gt;</span><span class="cp">&lt;![CDATA[Struts 2 JasperReports Sample]]&gt;</span><span class="nt">&lt;/text&gt;</span>
<span class="nt">&lt;/staticText&gt;</span>
<span class="nt">&lt;/band&gt;</span>
<span class="nt">&lt;/title&gt;</span>
<span class="nt">&lt;pageHeader&gt;</span>
<span class="nt">&lt;band/&gt;</span>
<span class="nt">&lt;/pageHeader&gt;</span>
<span class="nt">&lt;columnHeader&gt;</span>
<span class="nt">&lt;band</span> <span class="na">height=</span><span class="s">"20"</span><span class="nt">&gt;</span>
<span class="nt">&lt;staticText&gt;</span>
<span class="nt">&lt;reportElement</span> <span class="na">x=</span><span class="s">"180"</span> <span class="na">y=</span><span class="s">"0"</span> <span class="na">width=</span><span class="s">"180"</span> <span class="na">height=</span><span class="s">"20"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;textElement&gt;</span>
<span class="nt">&lt;font</span> <span class="na">isUnderline=</span><span class="s">"true"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/textElement&gt;</span>
<span class="nt">&lt;text&gt;</span><span class="cp">&lt;![CDATA[NAME]]&gt;</span><span class="nt">&lt;/text&gt;</span>
<span class="nt">&lt;/staticText&gt;</span>
<span class="nt">&lt;staticText&gt;</span>
<span class="nt">&lt;reportElement</span> <span class="na">x=</span><span class="s">"360"</span> <span class="na">y=</span><span class="s">"0"</span> <span class="na">width=</span><span class="s">"180"</span> <span class="na">height=</span><span class="s">"20"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;textElement&gt;</span>
<span class="nt">&lt;font</span> <span class="na">isUnderline=</span><span class="s">"true"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/textElement&gt;</span>
<span class="nt">&lt;text&gt;</span><span class="cp">&lt;![CDATA[LASTNAME]]&gt;</span><span class="nt">&lt;/text&gt;</span>
<span class="nt">&lt;/staticText&gt;</span>
<span class="nt">&lt;/band&gt;</span>
<span class="nt">&lt;/columnHeader&gt;</span>
<span class="nt">&lt;detail&gt;</span>
<span class="nt">&lt;band</span> <span class="na">height=</span><span class="s">"20"</span><span class="nt">&gt;</span>
<span class="nt">&lt;textField&gt;</span>
<span class="nt">&lt;reportElement</span> <span class="na">x=</span><span class="s">"180"</span> <span class="na">y=</span><span class="s">"0"</span> <span class="na">width=</span><span class="s">"180"</span> <span class="na">height=</span><span class="s">"15"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;textElement/&gt;</span>
<span class="nt">&lt;textFieldExpression&gt;</span><span class="cp">&lt;![CDATA[$F{name}]]&gt;</span><span class="nt">&lt;/textFieldExpression&gt;</span>
<span class="nt">&lt;/textField&gt;</span>
<span class="nt">&lt;textField&gt;</span>
<span class="nt">&lt;reportElement</span> <span class="na">x=</span><span class="s">"360"</span> <span class="na">y=</span><span class="s">"0"</span> <span class="na">width=</span><span class="s">"180"</span> <span class="na">height=</span><span class="s">"15"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;textElement/&gt;</span>
<span class="nt">&lt;textFieldExpression&gt;</span><span class="cp">&lt;![CDATA[$F{lastName}]]&gt;</span><span class="nt">&lt;/textFieldExpression&gt;</span>
<span class="nt">&lt;/textField&gt;</span>
<span class="nt">&lt;/band&gt;</span>
<span class="nt">&lt;/detail&gt;</span>
<span class="nt">&lt;columnFooter&gt;</span>
<span class="nt">&lt;band/&gt;</span>
<span class="nt">&lt;/columnFooter&gt;</span>
<span class="nt">&lt;pageFooter&gt;</span>
<span class="nt">&lt;band</span> <span class="na">height=</span><span class="s">"15"</span><span class="nt">&gt;</span>
<span class="nt">&lt;staticText&gt;</span>
<span class="nt">&lt;reportElement</span> <span class="na">x=</span><span class="s">"0"</span> <span class="na">y=</span><span class="s">"0"</span> <span class="na">width=</span><span class="s">"40"</span> <span class="na">height=</span><span class="s">"15"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;textElement/&gt;</span>
<span class="nt">&lt;text&gt;</span><span class="cp">&lt;![CDATA[Page:]]&gt;</span><span class="nt">&lt;/text&gt;</span>
<span class="nt">&lt;/staticText&gt;</span>
<span class="nt">&lt;textField&gt;</span>
<span class="nt">&lt;reportElement</span> <span class="na">x=</span><span class="s">"40"</span> <span class="na">y=</span><span class="s">"0"</span> <span class="na">width=</span><span class="s">"100"</span> <span class="na">height=</span><span class="s">"15"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;textElement/&gt;</span>
<span class="nt">&lt;textFieldExpression</span> <span class="na">class=</span><span class="s">"java.lang.Integer"</span><span class="nt">&gt;</span><span class="cp">&lt;![CDATA[$V{PAGE_NUMBER}]]&gt;</span><span class="nt">&lt;/textFieldExpression&gt;</span>
<span class="nt">&lt;/textField&gt;</span>
<span class="nt">&lt;/band&gt;</span>
<span class="nt">&lt;/pageFooter&gt;</span>
<span class="nt">&lt;summary&gt;</span>
<span class="nt">&lt;band/&gt;</span>
<span class="nt">&lt;/summary&gt;</span>
<span class="nt">&lt;/jasperReport&gt;</span>
</code></pre></div></div>
<p>Save this file in <code class="language-plaintext highlighter-rouge">S2_WEBAPP/jasper/</code> as <code class="language-plaintext highlighter-rouge">our_jasper_template.jrxml</code>.</p>
<p>Most important: we declared the fields name and lastName (two properties from our <code class="language-plaintext highlighter-rouge">Person</code> class). This means we will
now be able to use these fields in our Jasper template.</p>
<p>We define two columnheaders (NAME and LASTNAME), and then add our fields to the detail band (for a better explanation,
look at the JR tutorial). This ‘detail’ band will iterate over our List of People. This is the default behaviour of JR -
so if you want to display more information from the Person, add them to this band.</p>
<p>In the detail band we use the <code class="language-plaintext highlighter-rouge">$F{name}</code> expression. JasperReports will ask Struts to retrieve the <code class="language-plaintext highlighter-rouge">name</code> field value
from a <code class="language-plaintext highlighter-rouge">Person</code> object; the <code class="language-plaintext highlighter-rouge">lastName</code> field is handled the same way.</p>
<p>The rest is markup to define the layout.</p>
<blockquote>
<p>Use a logger (commons-logging, log4j, …) to watch <code class="language-plaintext highlighter-rouge">org.apache.struts2.views.jasperreports</code> in debug mode,
if you have any troubles.</p>
</blockquote>
<h2 id="registering-the-action">Registering the Action</h2>
<p>Using the JasperReports plugin requires adding the JasperReports result type as well as normal action configuration.</p>
<p><strong>struts.xml</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;package</span> <span class="na">name=</span><span class="s">"default"</span> <span class="na">namespace=</span><span class="s">"/"</span> <span class="na">extends=</span><span class="s">"jasperreports-default"</span><span class="nt">&gt;</span>
<span class="nt">&lt;action</span> <span class="na">name=</span><span class="s">"myJasperTest"</span> <span class="na">class=</span><span class="s">"com.acme.test.action.JasperAction"</span><span class="nt">&gt;</span>
<span class="nt">&lt;result</span> <span class="na">name=</span><span class="s">"success"</span> <span class="na">type=</span><span class="s">"jasper"</span><span class="nt">&gt;</span>
<span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">"location"</span><span class="nt">&gt;</span>/jasper/our_compiled_template.jasper<span class="nt">&lt;/param&gt;</span>
<span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">"dataSource"</span><span class="nt">&gt;</span>myList<span class="nt">&lt;/param&gt;</span>
<span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">"format"</span><span class="nt">&gt;</span>PDF<span class="nt">&lt;/param&gt;</span>
<span class="nt">&lt;/result&gt;</span>
<span class="nt">&lt;/action&gt;</span>
...
<span class="nt">&lt;/package&gt;</span>
</code></pre></div></div>
<p>To use the JasperReports result type we must either (a) extend the <code class="language-plaintext highlighter-rouge">jasperreports-default</code> package that defines it
or (b) manually define the JasperReport <code class="language-plaintext highlighter-rouge">jasper</code> result type ourselves.</p>
<p>In the above example we extend the <code class="language-plaintext highlighter-rouge">jasperreports-default</code> package; we can define the <code class="language-plaintext highlighter-rouge">jasper</code> result type manually
by defining it the same way the JasperReport plugin does:</p>
<p><strong>Manually defining the “jasper” result type</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;result-types&gt;</span>
<span class="nt">&lt;result-type</span> <span class="na">name=</span><span class="s">"jasper"</span> <span class="na">class=</span><span class="s">"org.apache.struts2.views.jasperreports.JasperReportsResult"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/result-types&gt;</span>
</code></pre></div></div>
<p>We configure our JasperAction with the name <code class="language-plaintext highlighter-rouge">myJasperTest</code> - this means that we can execute this Action by sending
a request to <code class="language-plaintext highlighter-rouge">myJasperTest.action</code> in our browser.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;action</span> <span class="na">name=</span><span class="s">"myJasperTest"</span> <span class="na">class=</span><span class="s">"com.acme.test.action.JasperAction"</span><span class="nt">&gt;</span>
</code></pre></div></div>
<p>When our JasperAction executes correctly, we will use the Result type registered with the name <code class="language-plaintext highlighter-rouge">jasper</code>. As discussed
above the <code class="language-plaintext highlighter-rouge">jasper</code> result type is available from either extending the <code class="language-plaintext highlighter-rouge">jasperreports-default</code> package or by defining
the result type manually.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;result</span> <span class="na">name=</span><span class="s">"success"</span> <span class="na">type=</span><span class="s">"jasper"</span><span class="nt">&gt;</span>
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">location</code> parameter defines the location of the compiled jasper file, which will be filled by Struts 2 with our dataSource:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">"location"</span><span class="nt">&gt;</span>/jasper/our_compiled_template.jasper<span class="nt">&lt;/param&gt;</span>
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">dataSource</code> parameter defines the action property containing the collection of objects to use in our report.
In this case it’s the <code class="language-plaintext highlighter-rouge">myList</code> property which we manually filled with some <code class="language-plaintext highlighter-rouge">Person</code> objects.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">"dataSource"</span><span class="nt">&gt;</span>myList<span class="nt">&lt;/param&gt;</span>
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">format</code> parameter specifies the output format of the report. Possible values include PDF, CSV, XLS and HTML.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">"format"</span><span class="nt">&gt;</span>PDF<span class="nt">&lt;/param&gt;</span>
</code></pre></div></div>
<h2 id="conclusion">Conclusion</h2>
<p>You should now be able to execute <a href="http://localhost:8080/YOUR_WEBAPP/myJasperTest.action">http://localhost:8080/YOUR_WEBAPP/myJasperTest.action</a></p>
<ul>
<li>and you should see a nice list of names.</li>
</ul>
<p>Struts provides probably the most elegant way to deal with JasperReport files; specify the location of the .jasper file,
specify what dataSource you want to use, and there you go.</p>
</section>
</article>
<footer class="container">
<div class="col-md-12">
Copyright &copy; 2000-2022 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts project logos are
trademarks of The Apache Software Foundation. All Rights Reserved.
</div>
<div class="col-md-12">Logo and website design donated by <a href="https://softwaremill.com/">SoftwareMill</a>.</div>
</footer>
<script>!function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (!d.getElementById(id)) {
js = d.createElement(s);
js.id = id;
js.src = "//platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
}
}(document, "script", "twitter-wjs");</script>
<script src="https://apis.google.com/js/platform.js" async="async" defer="defer"></script>
<div id="fb-root"></div>
<script>(function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s);
js.id = id;
js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
</body>
</html>