<?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>PawaStation 能猫环岛 &#187; jasperreport</title>
	<atom:link href="http://blog.pawa.ca/tag/jasperreport/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.pawa.ca</link>
	<description>An Apple a Day Keeps the Doctor Away</description>
	<lastBuildDate>Sun, 08 Mar 2009 04:39:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>无尽欢乐 JasperReport</title>
		<link>http://blog.pawa.ca/2008/01/06/jasperreport_tips/</link>
		<comments>http://blog.pawa.ca/2008/01/06/jasperreport_tips/#comments</comments>
		<pubDate>Sun, 06 Jan 2008 06:48:04 +0000</pubDate>
		<dc:creator>pawaca</dc:creator>
				<category><![CDATA[tips]]></category>
		<category><![CDATA[jasperreport]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.pawa.ca/?p=43</guid>
		<description><![CDATA[上个月很磕了一下 JasperReport，再次亲身印证了 80/20 法则。。。今天抽空列出几个“看上去”都用不了多少时间就可以搞定的问题。 空白 pdf 报表 我用的是 Spring 中的 JasperReportsPdfView 来帮助整合生成 pdf，这本来应该是一个非常简单的过程：Controller 返回一个标识 JasperReportsPdfView 的 ModelAndView，然后 Spring 自动生成报表。我最开始尝试的时候这样写的 Controller： 12345protected ModelAndView handleRequestInternal&#40;HttpServletRequest request, &#160; &#160; &#160; &#160; &#160; &#160; HttpServletResponse response&#41; throws Exception &#123; &#160; &#160; return new ModelAndView&#40;&#34;pdfReport&#34;&#41;; &#125; pdfReport 对应一个 JasperReportsPdfView，并配置指向了一个不需要任何动态数据的 report.jrxml 模板。 打开浏览器访问 controller ，会返回生成后的 pdf，不过内容是空的。。。改来改去，折腾了半天，最后发现原来 即使模板不需要任何动态数据，还是要传递一个 dummy 过去，才可以 render 出结果 [...]]]></description>
			<content:encoded><![CDATA[<p>上个月很磕了一下 JasperReport，再次亲身印证了 80/20 法则。。。今天抽空列出几个“看上去”都用不了多少时间就可以搞定的问题。</p>

<h3>空白 pdf 报表</h3>

<p>我用的是 Spring 中的 JasperReportsPdfView 来帮助整合生成 pdf，这本来应该是一个非常简单的过程：Controller 返回一个标识 JasperReportsPdfView 的 ModelAndView，然后 Spring 自动生成报表。我最开始尝试的时候这样写的 Controller：</p>

<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">protected</span> ModelAndView handleRequestInternal<span style="color: #009900;">&#40;</span>HttpServletRequest request,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HttpServletResponse response<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Exception</span></a><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> ModelAndView<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;pdfReport&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>

<p>pdfReport 对应一个 JasperReportsPdfView，并配置指向了一个不需要任何动态数据的 report.jrxml 模板。 打开浏览器访问 controller ，会返回生成后的 pdf，不过内容是空的。。。改来改去，折腾了半天，最后发现原来 <strong>即使模板不需要任何动态数据，还是要传递一个 dummy 过去，才可以 render 出结果</strong> 。</p>

<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">protected</span> ModelAndView handleRequestInternal<span style="color: #009900;">&#40;</span>HttpServletRequest request,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HttpServletResponse response<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Exception</span></a><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; Map<span style="color: #339933;">&lt;</span>Object<span style="color: #339933;">&gt;</span> model <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HashMap<span style="color: #339933;">&lt;</span>Object<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// Spring 配置的默认 jasper datasource 在 map 中的名称是 'datasource'，这个名字可以配置。</span><br />
&nbsp; &nbsp; model.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;datasource&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> JRBeanCollectionDataSource<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> ArrayList<span style="color: #339933;">&lt;</span>Object<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> ModelAndView<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;pdfReport&quot;</span>,model<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>

<h3>文字消失</h3>

<p>开始在 dev 环境下生成好好的 pdf，放到 product 环境下变得无法完全显示所有文字。推测是嵌入字体问题，换来换去都不行。最后想起  product 环境是 windows，而 dev 环境是 linux，digg 了许久文档，终于找出原因。原来 JasperReport 在生成 pdf 的时候 text 的 layout 是以 fontName 这个属性为基准，用 Java 的 <span class="caps">AWT </span>里算出字的高度，而最终显示在 Adobe Reader 中的事根据 pdfFontName 这个属性。很显然， Linux 和 Windows 下面算出的文字高度不同。Linux下面可以显示，但是 Windows 下面高度就不够了，所以出现了缺字的现象。解决办法就是把 TextField 的高度加 4 px 左右。后来还想出一个方法是设置 stretch with overflow 那个属性，不过没有具体测试。</p>

<h3>isStretchWithOverflow 失灵</h3>

<p>用户输入的多行文字不能完全显示，只显示了在 iReport 里面设计时候的那部分，仿佛 isStretchWithOverflow 设置了跟没设置一样。又是昏天黑地的 digg，最后发现原因在客户端录入，Flex 的文本域 line separator 竟然是 \r 。Java 这边则是 \n，JasperReport 的文本 stretch 很可能是数文本有多少个 line separator 然后算出总高度，结果当然是算不出实际的行数。解决的办法是在把文本发到 JasperReport 之前，先 correct line separator。</p>

<h3>总结</h3>

<p>是福不是祸，是祸躲不过。上面的问题每一个都耗掉 2 hours+ 的时间来 debug，记在这里，希望可以造福后人。另外有一点比较奇怪的是，JasperReport 的论坛好像完全没有被 google index，出了问题一定要到 <a href="http://www.jasperforge.org/jaspersoft/opensource/business_intelligence/jasperreports/faq.html">这里</a> 和 <a href="http://www.jasperforge.org/index.php?option=com_joomlaboard&amp;Itemid=215&amp;func=showcat&amp;catid=8">这里</a> 才可以啊。囧</p>


<p>我佛慈悲。。。</p>]]></content:encoded>
			<wfw:commentRss>http://blog.pawa.ca/2008/01/06/jasperreport_tips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
