<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Записки искателей &#187; JasperReports</title>
	<atom:link href="http://voituk.kiev.ua/category/jasper-reports/feed/" rel="self" type="application/rss+xml" />
	<link>http://voituk.kiev.ua</link>
	<description>while ( isAlive() ) {doCode(); doFun();}</description>
	<lastBuildDate>Sun, 29 Apr 2012 18:50:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>JasperReports 1.3.2</title>
		<link>http://voituk.kiev.ua/2007/04/18/jasperreports-132/</link>
		<comments>http://voituk.kiev.ua/2007/04/18/jasperreports-132/#comments</comments>
		<pubDate>Wed, 18 Apr 2007 06:26:48 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[JasperReports]]></category>

		<guid isPermaLink="false">http://dev.voituk.kiev.ua/2007/04/18/jasperreports-132/</guid>
		<description><![CDATA[30-го марта вышел новый релиз JasperReports http://www.jasperforge.org/index.php?option=com_content&#038;task=view&#038;id=286&#038;Itemid=214 . Кроме исправления ошибок и улучшения существующей функциональности JasperReports 1.3.2 представил две новых языковых конструкции $P!{&#8230;} и $X{&#8230;}. Оба новых элемента нацелены на поддержку динамических запросов в шаблоне отчета. Напомню, что в предыдущих релизах в элементе queryString можно было использовать значения параметров ($P{&#8230;}). В таком случае параметры трактовались [...]]]></description>
			<content:encoded><![CDATA[<p>30-го марта вышел новый релиз JasperReports <a href="http://www.jasperforge.org/index.php?option=com_content&#038;task=view&#038;id=286&#038;Itemid=214">http://www.jasperforge.org/index.php?option=com_content&#038;task=view&#038;id=286&#038;Itemid=214</a> . Кроме исправления ошибок и улучшения существующей функциональности JasperReports 1.3.2 представил две новых языковых конструкции $P!{&#8230;} и $X{&#8230;}.<br />
<span id="more-183"></span><br />
Оба новых элемента нацелены на поддержку динамических запросов в шаблоне отчета. Напомню, что в предыдущих релизах в элементе queryString можно было использовать значения параметров ($P{&#8230;}). В таком случае параметры трактовались как bind переменные (знаки &#8220;?&#8221; в PreparedStatement). Другими словами, существенно изменить структуру запроса было нельзя.</p>
<p>С выходом JasperReports 1.3.2 ситуация изменилась. С помощью синтаксиса $P!{имя_параметра} в запрос можно передавать параметры, которые будут трактоваться, как текст запроса.<br />
Вторая конструкция $X{&#8230;} упрощает работу с выражениями IN (&#8230;) и NOT IN(&#8230;) &#8211; когда количество параметров неизвестно до момента наполнения отчета.<br />
Ниже приведен фрагмент примера из стандартной поставки JasperReports 1.3.2:</p>
<p>[xml]<br />
&#8230;</p>
<parameter name="ReportTitle" class="java.lang.String"/>
<parameter name="ExcludedCities" class="java.util.Collection"/>
<parameter name="OrderClause" class="java.lang.String"/>
	<queryString><br />
		<![CDATA[SELECT * FROM Address WHERE $X{NOTIN, City, ExcludedCities}<br />
		ORDER BY $P!{OrderClause}]]&gt;<br />
	</queryString><br />
&#8230;<br />
[/xml]</p>
<p>[java]<br />
&#8230;<br />
List excludedCities = new ArrayList();<br />
excludedCities.add(&#8220;Boston&#8221;);<br />
excludedCities.add(&#8220;Chicago&#8221;);<br />
excludedCities.add(&#8220;Oslo&#8221;);<br />
parameters.put(&#8220;ExcludedCities&#8221;, excludedCities);</p>
<p>parameters.put(&#8220;OrderClause&#8221;, &#8220;City&#8221;);</p>
<p>if (TASK_FILL_IGNORE_PAGINATION.equals(taskName)) {<br />
	parameters.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.TRUE);<br />
}</p>
<p>JasperFillManager.fillReportToFile(fileName, parameters, getConnection());<br />
System.err.println(&#8220;Filling time : &#8221; + (System.currentTimeMillis() &#8211; start));<br />
System.exit(0);<br />
&#8230;<br />
[/java]</p>
<p>Если с синтаксисом $P!{…} все довольно просто (по сути, он ничем не отличается от $P{…}, то $X{…} я рассмотрю немного детальнее.</p>
<p>Итак, $X{…}, как впрочем и $P{} используется исключительно в элементе queryString. Синтаксис $X{…} – такой:<br />
$X{IN, имя_поля, включения}<br />
$X{NOTIN, имя_поля, исключения}</p>
<p>Литералы IN и NOTIN указывают какое действие следует выполнить: включение (IN) или исключение (NOTIN).<br />
имя_поля – название поля в запросе, над которым следует произвести действие.<br />
включения, исключения – это List значений, которые необходимо включить/исключить.</p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2007/04/18/jasperreports-132/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JasperReports: printing right</title>
		<link>http://voituk.kiev.ua/2007/03/23/jasperreports-printing-right/</link>
		<comments>http://voituk.kiev.ua/2007/03/23/jasperreports-printing-right/#comments</comments>
		<pubDate>Fri, 23 Mar 2007 14:02:44 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[JasperReports]]></category>

		<guid isPermaLink="false">http://dev.voituk.kiev.ua/2007/03/23/jasperreports-printing-right/</guid>
		<description><![CDATA[Эта небольшая заметка показывает, как вывести отчет на печать, не экспортируя его в промежуточный формат вроде PDF. Этот код я нашел в блоге Marc Nuri. Марк любезно дал согласие опубликовать этот сниппет в нашем блоге. Думаю, этот материал хорошо дополнит серию уроков о JasperReports. Оригинал статьи: Choosing a printer programmatically in Jasper Reports public class [...]]]></description>
			<content:encoded><![CDATA[<p>Эта небольшая заметка показывает, как вывести отчет на печать, не экспортируя его в промежуточный формат вроде PDF. Этот код я нашел в блоге <a href="http://blog.marcnuri.com/blog/default/">Marc Nuri</a>. Марк любезно дал согласие опубликовать этот сниппет в нашем блоге. Думаю, этот материал хорошо дополнит серию уроков о JasperReports.<br />
Оригинал статьи: <a href="http://blog.marcnuri.com/blog/default/2007/03/22/Choosing-a-printer-programmatically-in-Jasper-Reports">Choosing a printer programmatically in Jasper Reports</a></p>
<p><span id="more-161"></span></p>
<pre><code class="java">
public class PrinterTest {
	public static void main(String[] args) throws PrinterException, JRException {
		JasperPrint print = (JasperPrint) JRLoader.loadObject(
				new File("reports/fill/example1.jrprint"));

		PrinterJob job = PrinterJob.getPrinterJob();
		PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
		int selectedService = 0;

		// В этом блоке выбирается принтер, который
		// содержит в своем названии "HP"
		for(int i = 0; i &lt; services.length;i++){
			if(services[i].getName().contains("HP")){
				selectedService = i;
			}
		}

		System.out.println("Selected " + services[selectedService].getName());

		// Морально готовим принтер
		job.setPrintService(services[selectedService]);
		PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();
		MediaSizeName mediaSizeName = MediaSize.findMedia(4, 4, MediaPrintableArea.INCH);
		printRequestAttributeSet.add(mediaSizeName);
		printRequestAttributeSet.add(new Copies(1));

		// Экспортируем
		JRPrintServiceExporter exporter;
		exporter = new JRPrintServiceExporter();
		exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
		exporter.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE,
				services[selectedService]);
		exporter.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE_ATTRIBUTE_SET,
				services[selectedService].getAttributes());
		exporter.setParameter(JRPrintServiceExporterParameter.PRINT_REQUEST_ATTRIBUTE_SET,
				printRequestAttributeSet);
		exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PAGE_DIALOG,
				Boolean.FALSE);
		exporter.setParameter(JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG,
				Boolean.FALSE);
		exporter.exportReport();
		System.out.println("Done");
	}
}
</code></pre>
<p>Посмотрим на код еще раз: сначала выбираются все доступные принт-сервисы. Затем среди доступных принт сервисов выбирается тот, который содержит в названии строку &#8220;HP&#8221;.<br />
Затем для выбранного сервиса устанавливаются параметры печати: размер бумаги и количество копий.<br />
Затем создается экземпляр JRPrintServiceExporter, который передает отчет принтеру.</p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2007/03/23/jasperreports-printing-right/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JasperReports grouping</title>
		<link>http://voituk.kiev.ua/2007/03/20/jasperreports-grouping/</link>
		<comments>http://voituk.kiev.ua/2007/03/20/jasperreports-grouping/#comments</comments>
		<pubDate>Tue, 20 Mar 2007 08:56:30 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[JasperReports]]></category>

		<guid isPermaLink="false">http://dev.voituk.kiev.ua/2007/03/20/jasperreports-grouping/</guid>
		<description><![CDATA[Возможность группировать данные, и подсчитывать показатели группы (количество элементом, среднее значение некоторого поля и.т.д.) &#8211; мощный инструмент формирования гибких отчетов. Именно об этом инструменте и пойдет речь в новой заметке о JasperReports. Вторая часть заметки посвящена возможностям выражений (expressions) в JasperReports. Все статьи Группировка данных. Ниже представлен небольшой пример кода, с которым мы будем работать. [...]]]></description>
			<content:encoded><![CDATA[<p>Возможность группировать данные, и подсчитывать показатели группы (количество элементом, среднее значение некоторого поля и.т.д.) &#8211; мощный инструмент формирования гибких отчетов. Именно об этом инструменте и пойдет речь в новой заметке о JasperReports. Вторая часть заметки посвящена возможностям выражений (expressions) в JasperReports.</p>
<p><span id="more-155"></span></p>
<p><a href="http://voituk.kiev.ua/intro-jasper-reports/">Все статьи</a></p>
<p><strong>Группировка данных.</strong></p>
<p>Ниже представлен небольшой пример кода, с которым мы будем работать. Исходный отчет показывает список всех заказчиков: имя, фамилию и среднемесячные затраты.</p>
<pre><code>&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
  PUBLIC "-//JasperReports//DTD Report Design//EN"
  "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="group_demo"&gt;

	&lt;style name="Normal" isDefault="true"
		fontSize="12"
		pdfFontName="c:\tahoma.ttf"
		pdfEncoding="Cp1251"
		/&gt;
	&lt;queryString&gt;
		&lt;![CDATA[
			select * from customers c
		]]&gt;
	&lt;/queryString&gt;

	&lt;field name="firstname" class="java.lang.String" /&gt;
	&lt;field name="lastname" class="java.lang.String" /&gt;
	&lt;field name="segment" class="java.lang.String" /&gt;
	&lt;field name="city" class="java.lang.String" /&gt;
	&lt;field name="spendings" class="java.lang.Integer" /&gt;
	&lt;field name="id" class="java.lang.String" /&gt;

	&lt;detail&gt;
		&lt;band height="20"&gt;
			&lt;textField&gt;
				&lt;reportElement x="51" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{firstname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="252" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{lastname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="452" y="0" width="50" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.Integer"&gt;
					&lt;![CDATA[$F{spendings}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
		&lt;/band&gt;
	&lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p>Предположим теперь, что необходимо сгруппировать отчет по городам. Реализовать группировку можно с помощью элемента group:</p>
<pre><code>&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
  PUBLIC "-//JasperReports//DTD Report Design//EN"
  "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="group_demo"&gt;

	&lt;style name="Normal" isDefault="true"
		fontSize="12"
		pdfFontName="c:\tahoma.ttf"
		pdfEncoding="Cp1251"
		/&gt;
	&lt;queryString&gt;
		&lt;![CDATA[
			select * from customers c order by c.city
		]]&gt;
	&lt;/queryString&gt;

	&lt;field name="firstname" class="java.lang.String" /&gt;
	&lt;field name="lastname" class="java.lang.String" /&gt;
	&lt;field name="segment" class="java.lang.String" /&gt;
	&lt;field name="city" class="java.lang.String" /&gt;
	&lt;field name="spendings" class="java.lang.Integer" /&gt;
	&lt;field name="id" class="java.lang.String" /&gt;

	&lt;group name="city_group"&gt;
		&lt;groupExpression&gt;
			&lt;![CDATA[$F{city}]]&gt;
		&lt;/groupExpression&gt;
		&lt;groupHeader&gt;
			&lt;band height="40"&gt;
				&lt;textField&gt;
					&lt;reportElement x="0" y="10" width="50" height="30"/&gt;
					&lt;textFieldExpression&gt;$F{city}&lt;/textFieldExpression&gt;
				&lt;/textField&gt;
			&lt;/band&gt;
		&lt;/groupHeader&gt;
		&lt;groupFooter&gt;
			&lt;band height="10"&gt;
			&lt;/band&gt;
		&lt;/groupFooter&gt;
	&lt;/group&gt;

	&lt;detail&gt;
		&lt;band height="20"&gt;
			&lt;textField&gt;
				&lt;reportElement x="51" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{firstname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="252" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{lastname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="452" y="0" width="50" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.Integer"&gt;
					&lt;![CDATA[$F{spendings}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
		&lt;/band&gt;
	&lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p>Элемент group имеет три подэлемента:</p>
<p>groupExpression &#8211; выражение, по которому будет производится группировка<br />
groupHeader &#8211; заголовок группы &#8211; что будет напечатано перед первым элементом группы<br />
groupFooter &#8211; что будет напечатано после последнего элемента группы</p>
<p>Механизм группировки довольно прост &#8211; для каждой записи из DataSource вычисляется groupExpression и сравнивается с groupExpression предыдущей записи. Если они не равны &#8211; значит нужно закрывать прошлую группу и открывать следующую.<br />
Необходимо помнить, что в SQL запросе необходимо сортировать записи по тем полям, по которым планируется вводить группировку в отчете. Иначе получится белиберда.<br />
Заметьте, что в качестве группировки используется выражение (expression). В этом поле можно написать выражение на языке java (или groovy, но об этом расскажет Вадим ;-)) по которому будет определяться начало новой группы.</p>
<p>Вот пример того, как работают выражения в JasperReports: в следующем отчете мы сгруппируем покупателей по первой букве в имени:</p>
<pre><code>&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
  PUBLIC "-//JasperReports//DTD Report Design//EN"
  "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="group_demo"&gt;

	&lt;style name="Normal" isDefault="true"
		fontSize="12"
		pdfFontName="c:\tahoma.ttf"
		pdfEncoding="Cp1251"
		/&gt;
	&lt;queryString&gt;
		&lt;![CDATA[
			select * from customers c order by c.firstname
		]]&gt;
	&lt;/queryString&gt;

	&lt;field name="firstname" class="java.lang.String" /&gt;
	&lt;field name="lastname" class="java.lang.String" /&gt;
	&lt;field name="segment" class="java.lang.String" /&gt;
	&lt;field name="city" class="java.lang.String" /&gt;
	&lt;field name="spendings" class="java.lang.Integer" /&gt;
	&lt;field name="id" class="java.lang.String" /&gt;

	&lt;group name="city_group"&gt;
		&lt;groupExpression&gt;
			&lt;![CDATA[$F{firstname}.substring(0, 1)]]&gt;
		&lt;/groupExpression&gt;
		&lt;groupHeader&gt;
			&lt;band height="40"&gt;
				&lt;textField&gt;
					&lt;reportElement x="0" y="10" width="250" height="30"/&gt;
					&lt;textFieldExpression&gt;"Покупатели на букву " + $F{firstname}.substring(0, 1) &lt;/textFieldExpression&gt;
				&lt;/textField&gt;
			&lt;/band&gt;
		&lt;/groupHeader&gt;
		&lt;groupFooter&gt;
			&lt;band height="10"&gt;
			&lt;/band&gt;
		&lt;/groupFooter&gt;
	&lt;/group&gt;

	&lt;detail&gt;
		&lt;band height="20"&gt;
			&lt;textField&gt;
				&lt;reportElement x="51" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{firstname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="252" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{lastname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="452" y="0" width="50" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.Integer"&gt;
					&lt;![CDATA[$F{spendings}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
		&lt;/band&gt;
	&lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p>Выражения в JasperReports &#8211; это гибкий механизм, который помогает решать множество проблем. В конце заметки я покажу, как можно использовать выражения (expressions) для &#8220;подсветки&#8221; нужных значений в отчете.</p>
<p>Вернемся к группировкам. Чтобы сгруппировать отчет по нескольким критериям, достаточно описать по одной группе для каждого из них. В примере ниже, покупатели будут сгруппированы сначала по городу, а затем по сегменту:</p>
<pre><code>&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
  PUBLIC "-//JasperReports//DTD Report Design//EN"
  "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="group_demo"&gt;

	&lt;style name="Normal" isDefault="true"
		fontSize="12"
		pdfFontName="c:\tahoma.ttf"
		pdfEncoding="Cp1251"
		/&gt;
	&lt;queryString&gt;
		&lt;![CDATA[
			select * from customers c order by c.firstname
		]]&gt;
	&lt;/queryString&gt;

	&lt;field name="firstname" class="java.lang.String" /&gt;
	&lt;field name="lastname" class="java.lang.String" /&gt;
	&lt;field name="segment" class="java.lang.String" /&gt;
	&lt;field name="city" class="java.lang.String" /&gt;
	&lt;field name="spendings" class="java.lang.Integer" /&gt;
	&lt;field name="id" class="java.lang.String" /&gt;

	&lt;group name="city_group"&gt;
		&lt;groupExpression&gt;
			&lt;![CDATA[$F{city}]]&gt;
		&lt;/groupExpression&gt;
		&lt;groupHeader&gt;
			&lt;band height="40"&gt;
				&lt;textField&gt;
					&lt;reportElement x="0" y="10" width="250" height="30"/&gt;
					&lt;textFieldExpression&gt;$F{city} &lt;/textFieldExpression&gt;
				&lt;/textField&gt;
			&lt;/band&gt;
		&lt;/groupHeader&gt;
		&lt;groupFooter&gt;
			&lt;band height="10"&gt;
			&lt;/band&gt;
		&lt;/groupFooter&gt;
	&lt;/group&gt;
	&lt;group name="segment_group"&gt;
		&lt;groupExpression&gt;
			&lt;![CDATA[$F{segment}]]&gt;
		&lt;/groupExpression&gt;
		&lt;groupHeader&gt;
			&lt;band height="40"&gt;
				&lt;textField&gt;
					&lt;reportElement x="30" y="10" width="250" height="30"/&gt;
					&lt;textFieldExpression&gt;$F{segment}&lt;/textFieldExpression&gt;
				&lt;/textField&gt;
			&lt;/band&gt;
		&lt;/groupHeader&gt;
		&lt;groupFooter&gt;
			&lt;band height="10"&gt;
			&lt;/band&gt;
		&lt;/groupFooter&gt;
	&lt;/group&gt;
	&lt;detail&gt;
		&lt;band height="20"&gt;
			&lt;textField&gt;
				&lt;reportElement x="51" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{firstname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="252" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{lastname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="452" y="0" width="50" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.Integer"&gt;
					&lt;![CDATA[$F{spendings}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
		&lt;/band&gt;
	&lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p>Добавьте стили по вкусу :-).</p>
<p><strong>Выражения в JasperReports.</strong></p>
<p>Выражения &#8211; это механизм JasperReports, который позволяет вставлять в отчет некоторые вычисляемые значения. Выражения записываются на языке Java или Groovy. Выражения можно вставлять в блоки, названия которых оканчиваются на Expression: groupExpression, textFieldExpression, imageExpression и другие. В следующих примерах я покажу несколько примеров выражений на Java.</p>
<p>Не забывайте учитывать, какой class вы указали в качестве параметра выражения. Попытка сложить java.lang.String c java.lang.Integer и получить java.lang.Double ни к чему хорошему не приведет.</p>
<p><em>Пример первый. Объединение строк.</em></p>
<pre><code>&lt;textFieldExpression class="java.lang.String"&gt;
		&lt;![CDATA[$F{firstname} + " " + $F{lastname}]]&gt;
	&lt;/textFieldExpression&gt;</code></pre>
<p><em>Пример второй. Вычисление значения.</em></p>
<pre><code>&lt;textFieldExpression class="java.lang.String"&gt;
	&lt;![CDATA[
		String.valueOf(
			new Integer($F{firstname}.intValue()*10).intValue())
	]]&gt;
&lt;/textFieldExpression&gt;</code></pre>
<p><em>Пример третий. Подчеркнуть значения больше 400, остальные написать &#8220;как есть&#8221;.</em></p>
<pre><code>&lt;textField&gt;
	&lt;reportElement x="452" y="0" width="50" height="20" /&gt;
	&lt;textElement isStyledText="true" /&gt;
	&lt;textFieldExpression class="java.lang.String"&gt;
		&lt;![CDATA[
			$F{spendings}.intValue() &gt; 400 ?
				"&lt;style isUnderline=\"true\"&gt;" +
					String.valueOf($F{spendings}.intValue()) +
				"&lt;/style&gt;"
			:
			String.valueOf($F{spendings}.intValue())]]&gt;
	&lt;/textFieldExpression&gt;
&lt;/textField&gt;</code></pre>
<p><em>Пример четвертый. Выделить другим стилем ячейку, если затраты больше 400.</em></p>
<p>Этот пример требует некоторых дополнительных пояснений. У элемента reportElement есть необязательный подэлемент: printWhenExpression. В качестве expression необходимо передать java.lang.Boolean. Если вычисление даст результат true, то элемент, который описывается этим reportElement, будет напечатан, иначе не будет.<br />
Чтобы реализовать идею выделения нужных элементов цветом, необходимо сделать вот что:</p>
<p>1. Создать два стиля &#8211; green и red &#8211; для выделения &#8220;хороших&#8221; и &#8220;плохих&#8221; клиентов.<br />
2. Создать два одинаковых блока &#8211; один поверх другого. &#8220;Нижний&#8221; (&#8220;красный&#8221;) блок будет отображаться всегда. &#8220;Трюк&#8221; заключается в том, что верхний блок будет отображаться только в том случае, когда значение $F{spendings} больше 400</p>
<p>Вот листинг, который иллюстрирует этот прием:</p>
<pre><code>&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
  PUBLIC "-//JasperReports//DTD Report Design//EN"
  "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="group_demo"&gt;

	&lt;style name="Normal" isDefault="true"
		fontSize="12"
		pdfFontName="c:\tahoma.ttf"
		pdfEncoding="Cp1251"
		/&gt;
	&lt;style
		name="green"
		style="Normal"
		forecolor="#00AA00"
	/&gt;

	&lt;style
		name="red"
		style="Normal"
		forecolor="#AA0000"
	/&gt;
	&lt;queryString&gt;
		&lt;![CDATA[
			select * from customers c order by c.firstname
		]]&gt;
	&lt;/queryString&gt;

	&lt;field name="firstname" class="java.lang.String" /&gt;
	&lt;field name="lastname" class="java.lang.String" /&gt;
	&lt;field name="segment" class="java.lang.String" /&gt;
	&lt;field name="city" class="java.lang.String" /&gt;
	&lt;field name="spendings" class="java.lang.Integer" /&gt;
	&lt;field name="id" class="java.lang.String" /&gt;

	&lt;detail&gt;
		&lt;band height="20"&gt;
			&lt;textField&gt;
				&lt;reportElement x="51" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{firstname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="252" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{lastname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="452" y="0" width="50" height="20" style="red"/&gt;
				&lt;textFieldExpression class="java.lang.Integer"&gt;
					&lt;![CDATA[$F{spendings}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="452" y="0" width="50" height="20" style="green"&gt;
					&lt;printWhenExpression&gt;
						&lt;![CDATA[new Boolean($F{spendings}.intValue() &gt; 400)]]&gt;
					&lt;/printWhenExpression&gt;
				&lt;/reportElement&gt;
				&lt;textFieldExpression class="java.lang.Integer"&gt;
					&lt;![CDATA[$F{spendings}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
		&lt;/band&gt;
	&lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p>В следующей заметке речь пойдет о <em>параметрах и переменных</em> в JasperReports.</p>
<p>Предыдущая тема: <a href="http://voituk.kiev.ua/2007/03/20/jasperreports-visual-styles/">Оформление отчета</a></p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2007/03/20/jasperreports-grouping/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>JasperReports visual styles</title>
		<link>http://voituk.kiev.ua/2007/03/20/jasperreports-visual-styles/</link>
		<comments>http://voituk.kiev.ua/2007/03/20/jasperreports-visual-styles/#comments</comments>
		<pubDate>Tue, 20 Mar 2007 08:30:23 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[JasperReports]]></category>

		<guid isPermaLink="false">http://dev.voituk.kiev.ua/2007/03/20/jasperreports-visual-styles/</guid>
		<description><![CDATA[JasperReports оформление отчета. Отчеты, которые я демонстрировал в прошлых заметках, с точки зрения дизайна были довольно примитивными. Мы использовали элементы style, staticText и textField не вдаваясь в детали. В этой заметке я расскажу о том, как настроить внешний вид Jasper отчета. Все статьи Разметка страницы. У корневого элемента jasperReport есть один обязательный атрибут &#8211; name, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>JasperReports оформление отчета.</strong></p>
<p>Отчеты, которые я демонстрировал в прошлых заметках, с точки зрения дизайна были довольно примитивными. Мы использовали элементы style, staticText и textField не вдаваясь в детали. В этой заметке я расскажу о том, как настроить внешний вид Jasper отчета.<br />
<span id="more-154"></span></p>
<p><a href="http://voituk.kiev.ua/intro-jasper-reports/">Все статьи</a></p>
<p><strong>Разметка страницы.</strong><br />
У корневого элемента jasperReport есть один обязательный атрибут &#8211; name, название отчета. Кроме атрибута name есть еще много необязательных атрибутов, с помощью которых можно контролировать разметку страниц (размеры, отступы, и.т.д.) и некоторые другие особенности. Ниже представлена таблица, которая описывает эти атрибуты</p>
<p><strong>Название:</strong> pageWidth<br />
<strong>Назначение:</strong> определяет ширину страницы в пикселях<br />
<strong>Значения:</strong> любое целое позитивное число<br />
<strong>По умолчанию:</strong> 595</p>
<p><strong>Название:</strong> pageHeight<br />
<strong>Назначение:</strong> определяет высоту страницы в пикселях<br />
<strong>Значения:</strong> любое целое позитивное число<br />
<strong>По умолчанию:</strong> 842</p>
<p><strong>Название:</strong> leftMargin<br />
<strong>Назначение:</strong> определяет размер левого отступа в пикселях<br />
<strong>Значения:</strong> любое целое позитивное число<br />
<strong>По умолчанию:</strong> 20</p>
<p><strong>Название:</strong> rightMargin<br />
<strong>Назначение:</strong> определяет размер правого отступа в пикселях<br />
<strong>Значения:</strong> любое целое позитивное число<br />
<strong>По умолчанию:</strong> 20</p>
<p><strong>Название:</strong> topMargin<br />
<strong>Назначение:</strong> определяет размер верхнего отступа в пикселях<br />
<strong>Значения:</strong> любое целое позитивное число<br />
<strong>По умолчанию:</strong> 20</p>
<p><strong>Название:</strong> bottomMargin<br />
<strong>Назначение:</strong> определяет размер нижнего отступа в пикселях<br />
<strong>Значения:</strong> любое целое позитивное число<br />
<strong>По умолчанию:</strong> 20</p>
<p><strong>Название:</strong> orientation<br />
<strong>Назначение:</strong> определяет ориентацию страницы<br />
<strong>Значения:</strong> Portrait, Landscape<br />
<strong>По умолчанию:</strong> Portrait</p>
<p><strong>Название:</strong> whenNoDataType<br />
<strong>Назначение:</strong> определяет, какой отчет необходимо создать, если в DataSource&#8217;е, который передали в отчет, нет данных<br />
<strong>Значения:</strong> NoPages &#8211; отчет не будет генерироваться вообще. BlankPage &#8211; будет сгенерирована одна пустая страница. AllSectionsNoDetail &#8211; будут сгенерирован отчет, содержащий все блоки, кроме блока Detail.<br />
<strong>По умолчанию:</strong> NoPages</p>
<p><strong>Название:</strong> isTitleNewPage<br />
<strong>Назначение:</strong> определяет, следует ли выделять отдельную страницу под блок title.<br />
<strong>Значения:</strong> true, false<br />
<strong>По умолчанию:</strong> false</p>
<p><strong>Название:</strong> isSummaryNewPage<br />
<strong>Назначение:</strong> определяет, следует ли выделять отдельную страницу под блок summary.<br />
<strong>Значения:</strong> true, false<br />
<strong>По умолчанию:</strong> false</p>
<p>Есть еще и другие атрибуты, но если перечислять их все, то заметка об оформлении отчетов превратится в справочник по элементам шаблона JaserReports. Как видно по описанию, смысл большинства параметров понятен и без разъяснений. Полный список элементов и параметров можно посмотреть в dtd шаблона.</p>
<p><strong>Стили.</strong></p>
<p>Стили позволяют единожды определить некоторый набор свойств элементов, а затем использовать этот набор в любом блоке отчета.  Вы знакомы с CSS? Концепции очень похожи. В JasperReports стили действуют точно так же.<br />
С помощью стилей можно указать размер шрифта, цвет текста, указать будет ли текст написан курсивом или будет зачеркнут и еще много других свойств.<br />
Один стиль может наследовать другой: добавлять к определению стиля новые свойства или переопределять существующие.<br />
Про стили можно много говорить, но легче показать один пример:</p>
<pre><code>&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
  PUBLIC "-//JasperReports//DTD Report Design//EN"
  "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="JasperDBDemo"&gt;

	&lt;style
		name="Normal"
		isDefault="true"
		pdfFontName="c:\tahoma.ttf"
		pdfEncoding="Cp1251"
	 /&gt;

	&lt;style
		name="parent"
		fontSize="14"
		isBold="true"
		pdfFontName="c:\tahoma.ttf"
		pdfEncoding="Cp1251"
	 /&gt;

	 &lt;style
	 	name="child"
	 	style="parent"
	 	forecolor="#880000"
	 /&gt;
	&lt;detail&gt;
		&lt;band height="100"&gt;
			&lt;staticText&gt;
				&lt;reportElement x="180" y="0" width="200" height="20" /&gt;
				&lt;text&gt;&lt;![CDATA[Это стиль по умолчанию]]&gt;&lt;/text&gt;
			&lt;/staticText&gt;
			&lt;staticText&gt;
				&lt;reportElement x="180" y="20" width="200" height="20" style="parent"/&gt;
				&lt;text&gt;&lt;![CDATA[Это стиль parent]]&gt;&lt;/text&gt;
			&lt;/staticText&gt;
			&lt;staticText&gt;
				&lt;reportElement x="180" y="40" width="200" height="20" style="child"/&gt;
				&lt;text&gt;&lt;![CDATA[Это стиль child]]&gt;&lt;/text&gt;
			&lt;/staticText&gt;
		&lt;/band&gt;
	&lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p>Как и следовало ожидать, если стиль не указан явно, то будет использован стиль, назначенный по умолчанию. В нашем примере, это стиль Normal. Параметр стиля Normal isDefault=&#8221;true&#8221; указывает на то, что именно этот стиль будет использован по умолчанию.<br />
Если же явно указать другой стиль, то будет использован он. Во втором блоке staticText в элементе reportElement указан стиль parent: текст блока будет оформлен в соответствии с этим стилем.<br />
Обратите внимание на стиль child. Он наследует стиль parent (style=&#8221;parent&#8221;) и переопределяет цвет шрифта на красный (цвет указан в формате #RRGGBB). Все остальные параметры стиля останутся такими же, как у parent.<br />
Можно создать еще один стиль, grandChild, который будет наследовать child и продолжить цепочку.</p>
<p>Думаю, основную &#8220;идею&#8221; стилей вы уловили.</p>
<p>Ниже приведена небольшая таблица с описанием основных атрибутов тега style:</p>
<p><strong>Название:</strong> forecolor<br />
<strong>Назначение:</strong> определяет цвет шрифта<br />
<strong>Значения:</strong> 16-ричный код цвета: #RRGGBB или одно из предопределенных значений: blak, blue, cyan, darkGray, gray, green, lightGray, magenta, orange, pink, red, yellow, white</p>
<p><strong>Название:</strong> backcolor<br />
<strong>Назначение:</strong> определяет цвет фона<br />
<strong>Значения:</strong> см. описание forecolor.</p>
<p><strong>Название:</strong> border (leftBorder, rightBorder, topBorder, bottomBorder)<br />
<strong>Назначение:</strong> определяет размер рамки элемента.<br />
<strong>Значения:</strong> None, Thin,  1Point,  2Point,  4Point, Dotted</p>
<p><strong>Название:</strong> borderColor (leftBorderColor, rightBorderColor, topBorderColor, bottomBorderColor)<br />
<strong>Назначение:</strong> определяет цвет рамки элемента.<br />
<strong>Значения:</strong> см. описание forecolor.</p>
<p><strong>Название:</strong> padding (leftPadding, rightPadding, topPading, bottomPadding)<br />
<strong>Назначение:</strong> определяет отступ (в пикселях) между рамкой и элементом<br />
<strong>Значения:</strong> Целое число</p>
<p><strong>Название:</strong> fontName<br />
<strong>Назначение:</strong> определяет название шрифта<br />
<strong>Значения:</strong> строка &#8211; имя шрифта</p>
<p><strong>Название:</strong> fontSize<br />
<strong>Назначение:</strong> определяет размер шрифта<br />
<strong>Значения:</strong> число &#8211; размер шрифта</p>
<p><strong>Название:</strong> isBold<br />
<strong>Назначение:</strong> определяет, будет ли текст &#8220;жирным&#8221;<br />
<strong>Значения:</strong> true, false</p>
<p><strong>Название:</strong> isItalic<br />
<strong>Назначение:</strong> определяет, будет ли текст курсивом<br />
<strong>Значения:</strong> true, false</p>
<p><strong>Название:</strong> isStrikeThrough<br />
<strong>Назначение:</strong> определяет, будет ли текст зачеркнутым<br />
<strong>Значения:</strong> true, false</p>
<p><strong>Название:</strong> isUnderline<br />
<strong>Назначение:</strong> определяет, будет ли текст подчеркнутым<br />
<strong>Значения:</strong> true, false</p>
<p><strong>Название:</strong> lineSpacing<br />
<strong>Назначение:</strong> определяет междустрочный интервал (1_1_2 &#8211; это полуторный интервал)<br />
<strong>Значения:</strong> 1_1_2, Double, Single</p>
<p><strong>Название:</strong> rotation<br />
<strong>Назначение:</strong> определяет на как будет повернут текст<br />
<strong>Значения:</strong> Left, None, Right, UpsideDown</p>
<p><strong>Название:</strong> isStyledText<br />
<strong>Назначение:</strong> определяет, будет ли текст внутри блока содержать дополнительную информацию о стилях<br />
<strong>Значения:</strong> true, false</p>
<p>Назначение всех атрибутов кроме, пожалуй, isStyledText, вполне очевидны. Про isStyledText я расскажу немного позже.</p>
<p>Есть еще один способ указывать параметры текста &#8211; описывать их в элементе textElement (необязательный подэлмент staticText и textField). На мой взгляд, этот способ не такой гибкий, как использование стилей, но я не исключаю, что бывают ситуации, когда он нужен.</p>
<p>Вот пример использования элемента textElement для форматирования текста</p>
<pre><code>&lt;staticText&gt;
	&lt;reportElement x="0" y="40" width="500" height="20"/&gt;
	&lt;textElement verticalAlignment="Top" textAlignment="Right"/&gt;
	&lt;text&gt;&lt;![CDATA[Это пример форматирования с помощью textElement]]&gt;&lt;/text&gt;
&lt;/staticText&gt;</code></pre>
<p>Ниже &#8211; список атрибутов textElement:</p>
<p><strong>Название:</strong> textAlignment<br />
<strong>Назначение:</strong> выравнивание текста<br />
<strong>Значения:</strong> Left, Center, Right, Justified</p>
<p><strong>Название:</strong> verticalAlignment<br />
<strong>Назначение:</strong> вертикальное выранивание<br />
<strong>Значения:</strong> Top, Middle, Bottom</p>
<p><strong>Название:</strong> rotation<br />
<strong>Назначение:</strong> поворот текста<br />
<strong>Значения:</strong> None, Left, Right, UpsideDown</p>
<p><strong>Название:</strong> lineSpacing<br />
<strong>Назначение:</strong> междустрочный интервал<br />
<strong>Значения:</strong> Single, 1_1_2, Double</p>
<p><strong>Название:</strong> isStyledText<br />
<strong>Назначение:</strong> определяет, будет ли текст внутри блока содержать дополнительную информацию о стилях<br />
<strong>Значения:</strong> true, false</p>
<p>Мы научились указывать стили для блоков staticText и textField. Но что, если требуется выделить другим стилем некоторую часть текста блока? Именно для этого и служит элемент isStyledText, о котором я обещал рассказать дополнительно.<br />
Если указать isStyledText=&#8221;true&#8221;, то внутри блока textField или staticText можнно указывать дополнительную информацию о стиле фрагмента. Вот пример того, как это работает:</p>
<pre><code>&lt;staticText&gt;
	&lt;reportElement x="0" y="40" width="500" height="60"/&gt;
	&lt;textElement isStyledText="true"/&gt;
	&lt;text&gt;&lt;![CDATA[Это
		&lt;style pdfFontName="c:\timesi.ttf" isItalic="true" isUnderline="true"&gt;пример&lt;/style&gt;
		форматирования с помощью textElement]]&gt;&lt;/text&gt;
&lt;/staticText&gt;</code></pre>
<p>Обратите внимание на pdfFontName &#8211; имя шрифта для PDF, при генерации pdf атрибуты вроде isItalic и isBold &#8211; будут проигнорированы. Внешний вид шрифта определяется в файле .ttf. и, строго говоря, Tahoma и Tahoma bold это разные шрифты. Таким образом, чтобы сделать pdf с курсивом, необходимо указывать &#8220;курсивный&#8221; шрифт. Для примера я взял timesi.ttf. С другой стороны для HTML отчета такие &#8220;изыски&#8221; не обязательны. Аттрибутов isUnderline и isStrikeThrough эти ограничения не касаются &#8211; чтобы создать соответствующий эффект достаточно провести линию: &#8220;под&#8221; или &#8220;через&#8221; текст, соответственно. Начертание самого шрифта не меняется, поэтому указывать pdfFontName не нужно.</p>
<p><strong>Установка фона для отчета.</strong><br />
Бывают ситуации, когда необходимо установить фон &#8211; логотип компании или водяной знак &#8220;конфиденциально&#8221;. Реализовать эту задачу можно, воспользовавшись тегом &#8220;background&#8221;.<br />
Замечание: установка фона никак не отразится на отчетах, проэкспортированных в HTML и в xls. Эти форматы не поддерживают фоновых изображений. Очевидно, что для форматов plain text и csv большинство &#8220;стилистических изысков&#8221; тоже не пригодится.<br />
Вот пример кода, который показывает, как добавить фон:</p>
<pre><code>&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
  PUBLIC "-//JasperReports//DTD Report Design//EN"
  "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="JasperDBDemo"&gt;

	&lt;style
		name="Normal"
		isDefault="true"
		forecolor="#880000"
		pdfFontName="reports\fonts\tahoma.ttf"
		pdfEncoding="Cp1251"
	 /&gt;

	 &lt;style
	 	style="Normal"
	 	name="bg"
	 	fontSize="50"
	 	forecolor="lightGray"
	  /&gt;

	&lt;background&gt;
		&lt;band height="780"&gt;
			&lt;staticText&gt;
				&lt;reportElement x="150" y="0" width="500" height="780"
				mode="Transparent" style="bg"/&gt;
				&lt;text&gt;&lt;![CDATA[СЕКРЕТНО]]&gt;&lt;/text&gt;
			&lt;/staticText&gt;
		&lt;/band&gt;
	&lt;/background&gt;

	&lt;detail&gt;
		&lt;band height="100"&gt;
			&lt;staticText&gt;
				&lt;reportElement x="230" y="40" width="100" height="60"/&gt;
				&lt;box border="Thin" /&gt;
				&lt;text&gt;&lt;![CDATA[Текст отчета]]&gt;&lt;/text&gt;
			&lt;/staticText&gt;
		&lt;/band&gt;
	&lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p>Забегая немного вперед, хочется показать, как вставить изображение на фон отчета. Синтаксис понятен интуитивно:</p>
<pre><code>&lt;background&gt;
	&lt;band height="780"&gt;
		&lt;image&gt;
			&lt;reportElement x="0" y="0" width="500" height="780"
			mode="Transparent"/&gt;
			&lt;imageExpression class="java.lang.String"&gt;
				"reports/images/logo.png"
			&lt;/imageExpression&gt;
		&lt;/image&gt;
	&lt;/band&gt;
&lt;/background&gt;</code></pre>
<p>Для одной заметки информации более чем достаточно, в следующей заметке я расскажу о том, как группировать данные в Jasper отчетах.</p>
<p>Предыдущая тема: <a href="http://voituk.kiev.ua/2007/03/16/jasperreports-and-ant/">Интеграция Ant</a><br />
Следующая тема: <a href="http://voituk.kiev.ua/2007/03/20/jasperreports-grouping/">Группировка данных, выражения</a></p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2007/03/20/jasperreports-visual-styles/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JasperReports Video Kick-Off</title>
		<link>http://voituk.kiev.ua/2007/03/16/jasperreports-video-kick-off/</link>
		<comments>http://voituk.kiev.ua/2007/03/16/jasperreports-video-kick-off/#comments</comments>
		<pubDate>Fri, 16 Mar 2007 18:53:16 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JasperReports]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://dev.voituk.kiev.ua/2007/03/16/jasperreports-video-kick-off/</guid>
		<description><![CDATA[После работы было весьма творческое настроение, поэтому натворил видеодемку &#8211; как начать работать с JasperReports в среде Eclipse. Все знают, что в любом деле самое сложное &#8211; это первый удачный шаг. Надеюсь демка поможет вам без труда начать использовать одно из наиболее мощных средств создания отчетов &#8211; JasperReports. Вот ссылка на видео. Если будет интерес [...]]]></description>
			<content:encoded><![CDATA[<p>После работы было весьма творческое настроение, поэтому натворил видеодемку &#8211; как начать работать с JasperReports в среде Eclipse. Все знают, что в любом деле самое сложное &#8211; это первый удачный шаг. Надеюсь демка поможет вам без труда начать использовать одно из наиболее мощных средств создания отчетов &#8211; JasperReports.</p>
<p>Вот ссылка на видео. Если будет интерес &#8211; кину еще пару туториалов.</p>
<p><script src="/wp-content/uploads/jasper/_show_video.js"></script><a onclick="_showVideo();" href="javascript:void(0);">Смотреть видео</a> | <a href="http://voituk.kiev.ua/wp-content/uploads/jasper/jasper_good.swf">Загрузить ролик (в SWF)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2007/03/16/jasperreports-video-kick-off/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>JasperReports and Ant</title>
		<link>http://voituk.kiev.ua/2007/03/16/jasperreports-and-ant/</link>
		<comments>http://voituk.kiev.ua/2007/03/16/jasperreports-and-ant/#comments</comments>
		<pubDate>Fri, 16 Mar 2007 16:33:10 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[JasperReports]]></category>

		<guid isPermaLink="false">http://dev.voituk.kiev.ua/2007/03/16/jasperreports-and-ant/</guid>
		<description><![CDATA[В этой заметке я расскажу о том, как можно использовать Ant для автоматизации некоторых задач, связанных с разработкой Jasper отчетов. Все статьи Ant и JasperReports Будем считать, что Ant уже установлен. Если не установлен &#8211; быстрее качайте http://ant.apache.org/bindownload.cgi, читайте инструкции по установке и устанавливайте! В библиотеке JasperReports есть две маленьких, но очень полезных утилиты, которые [...]]]></description>
			<content:encoded><![CDATA[<p>В этой заметке я расскажу о том, как можно использовать Ant для автоматизации некоторых задач, связанных с разработкой Jasper отчетов.<br />
<span id="more-152"></span></p>
<p><a href="http://voituk.kiev.ua/intro-jasper-reports/">Все статьи</a></p>
<p><strong>Ant и JasperReports</strong></p>
<p>Будем считать, что Ant уже установлен. Если не установлен &#8211; быстрее качайте <a href="http://ant.apache.org/bindownload.cgi">http://ant.apache.org/bindownload.cgi</a>, читайте инструкции по установке и устанавливайте!</p>
<p>В библиотеке JasperReports есть две маленьких, но очень полезных утилиты, которые позволяют просматривать отчет на любом этапе его жизненного цикла, не экспортируя, к примеру, в PDF. Исполняемые файлы утилит &#8211;  net.sf.jasperreports.view.JasperDesignViewer и net.sf.jasperreports.view.JasperViewer.</p>
<p>Первая утилита, как и следует из названия, предназначена для просмотра шаблонов &#8211; как XML шаблона, так и бинарного .jasper шаблона. Вторая утилита позволяет просматривать отчеты формата .jrprint (уже заполненные данными отчеты).<br />
Первая &#8220;оптимизация&#8221; заключается в том, что мы создадим target для Ant&#8217;а, который будет автоматически запускать утилиту для просмотра разрабатываемого XML отчета.</p>
<pre><code>&lt;project name="Jasper Utils" default="viewXML" basedir="."&gt;

	&lt;property name="file.name" value="reports/simple.xml"/&gt;
	&lt;property name="jasper.dir" value="C:/apps/jasperreports-1.3.1"/&gt;
	&lt;property name="classes.dir" value="${jasper.dir}/build/classes"/&gt;
	&lt;property name="lib.dir" value="${jasper.dir}/lib"/&gt;

	&lt;path id="classpath"&gt;
		&lt;pathelement location="./"/&gt;
		&lt;pathelement location="${classes.dir}"/&gt;
		&lt;fileset dir="${lib.dir}"&gt;
			&lt;include name="**/*.jar"/&gt;
		&lt;/fileset&gt;
	&lt;/path&gt;

	&lt;target name="viewXML"&gt;
		&lt;java classname="net.sf.jasperreports.view.JasperDesignViewer" fork="true"&gt;
			&lt;arg value="-XML"/&gt;
			&lt;arg value="-F${file.name}"/&gt;
			&lt;classpath refid="classpath"/&gt;
		&lt;/java&gt;
	&lt;/target&gt;
&lt;/project&gt;</code></pre>
<p>Параметр ${file.name} &#8211; это путь к файлу, который необходимо просмотреть.<br />
Все что делает скрипт &#8211; это собирает воедино все библиотеки, которые нужны для работы JasperDesignViewer и запускает программу с двумя параметрами:</p>
<p>-XML &#8211; указывает на то, что мы будем просматривать еще нескомпилированный отчет.<br />
-Fпуть_к_файлу &#8211; путь к шаблону, который нужно просмотреть.</p>
<p>Запустите скрипт и убедитесь, что он работает.</p>
<p>Чтобы &#8220;натравить&#8221; просмотрщик на скомпилированный отчет &#8211; достаточно убрать параметр -XML из опций запуска JasperDesignViewer. Новый target будет выглядеть так:</p>
<pre><code>&lt;target name="viewCompiled"&gt;
	&lt;java classname="net.sf.jasperreports.view.JasperDesignViewer" fork="true"&gt;
		&lt;arg value="-F${file.name}"/&gt;
		&lt;classpath refid="classpath"/&gt;
	&lt;/java&gt;
&lt;/target&gt;</code></pre>
<p>Target для просмотра заполненных данными отчетов не слишком сильно отличается от двух предыдущих:</p>
<pre><code>&lt;target name="viewFilled"&gt;
	&lt;java classname="net.sf.jasperreports.view.JasperViewer" fork="true"&gt;
		&lt;arg value="-F${file.name}"/&gt;
		&lt;classpath refid="classpath"/&gt;
	&lt;/java&gt;
&lt;/target&gt;</code></pre>
<p>Компиляцию отчетов тоже можно автоматизировать. Разработчики библиотеки поставляют специальный task для Ant&#8217;а &#8211; net.sf.jasperreports.ant.JRAntCompileTask. Task называется jrc, и его синтаксис очень напоминает синтаксис javac:</p>
<pre><code>&lt;target name="compile" &gt;
	&lt;taskdef name="jrc" classname="net.sf.jasperreports.ant.JRAntCompileTask"&gt;
		&lt;classpath refid="classpath"/&gt;
	&lt;/taskdef&gt;
	&lt;jrc destdir="."&gt;
		&lt;src&gt;
			&lt;fileset dir="."&gt;
				&lt;include name="**/*.xml"/&gt;
			&lt;/fileset&gt;
		&lt;/src&gt;
		&lt;classpath refid="classpath"/&gt;
	&lt;/jrc&gt;
&lt;/target&gt;</code></pre>
<p>Этот target позволяет скомпилировать все шаблоны в директории reports.</p>
<p>Вот что получится, если собрать все task&#8217;и в одном проекте:</p>
<pre><code>&lt;project name="Jasper Utils" default="viewXML" basedir="."&gt;

	&lt;property name="file.name" value="reports/simple.xml"/&gt;
	&lt;property name="jasper.dir" value="C:/apps/jasperreports-1.3.1"/&gt;
	&lt;property name="classes.dir" value="${jasper.dir}/build/classes"/&gt;
	&lt;property name="lib.dir" value="${jasper.dir}/lib"/&gt;

	&lt;path id="classpath"&gt;
		&lt;pathelement location="./"/&gt;
		&lt;pathelement location="${classes.dir}"/&gt;
		&lt;fileset dir="${lib.dir}"&gt;
			&lt;include name="**/*.jar"/&gt;
		&lt;/fileset&gt;
	&lt;/path&gt;

	&lt;target name="viewXML"&gt;
		&lt;java classname="net.sf.jasperreports.view.JasperDesignViewer" fork="true"&gt;
			&lt;arg value="-XML"/&gt;
			&lt;arg value="-F${file.name}"/&gt;
			&lt;classpath refid="classpath"/&gt;
		&lt;/java&gt;
	&lt;/target&gt;

	&lt;target name="viewCompiled"&gt;
		&lt;java classname="net.sf.jasperreports.view.JasperDesignViewer" fork="true"&gt;
			&lt;arg value="-F${file.name}"/&gt;
			&lt;classpath refid="classpath"/&gt;
		&lt;/java&gt;
	&lt;/target&gt;

	&lt;target name="viewFilled"&gt;
		&lt;java classname="net.sf.jasperreports.view.JasperViewer" fork="true"&gt;
			&lt;arg value="-F${file.name}"/&gt;
			&lt;classpath refid="classpath"/&gt;
		&lt;/java&gt;
	&lt;/target&gt;

	&lt;target name="compile" &gt;
		&lt;taskdef name="jrc" classname="net.sf.jasperreports.ant.JRAntCompileTask"&gt;
			&lt;classpath refid="classpath"/&gt;
		&lt;/taskdef&gt;
		&lt;jrc destdir="reports"&gt;
			&lt;src&gt;
				&lt;fileset dir="."&gt;
					&lt;include name="reports/*.xml"/&gt;
				&lt;/fileset&gt;
			&lt;/src&gt;
			&lt;classpath refid="classpath"/&gt;
		&lt;/jrc&gt;
	&lt;/target&gt;
&lt;/project&gt;</code></pre>
<p>Надеюсь, этот маленький инструментарий поможет при разработке отчетов.</p>
<p>Предыдущая тема <a href="http://voituk.kiev.ua/2007/03/16/jasperreports-life-cycle/">Жизненный цикл отчета</a><br />
Следующая тема <a href="http://voituk.kiev.ua/2007/03/20/jasperreports-visual-styles/">Оформление отчетов</a></p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2007/03/16/jasperreports-and-ant/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>JasperReports Life Cycle</title>
		<link>http://voituk.kiev.ua/2007/03/16/jasperreports-life-cycle/</link>
		<comments>http://voituk.kiev.ua/2007/03/16/jasperreports-life-cycle/#comments</comments>
		<pubDate>Fri, 16 Mar 2007 07:16:01 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[JasperReports]]></category>

		<guid isPermaLink="false">http://dev.voituk.kiev.ua/2007/03/16/jasperreports-life-cycle/</guid>
		<description><![CDATA[В прошлой заметке о JasperReports я описал основные принципы разметки отчета и показал способ составить отчет на основании данных из БД. В этой заметке я расскажу о &#8220;жизненном цикле&#8221; Jasper отчета. Все статьи Жизненный цикл отчета. Жизненный цикл отчета начинается с разработки xml-шаблона отчета. Давайте вспомним Java код, который мы использовали в первой заметке для [...]]]></description>
			<content:encoded><![CDATA[<p>В прошлой заметке о JasperReports я описал основные принципы разметки отчета и показал способ составить отчет на основании данных из БД. В этой заметке я расскажу о &#8220;жизненном цикле&#8221; Jasper отчета.<br />
<span id="more-151"></span></p>
<p><a href="http://voituk.kiev.ua/intro-jasper-reports/">Все статьи</a></p>
<p><strong>Жизненный цикл отчета.</strong></p>
<p>Жизненный цикл отчета начинается с разработки xml-шаблона отчета. Давайте вспомним Java код, который мы использовали в первой заметке для создания HTML отчета:</p>
<p>	[java]JasperReport jasperReport = JasperCompileManager<br />
			.compileReport(&#8220;reports/test.jrxml&#8221;);</p>
<p>	JasperPrint jasperPrint = JasperFillManager.fillReport(<br />
			jasperReport,<br />
			new HashMap(),<br />
			new JREmptyDataSource()<br />
		);</p>
<p>	JasperExportManager.exportReportToHtmlFile(<br />
		jasperPrint,<br />
		&#8220;reports/demo_report.html&#8221;<br />
	);[/java]</p>
<p>Эти три строки полностью описывают жизненный цикл отчета. Рассмотрим их по порядку. Первая строка</p>
<p><code>	JasperReport jasperReport = JasperCompileManager<br />
			.compileReport("reports/test.jrxml");</code></p>
<p>преобразует xml формат отчета в некоторый внутренний формат, который представлен классом JasperReport. Формат JasperReport называется скомпилированным шаблоном.<br />
Скомпилированный (бинарный) вариант отчета можно сохранить в виде обычного бинарного файла, используя метод JasperCompileManager.compileReportToFile(&#8230;);</p>
<p>Вот пример кода, который скомпилирует отчет из первой заметки и сохранит скомпилированную версию в виде файла.</p>
<p>[java]public class JasperReportsIntro {<br />
	public static void main(String[] args) {<br />
		try {<br />
			JasperCompileManager<br />
					.compileReportToFile(&#8220;reports/demo_report.xml&#8221;);<br />
		} catch (JRException e) {<br />
			e.printStackTrace();<br />
		}<br />
	}<br />
}[/java]</p>
<p>Процесс загрузки, проверки и обработки xml-шаблона занимает некоторое время. Поэтому работа со скомпилированной версией отчета дает существенный выигрыш в производительности на production системах.<br />
Если использовать вариант функции compileReportToFile с одним аргументом, то скомпилированный отчет будет сохранен в ту же папку, где находится исходный xml файл. Имя файла будет таким: <em>название_отчета.jasper</em>.</p>
<p>Если есть скомпилированный шаблон, то код для генерации отчета будет выглядеть так:</p>
<p>[java]public class JasperReportsIntro {<br />
	public static void main(String[] args) {<br />
		try {<br />
			JasperPrint jasperPrint = JasperFillManager.fillReport(<br />
					&#8220;reports/Simple_Report.jasper&#8221;,<br />
					new HashMap(), new JREmptyDataSource());<br />
			JasperExportManager.exportReportToHtmlFile(<br />
					jasperPrint,<br />
					&#8220;reports/demo_report.html&#8221;);<br />
		} catch (JRException e) {<br />
			e.printStackTrace();<br />
		}<br />
	}<br />
}[/java]</p>
<p>Как видно, осталось всего две строки: строка, с помощью которой отчет заполняется данными:</p>
<p><code>			JasperPrint jasperPrint = JasperFillManager.fillReport(<br />
					"reports/Simple_Report.jasper",<br />
					new HashMap(), new JREmptyDataSource());</code></p>
<p>и строка, экспортирующая отчет в html файл.<br />
Заполненный и готовый к экспорту отчет хранится в виде объекта JasperPrint. Разработчики библиотеки предоставили нам возможность сохранить в виде файла и эту промежуточную версию отчета. Код, который реализует эту функциональность, не отличается оригинальностью:</p>
<p>[java]public class JasperReportsIntro {<br />
	public static void main(String[] args) {<br />
		try {<br />
			JasperFillManager.fillReportToFile(<br />
					&#8220;reports/Simple_Report.jasper&#8221;,<br />
					new HashMap(), new JREmptyDataSource());<br />
		} catch (JRException e) {<br />
			e.printStackTrace();<br />
		}<br />
	}<br />
}[/java]</p>
<p>Как и в прошлом примере, отчет будет сохранен в той же папке, но теперь с расширением <em>.jrprint</em>.</p>
<p>Чтобы загрузить .jrprint и экспортировать в один из &#8220;общедоступных&#8221; форматов можно использовать такой код:</p>
<p>[java]public class JasperReportsIntro {<br />
	public static void main(String[] args) {<br />
		try {<br />
			JasperExportManager.exportReportToHtmlFile(<br />
					&#8220;reports/Simple_Report.jrprint&#8221;,<br />
					&#8220;reports/demo_report.html&#8221;);<br />
		} catch (JRException e) {<br />
			e.printStackTrace();<br />
		}<br />
	}<br />
}[/java]</p>
<p>Экспорт является конечной точкой жизненного цикла отчета (ну, конечно, если не считать за конечную точку пыльный ящик стола одного из заказчиков).</p>
<p>Подведем итоги.<br />
Жизненный цикл отчета JasperReports состоит из трех стадий:</p>
<p>1. XML (jrxml) шаблон отчета, который создает разработчик (шаблон можно написать вручную или использовать GUI редактор вроде iReport).<br />
2. Скомпилированный шаблон (файл .jasper). Скомпилированный шаблон еще не заполнен данными, но, в отличии от xml шаблона файл jasper не надо разбирать или верифицировать. Поэтому для работы в production среде лучше использовать именно скомпилированные шаблоны.<br />
3. Отчет, заполненный данными (.jrprint). Это готовый к просмотру (с помощью специальной утилиты о которой я расскажу в следующей заметке) или к экспорту отчет.<br />
4. Экспортированный файл &#8211; файл, готовый для конечных пользователей. Сейас экспортировать отчеты можно в один из следующих форматов &#8211; pdf, html, rtf, xls, csv, xml, plain text.</p>
<p>В следующей заметке я расскажу, как можно просматривать отчеты на любой стадии их жизненного цикла, не экспортируя их в открытый формат (очень полезно при разработке) и о том, как автоматизировать некоторые задачи построения отчетов с помощью утилиты Ant (не менее полезно при разработке).</p>
<p>Предыдущая тема <a href="http://voituk.kiev.ua/2007/03/15/jasperreports-db-support/">Работа с БД</a><br />
Следующая тема <a href="http://voituk.kiev.ua/2007/03/16/jasperreports-and-ant/">Интеграция Ant</a></p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2007/03/16/jasperreports-life-cycle/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>JasperReports DB support</title>
		<link>http://voituk.kiev.ua/2007/03/15/jasperreports-db-support/</link>
		<comments>http://voituk.kiev.ua/2007/03/15/jasperreports-db-support/#comments</comments>
		<pubDate>Thu, 15 Mar 2007 07:58:13 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[JasperReports]]></category>

		<guid isPermaLink="false">http://dev.voituk.kiev.ua/2007/03/15/jasperreports-db-support/</guid>
		<description><![CDATA[В прошлой заметке я привел пример простого отчета, сгенерированного с помошью библиотеки JasperReports. В этой раз я продолжу тему автоматизированных отчетов и более детально расскажу про структуру шаблона и про то, как заставить Jasper генерировать отчеты на основе данных из БД. Все статьи Структура шаблона. Шаблон Jasper отчета &#8211; это xml документ, составленный по определенным [...]]]></description>
			<content:encoded><![CDATA[<p>В прошлой заметке я привел пример простого отчета, сгенерированного с помошью библиотеки JasperReports. В этой раз я продолжу тему автоматизированных отчетов и более детально расскажу про структуру шаблона и про то, как заставить Jasper генерировать отчеты на основе данных из БД.</p>
<p><span id="more-149"></span></p>
<p><a href="http://voituk.kiev.ua/intro-jasper-reports/">Все статьи</a></p>
<p><strong>Структура шаблона.</strong><br />
Шаблон Jasper отчета &#8211; это xml документ, составленный по определенным правилам. Правил немного и большинство из них понятны интуитивно.</p>
<p>Каждый отчет должен иметь корневой элемент jasperReport с одним обязательным атрибутом: name &#8211; название отчета. Авторы библиотеки рекомендуют создавать отчеты таким образом, чтобы атрибут name и имя файла шаблона были одинаковыми. К примеру, если файл называется min_report.xml, то атрибут name должен иметь значение &#8220;min_report&#8221;.<br />
У корневого элемента jasperReport нет обязательных подэлементов, поэтому минимальный шаблон отчета выглядит так:</p>
<pre><code class="xml">&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
    PUBLIC "-//JasperReports//DTD Report Design//EN"
    "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="min_report"&gt;
&lt;/jasperReport&gt;</code></pre>
<p>Содержимое тега jasperReport полностью определяет внешний вид отчета.</p>
<p>Отчет состоит из нескольких блоков. В шаблоне может содержаться максимум по одному блоку каждого типа (это правило касается только блоков &#8220;разметки&#8221;, которые описаны ниже). С другой стороны, ни один из блоков обязательным не является.</p>
<p><em>&lt;title&gt;</em> &#8211; название отчета. Название отображается один раз в начале отчета.<br />
<em>&lt;pageHeader&gt;</em> &#8211; заголовок страницы. Отображается вначале каждой новой страницы отчета.<br />
<em>&lt;columnHeader&gt;</em> &#8211; заголовок колонки. Имеет смысл только в случае, если отчет разбит на несколько колонок. По умолчанию в отчете есть только одна колонка. columnHeader отображается вначале каждой новой колонки.<br />
<em>&lt;detail&gt;</em> &#8211; ключевая и самая важная часть отчета. Можно назвать этот блок &#8220;телом&#8221; отчета. В блоке detail содержится основная информация.<br />
<em>&lt;columnFooter&gt;</em> &#8211; &#8220;подножье&#8221; колонки. Отображается после колонки. Аналогично с columnHeader этот блок имеет смысл вставлять только в том случае, если колонок в шаблоне как минимум две.<br />
<em>&lt;pageFooter&gt;</em> &#8211; &#8220;подножье&#8221; страницы. Печатается в конце каждой страницы отчета.<br />
<em>&lt;lastPageFooter&gt;</em> &#8211; &#8220;подножье&#8221; последней страницы. Печатается в конце последней страницы отчета. Если lastPageFooter определен, то на последней странице не будет напечатан pageFooter, а только lastPageFooter. Есть один интересный нюанс: если в отчете всего одна страница и определен lastPageFooter, то pageFooter не будет напечатан вообще: ведь единственная страница является и первой и последней.<br />
<em>&lt;summary&gt;</em> &#8211; выводы или итоги. Печатается один раз в конце отчета.</p>
<p>То есть отчет &#8220;выглядит&#8221; так:</p>
<pre><code>&lt;title&gt;
&lt;pageHeader&gt;
&lt;columnHeader&gt;
&lt;detail&gt;
&lt;columnFooter&gt;
&lt;summary&gt;
&lt;pageFooter&gt;|&lt;lastPageFooter&gt;</code></pre>
<p>Каждый из этих элементов содержит один обязательный подэлемент &#8211; band. band &#8211; это часть площади отчета, которая отводится в распоряжение соответствующего блока.</p>
<p>Внутри band содержатся элементы, которые отвечают за отображение данных.</p>
<p>Посмотрим еще раз на отчет из прошлой заметки:</p>
<pre><code class="xml">&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
    PUBLIC "-//JasperReports//DTD Report Design//EN"
    "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="simple"&gt;

  &lt;style
    name="Normal"
    isDefault="true"
    pdfFontName="c:\tahoma.ttf"
    pdfEncoding="Cp1251"
  /&gt;

  &lt;detail&gt;
    &lt;band height="20"&gt;
      &lt;staticText&gt;
        &lt;reportElement x="180" y="0" width="200" height="20" /&gt;
        &lt;text&gt;&lt;![CDATA[Тест !!]]&gt;&lt;/text&gt;
      &lt;/staticText&gt;
    &lt;/band&gt;
  &lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p>Как видно, мы пренебрегли всеми блоками кроме двух &#8211; detail и style. Внутри блока detail содержится band &#8211; &#8220;полоса&#8221;. Этот элемент описывает свойства той части отчета, которая будет отведена под блок detail. В этом примере мы указали, что высота полосы будет 20 пикселей (height=&#8221;20&#8243;). Внутри band, в свою очередь содержится статический текст (&#8220;Тест !!&#8221;).</p>
<p>Блок style нужен для определения стиля документа. В нашем примере он нужен для корректной локализации (без него русские буквы ведут себя непредсказуемо). Я посвящу стилям отдельную заметку. Сейчас я предлагаю принять этот блок таким, какой он есть.</p>
<p>Элемент reportElement, в этом примере, определяет положение текста внутри band&#8217;а &#8211; текст будет смещен на 180 пикселей вправо.</p>
<p>Внутри одного band&#8217;а может быть <em>несколько</em> элементов с данными: к примеру, такой шаблон тоже будет вполне допустимым:</p>
<pre><code>&lt;jasperReport name="simple"&gt;
  &lt;style name="Normal" isDefault="true" pdfFontName="c:\tahoma.ttf" pdfEncoding="Cp1251" /&gt;

  &lt;detail&gt;
    &lt;band height="20"&gt;
      &lt;staticText&gt;
        &lt;reportElement x="100" y="0" width="50" height="20"/&gt;
        &lt;text&gt;&lt;![CDATA[Текст 1]]&gt;&lt;/text&gt;
      &lt;/staticText&gt;
      &lt;staticText&gt;
        &lt;reportElement x="150" y="0" width="50" height="20"/&gt;
        &lt;text&gt;&lt;![CDATA[Текст 2]]&gt;&lt;/text&gt;
      &lt;/staticText&gt;
    &lt;/band&gt;
  &lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p><strong>Использование данных БД.</strong></p>
<p>Заставить Jasper работать с базой данных совсем не сложно. Для примера я использовал MySQL. Совершенно не важно, какую СУБД используете вы. Для того, чтобы успешно сформировать отчет по данным из базы вам достаточно знать, как соединиться с БД через JDBC.<br />
Для примера я создал одну простую таблицу &#8211; customers:</p>
<pre><code class="sql">DROP TABLE IF EXISTS `jasper`.`customers`;
CREATE TABLE `customers` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `firstname` varchar(45) NOT NULL default '',
  `lastname` varchar(45) NOT NULL default '',
  `segment` varchar(45) NOT NULL default '',
  `city` varchar(45) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB ;</code></pre>
<p>Начнем с java кода.<br />
Если записать последовательность действий, которые нужно выполнить для передачи данных из базы в отчет, то получится такой список:</p>
<p>1. Соединиться с БД, выполнить запрос и получить ResultSet.<br />
2. Передать полученный ResultSet в JasperFillManager.fillReport(&#8230;)<br />
3. Корректно закрыть соединение с БД.</p>
<p>Чтобы передать в отчет ResultSet его нужно &#8220;обернуть&#8221; в JRResultSetDataSource &#8211; класс, специально для этого созданный и наследующий JRDataSource.</p>
<p>Давайте вспомним предыдущую заметку. &#8220;Заполняя&#8221; отчет мы передавали в него эксземпляр JREmptyDataSource &#8211; пустой источник данных. В этот раз мы передаем экземпляр JRResultSetDataSource, поскольку источник данных это ResultSet.</p>
<p>Код изменится совсем немного:</p>
<pre><code class="java">JasperPrint jasperPrint = JasperFillManager.fillReport(
    jasperReport,
    new HashMap(),
    new JRResultSetDataSource(resultSet)
);</code></pre>
<p>Если собрать воедино все сказанное, то выйдет такой кусочек кода:</p>
<pre><code class="java">public class JasperDBDemo {
  public static void main(String[] args) throws SQLException {

    Connection conn = null;
    ResultSet resultSet = null;
    PrepearedStatement statement = null;

    System.out.println("Starting");

    try {
      // Открываем соединение с базой
      Class.forName("org.gjt.mm.mysql.Driver");
      String query = "select * from customers";
      conn = DriverManager.getConnection("jdbc:mysql://localhost/jasper", "jasper", "jasper");
      statement = conn.prepareStatement(query);

      // Исполняем запрос и получаем ResultSet
      resultSet = statement.executeQuery();

      JasperReport jasperReport = JasperCompileManager.compileReport("reports/db_report.xml");

      // Передаем resultSet в отчет
      JasperPrint jasperPrint = JasperFillManager.fillReport( jasperReport,  new HashMap(),
        new JRResultSetDataSource(resultSet) );

      JasperExportManager.exportReportToHtmlFile(jasperPrint, "reports/db_report.html");

    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (SQLException e) {
      e.printStackTrace();
    } catch (JRException e) {
      e.printStackTrace();
    } finally {
      // Корректно закрываем соединение с базой
      try {
        resultSet.close();
        statement.close();
        conn.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    System.out.println("Done.");
  }
}</code></pre>
<p>Теперь займемся шаблоном отчета.</p>
<p>Чтобы использовать поля выборки в отчете их необходимо описать. Описание поля &#8211; это его имя и java класс, совместимый с типом поля.</p>
<pre><code class="xml">&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
    PUBLIC "-//JasperReports//DTD Report Design//EN"
    "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="JasperDBDemo"&gt;

  &lt;style name="Arial_Normal" isDefault="true" fontName="Arial"
    fontSize="12" pdfFontName="c:\tahoma.ttf" pdfEncoding="Cp1251"
    isPdfEmbedded="false" /&gt;

  &lt;field name="id" class="java.lang.String" /&gt;
  &lt;field name="firstname" class="java.lang.String" /&gt;
  &lt;field name="lastname" class="java.lang.String" /&gt;
  &lt;field name="city" class="java.lang.String" /&gt;
  &lt;field name="segment" class="java.lang.String" /&gt;

&lt;/jasperReport&gt;</code></pre>
<p>После того, как поля описаны к ним можно обращаться из отчета, используя синтаксис $F{имя_поля}. К примеру, чтобы обратиться к полю firstname необходимо написать $F{firstname}.</p>
<p>Теперь становится довольно очевидным, как надо создать отчет, используя поля выборки:</p>
<pre><code class="xml">&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
	PUBLIC "-//JasperReports//DTD Report Design//EN"
	"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="JasperDBDemo"&gt;

	&lt;style name="Arial_Normal" isDefault="true" fontName="Arial"
		fontSize="12" pdfFontName="c:\tahoma.ttf" pdfEncoding="Cp1251"
		isPdfEmbedded="false" /&gt;

	&lt;field name="id" class="java.lang.String" /&gt;
	&lt;field name="firstname" class="java.lang.String" /&gt;
	&lt;field name="lastname" class="java.lang.String" /&gt;
	&lt;field name="city" class="java.lang.String" /&gt;
	&lt;field name="segment" class="java.lang.String" /&gt;

	&lt;detail&gt;
		&lt;band height="20"&gt;
			&lt;textField&gt;
				&lt;reportElement x="0" y="0" width="50" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{id}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="51" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{firstname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
			&lt;textField&gt;
				&lt;reportElement x="252" y="0" width="200" height="20" /&gt;
				&lt;textFieldExpression class="java.lang.String"&gt;
					&lt;![CDATA[$F{lastname}]]&gt;
				&lt;/textFieldExpression&gt;
			&lt;/textField&gt;
		&lt;/band&gt;
	&lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p>Как видно, для каждой записи из базы мы напечатали 3 элемента, &#8211; id, firstname и lastname. Нет ничего проще, верно?.</p>
<p>Напоследок, еще один небольшой &#8220;трюк&#8221;. Запрос можно хранить прямо в шаблоне отчета. Для этого текст запроса достаточно поместить в блок &lt;queryString&gt;, а в java коде передавать не JRDataSource, а java.sql.Connection.</p>
<p>Идея довольно простая, поэтому ниже я просто приведу код реализации.</p>
<p>Шаблон будет выглядеть так:</p>
<pre><code>&lt;jasperReport name="JasperDBDemo"&gt;

  &lt;style name="Arial_Normal" isDefault="true" fontName="Arial"
    fontSize="12" pdfFontName="c:\tahoma.ttf" pdfEncoding="Cp1251"
    isPdfEmbedded="false" /&gt;

  &lt;queryString&gt;
    &lt;![CDATA[ select * from customers ]]&gt;
  &lt;/queryString&gt;

  &lt;field name="id" class="java.lang.String" /&gt;
  &lt;field name="firstname" class="java.lang.String" /&gt;
  &lt;field name="lastname" class="java.lang.String" /&gt;
  &lt;field name="city" class="java.lang.String" /&gt;
  &lt;field name="segment" class="java.lang.String" /&gt;

  &lt;detail&gt;
    &lt;band height="20"&gt;
      &lt;textField&gt;
        &lt;reportElement x="0" y="0" width="50" height="20" /&gt;
        &lt;textFieldExpression class="java.lang.String"&gt;
          &lt;![CDATA[$F{id}]]&gt;
        &lt;/textFieldExpression&gt;
      &lt;/textField&gt;
      &lt;textField&gt;
        &lt;reportElement x="51" y="0" width="200" height="20" /&gt;
        &lt;textFieldExpression class="java.lang.String"&gt;
          &lt;![CDATA[$F{firstname}]]&gt;
        &lt;/textFieldExpression&gt;
      &lt;/textField&gt;
      &lt;textField&gt;
        &lt;reportElement x="252" y="0" width="200" height="20" /&gt;
        &lt;textFieldExpression class="java.lang.String"&gt;
          &lt;![CDATA[$F{lastname}]]&gt;
        &lt;/textFieldExpression&gt;
     &lt;/textField&gt;
   &lt;/band&gt;
  &lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p>А java код &#8211; так:</p>
<pre><code class="java">public class JasperDBDemo {
  public static void main(String[] args) throws SQLException {

    Connection conn = null;
    System.out.println("Starting");

    try {
      // Открываем соединение с базой
      Class.forName("org.gjt.mm.mysql.Driver");
      String query = "select * from customers";
      conn = DriverManager.getConnection("jdbc:mysql://localhost/jasper",
          "jasper", "jasper");

      JasperReport jasperReport = JasperCompileManager
          .compileReport("reports/db_report.xml");

      // Передаем resultSet в отчет
      JasperPrint jasperPrint = JasperFillManager.fillReport( jasperReport,
           new HashMap(), conn );

      JasperExportManager.exportReportToHtmlFile(jasperPrint,
           "reports/db_report.html");

    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (SQLException e) {
      e.printStackTrace();
    } catch (JRException e) {
      e.printStackTrace();
    } finally {
      // Корректно закрываем соединение с базой
      try {
        conn.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    System.out.println("Done.");
  }
}</code></pre>
<p>Порядок следования элементов в шаблоне имеет значение. Нельзя описывать поля перед описанием запроса. Нельзя ставить title после footer&#8217;а и.т.д.</p>
<p>Требование вполне естественное, но чтобы не возникало лишних ошибок, я рекомендую использовать редактор xml который умеет &#8220;подсвечивать&#8221; отклонения от dtd и нормально описывать причину ошибки.</p>
<p>На этом все. Пишите комменты.</p>
<p>Предыдущая тема: <a href="http://voituk.kiev.ua/2007/03/13/report-in/">Report in</a><br />
Следующая тема: <a href="http://voituk.kiev.ua/2007/03/16/jasperreports-life-cycle/">Жизненный цикл отчета</a></p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2007/03/15/jasperreports-db-support/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Report in</title>
		<link>http://voituk.kiev.ua/2007/03/13/report-in/</link>
		<comments>http://voituk.kiev.ua/2007/03/13/report-in/#comments</comments>
		<pubDate>Tue, 13 Mar 2007 07:42:08 +0000</pubDate>
		<dc:creator>juriy</dc:creator>
				<category><![CDATA[JasperReports]]></category>

		<guid isPermaLink="false">http://dev.voituk.kiev.ua/2007/03/13/report-in/</guid>
		<description><![CDATA[Рапорт на стол. Или короткая история о том, как надо писать отчеты. Все статьи цикла о JasperReports Если вы хоть раз писали серьезное бизнес-приложение, то вам наверняка знакомо желание заказчиков, пользователей или начальников пользователей контролировать каждый её вздох. Все начинается довольно безобидно: простые выборки, оформленные в виде табличек, всех устраивают и радуют глаз незамысловатым примитивизмом. [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Рапорт на стол.</strong><br />
<strong>Или короткая история о том, как надо писать отчеты.</strong></p>
<p><a href="http://voituk.kiev.ua/intro-jasper-reports/">Все статьи цикла о JasperReports</a></p>
<p>Если вы хоть раз писали серьезное бизнес-приложение, то вам наверняка знакомо желание заказчиков, пользователей или начальников пользователей контролировать каждый её вздох.<br />
Все начинается довольно безобидно: простые выборки, оформленные в виде табличек, всех устраивают и радуют глаз незамысловатым примитивизмом. Вскоре таблички становятся объемнее и пользователи просят &#8220;подсветить&#8221; те показатели, которые существенно отклоняются от нормы.<br />
Запросы к базе тоже не стоят на месте: они растут и усложняются, включают в себя все более запутанные связи и зависимости.<br />
На некотором этапе оказывается, что анализировать массивы чисел неудобно, а представленные результаты выглядят ненаглядно. Тогда к арсеналу табличек добавляется арсенал графиков. О, как же все они помешаны на графиках: больших и маленьких, круговых и сплайнах, двумерных и трехмерных, и побольше, побольше!<br />
В этот момент понимаешь, что обойтись простыми функциями вроде &#8220;resultSetToHtmlTable&#8221; уже не выйдет. В схватку вступают объекты, представляющие аггрегированные данные и объекты, умеющие красиво отобразить первые объекты.<br />
В этот момент начинаешь понимать, что попал в &#8220;смоляную яму&#8221;. Чем больше двигаешься, тем больше тебя засасывает.<br />
Но заказчику как правило этого недостаточно. Дальше заказчик хочет получить экспорт в пару-тройку &#8220;офисных&#8221; форматов, поскольку&#8230; да в общем причин может быть масса.</p>
<p>Только не подумайте, что я считаю требования бизнес заказчиков абсолютной чушью. Впрочем, я немного отклонился от темы.</p>
<p>Так случилось, что отчеты стали занимать слишком много времени. Кроме того, в процессе разработки нового отчета меня не покидало чувство изобретения велосипеда. Совершенно естественно, что я решил попробовать упростить себе жизнь и как можно более автоматизировать этот процесс.</p>
<p>Первое что попалось на глаза &#8211; BIRT: кусок проекта Calisto, прекрасно интегрируется в платформу Eclipse, но, увы, уж слишком тяжеловесен и тормознут. Да и вообще, продукт оставляет впечатление недопеченного пирога, оздобленного сверху шапкой из взбитых сливок: на demo ролике все выглядит очень хорошо, но первые же тесты быстро возвращают на землю.</p>
<p>После BIRT я наткнулся на Jasper. Симпатичная библиотека, о которой и пойдет речь ниже.<br />
<span id="more-146"></span><br />
Я не буду долго рассуждать о принципах работы библиотеки, а сразу кину &#8220;минимальный прожиточный&#8221; кусок кода, который покажет, как сделать простой проект a-la &#8220;Привет, мир!&#8221;. Да, да, именно &#8220;привет, мир&#8221;, а не &#8220;Hello, World!&#8221;, потому что после успешного &#8220;Hello, World!&#8221; я слишком много раз разбивал нос о &#8220;железный занавес локализации&#8221;.</p>
<p>Начало &#8211; вполне классическое: необходимо загрузить свежую версию библиотеки. Домашняя страничка проекта &#8211; <a href="http://jasperforge.org/sf/projects/jasperreports">http://jasperforge.org/sf/projects/jasperreports</a>, а скачать библиотеку можно тут: <a href="http://sourceforge.net/projects/jasperreports/">http://sourceforge.net/projects/jasperreports/</a> .<br />
Чтобы сгенерировать отчет, необходимо написать 2 файла: первый &#8211; xml c разметкой отчета, а второй &#8211; класс Java, который с помощью библиотек Jasper сгенерирует отчет по указанному xml.</p>
<p>Вот так будет выглядеть xml с разметкой отчета. Обратите внимание на строку  pdfFontName=&#8221;c:\tahoma.ttf&#8221;. По непонятной причине, если не указать явно путь к файлу шрифта, то PDF генерируется некорректно: русские буквы накладываются друг на друга.</p>
<pre><code>&lt;?xml version="1.0" encoding="windows-1251"?&gt;
&lt;!DOCTYPE jasperReport
  PUBLIC "-//JasperReports//DTD Report Design//EN"
  "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"&gt;

&lt;jasperReport name="simple"&gt;

	&lt;style
		name="Normal"
		isDefault="true"
		pdfFontName="c:\tahoma.ttf"
		pdfEncoding="Cp1251"
	 /&gt;

	&lt;detail&gt;
		&lt;band height="20"&gt;
			&lt;staticText&gt;
				&lt;reportElement x="180" y="0" width="200" height="20" /&gt;
				&lt;text&gt;&lt;![CDATA[Тест !!]]&gt;&lt;/text&gt;
			&lt;/staticText&gt;
		&lt;/band&gt;
	&lt;/detail&gt;
&lt;/jasperReport&gt;</code></pre>
<p>Java класс для генерации отчета выглядит намного проще:</p>
<pre><code class="java">import java.util.HashMap;

import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;

public class JasperHello {
	public static void main(String[] args) {
		try {
			JasperReport jasperReport = JasperCompileManager
				.compileReport("reports/hello.xml");

			JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,
				new HashMap(), new JREmptyDataSource());

			JasperExportManager.exportReportToPdfFile(jasperPrint, "reports/hello_report.pdf");
		} catch (JRException e) {
			e.printStackTrace();
		}
	}
}</code></pre>
<p>Я поместил файл hello.xml в папку reports в корне проекта. В эту же папку будет записан созданный отчет. Скомпилируйте и запустите класс. В папке reports должен был появиться файл <em>hello_report.pdf</em> &#8211; это и есть ваш первый отчет.</p>
<p>Как видно, процесс генерации отчета состоит из трех шагов: компиляция отчета, заполнение отчета данными (JasperFillManager.fillReport(&#8230;)) и экспорт отчета в файл.<br />
В нашем случае отчет не содержит никаких параметров и не работает с источниками данных, поэтому мы &#8220;заполняем&#8221; отчет пустышками: new HashMap() и new JREmptyDataSource() не передают в отчет абсолютно ничего.</p>
<p>Чтобы экспортировать отчет в другой формат, к примеру, в HTML, достаточно заменить строку</p>
<pre><code class="java">JasperExportManager.exportReportToPdfFile(jasperPrint,
	"reports/hello_report.pdf");</code></pre>
<p>на строку</p>
<pre><code class="java">JasperExportManager.exportReportToHtmlFile(jasperPrint,
	"reports/hello_report.html");</code></pre>
<p>Для начала &#8211; вполне достаточно. На сайте проекта есть масса примеров самых разных отчетов. Это самая лучшая демонстрация возможностей пакета.</p>
<p>Если статья вышла интересной &#8211; пишите комменты. В следующей статье я расскажу, как сгенерировать более &#8220;продвинутый&#8221; отчет, который использует БД в качестве источника данных.</p>
<p>Я создал небольшой видеоролик, который демонстрирует настройку Eclipse для работы с JasperReports, и процесс создания первого отчета. Видео есть <a href="http://voituk.kiev.ua/2007/03/16/jasperreports-video-kick-off/">тут</a>.</p>
<p>Следующая тема: <a href="http://voituk.kiev.ua/2007/03/15/jasperreports-db-support/">Работа с БД</a></p>
]]></content:encoded>
			<wfw:commentRss>http://voituk.kiev.ua/2007/03/13/report-in/feed/</wfw:commentRss>
		<slash:comments>45</slash:comments>
		</item>
	</channel>
</rss>

