Jasper使用小结

 

     最近项目中要使用到单据的打印功能,于是采用了jasper来实现这个feature。由于之前没有开发过类似的功能,做的过程中也走了一些弯路,并且总结了一些经验,正好记录下来。

     一、为什么要使用报表工具进行打印

     首先,需要打印的内容是业务表数据的一部分,因此牵涉到数据查询,采用报表对SQL的支持进行查询是很方便的。

     其次,打印一般对格式要求很高,采用报表设计工具可以很直观的调整格式(当然,HTML编辑器也有类似功能)。尤其对于分页的报表,HTML并没有直接的对分页进行支持,因此可能出现由于页边距的打印设置问题,导致分页错乱。

     二、JASPER使用示例

     a) 报表设计器iReport

     iReport是Jasper Report自带的一个设计器,最牛逼的是,居然也支持Mac平台。各项拖拽操作都非常顺畅,而且可以显示虚线来对齐(和QQ拼音有兼容问题,容易导致Jasper崩溃)。

 

 

     b) 和Struts2进行整合

     官方文档:http://struts.apache.org/2.0.11.2/docs/jasperreports-tutorial.html 

     不过官方介绍的是以DataSource的形式传递数据,也就是在Action中进行查询,然后将查询结果传递给报表引擎。但是在后来的实践中,我觉得这样做不是很好。

     首先,你无法直接在iReport中预览列表结果,因为需要传递一个List对象(部署到服务器上再预览结果是很费事的);

     其次,在报表中,我们一般习惯写SQL语句。至少可以进行SQL的优化调整。报表对性能的要求与普通应用不一样,基本是固定的数据库查询,因此我认为使用SQL作为查询语句是非常合适的。

     下面介绍如何在报表中编写查询语句:

     i. 通过Struts传递数据库连接

 

 

     上面两个图中红色部分,就是如何将数据库连接传递给Jasper引擎的方法。有了数据库连接,我们就可以在iReport里直接写SQL了。当然,这是运行时数据库的连接传递方式。在iReport中,可以直接指定数据库连接,这个连接在运行时会被替换为Struts传递过来的Connection

 

 

     点击上图中红色圆圈处,就可以编辑iReport所使用的数据库连接。

     ii. 我们再看一下iReport自带的Query Designer

 

这个Query Designer非常智能,支持你从左侧拖拽表到右侧区域,勾选需要显示的列,以及拖拽关联字段建立表之间的关联关系,自动的生成SQL语句(强烈推荐使用)。

 

 

 

 

其实Jasper还可以支持很多其他的查询语言,包括HQL。我这里就不实验了。因为我觉得,报表还是处理关系数据,因此SQL肯定更合适一些。

     关于Jasper各个Band的功能这里不做介绍。不过这种区分对于报表开发是非常好的,体现了Jasper对报表技术要求的深入理解和良好设计。

     iii. 如何格式化数据:

 

 

 

    上图的红色部分,就是Jasper中的表达式语法。Jasper支持多种表达式语法,包括JavaGroovy等。尤其是支持java类的调用。可以看到上图中就是利用了javaformat功能,拼成一个字符串。

     合理的利用表达式非常重要。因为这种用于显示的值,使用java这种强类型语言编写非常麻烦,有时候还要处理异常。而表达式非常适合这种情况,简单,高效,方便修改。因此千万不要将这种代码写在你的Action里,Action应该只负责数据的加载和保存等,不负责数据的显示。

     iv. iReport的预览功能

 

 

     

 

 

     点击上图的预览按钮,有可能出现下面的参数输入界面:

 

 

     这取决于你的报表是否需要参数。当然,大部分报表都需要传递查询参数。这里你可以输入一个有查询结果的参数值,以方便预览报表查询结果。

     v. 查询结果导出

     Jasper支持非常多的格式显示查询结果。包括常见的HTMLPDFEXCEL等等。因此,Jasper也是一个很好的导出解决方案。

 

 

     你可以指定Jasper以什么格式输出结果,如上图所示(在Struts应用中)。

     下面我简单解释一下,为什么要使用PDF来显示查询结果,而不用常见的HTML

     首先,HTML不支持分页。Jasper之所以可以使HTML报表产生分页的效果,是基于对高度的计算。但是这个计算显然会依赖于页边距的设置。如果页边距不同,那么就可能造成分页错误。而且各个浏览器对于页边距的默认值都是不一样的,因此很难做到通用(我们不可能给每个客户端调整一下页边距);

     但是PDF对于分页的支持是全面的,而且格式是通用的,在任何PDF浏览器中,都不可能产生串页的现象。而且现在PDF应该也是一个广泛接受的标准,客户机几乎不需要任何特别的设置(对于没有安装PDF阅读器的机器,可能需要安装一下)。

     总结到这里,以后有了新的想法,还会更新。下一步将尝试一下图表功能以及其他的报表工具,例如BIRT等。

 

 

 


 

<think>我们正在讨论Jasper Reports中添加图片水印的方法。根据用户的问题,他希望在Jasper Reports中使用图片作为水印。 在Jasper Reports中,水印通常是通过在报表背景中添加一个覆盖整个页面的图像或文本元素来实现的。由于水印需要在每一页都显示,因此我们需要将其放置在报表的背景带(background band)中。 步骤: 1. 在报表设计文件中,确保有Background band。如果没有,可以添加。 2. 在Background band中添加一个图片元素(image element)。 3. 设置图片的属性,使其平铺或拉伸以覆盖整个页面,并调整透明度以达到水印效果。 具体操作: a. 打开JasperReport模板(.jrxml文件)。 b. 在报表的根元素下,确保有<background>元素。如果没有,可以手动添加: <background> <band height="802" splitType="Stretch"> <!-- 高度根据页面设置调整 --> </band> </background> c. 在<band>元素内添加一个图片元素: <image> <reportElement x="0" y="0" width="595" height="842" uuid="..."/> <!-- 宽度和高度设置为页面大小(例如A4是595x842) --> <imageExpression><![CDATA["path/to/your/watermark.png"]]></imageExpression> </image> d. 为了达到水印效果,我们需要设置图片的透明度。在Jasper Reports中,可以通过设置<reportElement>的opacity属性(0.0到1.0之间,0.0完全透明,1.0不透明)来实现。例如,设置透明度为0.3: <reportElement x="0" y="0" width="595" height="842" uuid="..." opacity="0.3"/> e. 另外,如果希望图片居中且不拉伸,可以设置缩放模式(scaleImage属性)。例如,使用“Clip”模式保持原图大小,但这样可能无法覆盖整个页面。因此,我们通常使用“FillFrame”来填充整个区域,但这可能会使图片变形。另一种方法是使用“RetainShape”来保持比例并尽可能填充,但可能留白。根据需求选择。 注意:图片路径可以是绝对路径、相对路径,或者是通过参数传递的路径。也可以将图片编译到报表中(使用isLazy属性或者将图片作为参数传入)。 另外,也可以考虑使用静态图片资源,将其作为资源绑定到报表。例如,在JasperSoft Studio中,可以将图片添加到资源文件夹,然后在图像表达式中使用类似: <imageExpression><![CDATA["watermark.png"]]></imageExpression> 并在报表属性中设置资源文件夹路径。 如果需要在运行时动态设置水印图片,可以通过参数传递图片的路径或输入流(java.io.InputStream)。例如: <parameter name="WatermarkImage" class="java.lang.String"/> <!-- 或者使用java.io.InputStream --> ... <imageExpression><![CDATA[$P{WatermarkImage}]]></imageExpression> 重要:如果使用InputStream,需要在填充报表时传入该参数。 代码示例(在Java中填充报表时设置参数): Map<String, Object> parameters = new HashMap<>(); parameters.put("WatermarkImage", new FileInputStream("path/to/watermark.png")); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource); 但是,请注意,在Background band中使用图片时,要确保图片不会因为数据带的内容过多而被覆盖。Background band是绘制在最底层的,所以通常不会覆盖。 另外,如果希望水印在每一页都显示,Background band是自动在每一页显示的。 总结:在Background band中添加一个图片元素,调整其大小和位置覆盖整个页面,并设置透明度。 下面是一个简单的jrxml片段示例: <jasperReport ...> <background> <band height="842" splitType="Stretch"> <image> <reportElement mode="Opaque" x="0" y="0" width="595" height="842" backcolor="#FFFFFF" uuid="..." opacity="0.3"/> <imageExpression><![CDATA["watermark.png"]]></imageExpression> </image> </band> </background> ... <!-- 其他带,如title, pageHeader, detail等 --> </jasperReport> 注意:这里将背景带的高度设置为842,宽度595(A4),并且图片元素也相应设置。实际值应根据页面尺寸调整。 如果水印图片需要重复平铺,目前Jasper Reports没有内置的平铺功能,但可以通过自定义元素或使用子报表等方式实现。不过,更简单的方法是准备一张已经平铺好的大图(覆盖整个页面),然后直接使用。 另外,也可以使用多个图片元素来手动平铺,但这样比较繁琐。 因此,推荐的方法是提前处理好水印图片(比如使用图像处理软件制作好覆盖整个页面的半透明水印图)。 相关问题: 1. 如何在Jasper Reports中设置背景图片的透明度? 2. 如何将图片作为参数传递给Jasper报表? 3. 在Jasper Reports中,Background band和Title band有什么区别? 4. 如何在Jasper Reports中实现水印文字的添加? 5. 如何让一张图片在Jasper报表的每一页都显示? 注意:用户的问题是针对图片水印,但我们也可以顺便提一下文字水印,因为问题相关。 文字水印:在Background band中添加一个静态文本或文本框,设置其位置覆盖整个页面,并设置旋转、字体、颜色和透明度。例如: <staticText> <reportElement x="0" y="0" width="595" height="842" uuid="..." rotation="45" opacity="0.3"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font size="72" isBold="true" isItalic="true"/> </textElement> <text><![CDATA[CONFIDENTIAL]]></text> </staticText> 以上。 </think>### Jasper Reports 添加图片水印的方法 在 Jasper Reports 中实现图片水印的核心思路是**将水印图片放置在报表背景层**,通过调整透明度实现水印效果。以下是具体步骤(基于 JRXML 模板): --- #### 方法 1:使用 `background` 带区(推荐) ```xml <jasperReport> <!-- 添加背景带区 --> <background> <band height="842" splitType="Stretch"> <!-- 高度=页面高度 --> <image> <!-- 覆盖整个页面 --> <reportElement x="0" y="0" width="595" height="842" <!-- 页面尺寸(A4: 595×842) --> uuid="..." opacity="0.3" <!-- 关键:设置透明度(0-1) --> /> <imageExpression> <![CDATA["watermark.png"]]> <!-- 图片路径 --> </imageExpression> </image> </band> </background> <detail> <!-- 报表主体内容 --> </detail> </jasperReport> ``` #### 关键参数说明: 1. **`<background>` 带区** 自动在所有页面底部渲染,确保水印出现在每页 2. **`opacity` 属性** `0.3` 表示 30% 透明度(值越低越透明) 3. **图片路径** 支持绝对路径、类路径资源(如 `classpath:/images/watermark.png`)或动态参数 --- #### 方法 2:通过 Java 代码动态添加 ```java // 填充报表时动态设置水印 try (InputStream watermark = getClass().getResourceAsStream("/watermark.png")) { Map<String, Object> params = new HashMap<>(); params.put("WATERMARK_IMG", watermark); // 传入图片流 JasperPrint print = JasperFillManager.fillReport( "template.jasper", params, dataSource // 数据源 ); // 导出PDF JasperExportManager.exportReportToPdfFile(print, "output.pdf"); } ``` 在 JRXML 中引用参数: ```xml <image> <reportElement ... opacity="0.3"/> <imageExpression><![CDATA[$P{WATERMARK_IMG}]]></imageExpression> </image> ``` --- #### 注意事项: 1. **图片层级控制** 确保水印在 `<background>` 带区,否则可能被主体内容覆盖 2. **格式兼容性** 推荐使用 PNG(支持透明度)或 JPG 3. **性能优化** 大尺寸图片会降低渲染速度,建议: - 使用 `isLazy="true"` 延迟加载 - 压缩水印图片分辨率 4. **旋转效果**(可选) 添加 `rotation="45"` 属性使水印倾斜(单位:度) ```xml <reportElement ... rotation="45" opacity="0.2"/> ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值