JasperReport常见问题有哪些?

JasperReport常见问题有哪些?

  1. JasperReport 常见问题
  2. .jrxml vs .jasper
    • 如果在运行时载入.jrxml, 那么每次调用还得编译, 不如预先编译成.jasper.不过预先编译的jasper,必须用同样版本的JasperReport载入,而且灵活性差些. 不过对于大部分报表,还是预先编译成jasper方便
  3. 如果批量编译jrxml
    • 用Ant很容易解决

      ?

      .....

      ?

       
  4. 如何使用图片?
    • 很容易,用Image控件就可以了. 在Image Express里面可以用String来表示图片的路径, 或者用InputStream, File对象.不过不管用File还是String对象, 都不得不用绝对路径, 这显然很不灵活. 解决办法是,穿入一个$P的参数,表示图片所在的目录,然后用$P和文件名拼接出完整的绝对路径. 更好的方法是用InputStream, 例如this.getClass().getResourceAsStream("logo.jpg")?,这时只要把图片放在当前.jasper所在的目录就可以了,不必考虑什么参数,什么路径了
  5. 显示非数据库字段变量
    • 显示如运行日期等,可以直接在Text Field里面输入new java.util.Date(), 然后把Pattern设成如mm/dd/yyyy.
  6. 动态控制某些Field是否显示
    • 每个Static Text, Text Field甚至整个Band的属性里面都有Print When Expression, 比如设成new Boolean(!$P{isDisplay}.equalsIgnoreCase("yes")), 那么只有当参数display的值为yes的时候才显示
  7. 使用Sub Report, 如何使用相对路径
    • 见1.3, 和使用图片类似, 用InputStream或者传入参数
  8. Query里面如何使用参数
    • $P!{xxx} 或者 $P{xxx} 后者只能用于类似PreparedStatement参数绑定, 而前者可替换Sql的任意部分. 在需要动态排序的时候, 前者特别有用. 比如 select a,b,c from t order by $P!{orderClause}???不管用$P还是$P!, SQL最终是以PreparedStatement方式执行的, 不必太担心性能问题?? 注意:参数是不能嵌套的, 比如$P{a} =''$P{b}''?? , $P{b}=''value'', 不要指望$P{a}能被替换成''value''
  9. 如何使用图表(Graph)
    • JasperReport本身没有图表功能, 只有显示Image的功能(见4.3). iReport里有个Graph向导, 其实质是通过jFreeChart生成Image. 更另外, 更直接的做法是放一个Image控件, Image Express Class设置成java.awt.Image, 在Image Expression里通过自定义的类返回java.awt.Image对象. 例如''GraphProvider.getImage($P{REPORT_DATASOURCE},title, subtitle.....)''.? GraphProvider是自己的类, public static Image getImage(JRDataSource, ....)
  10. 如果显示多个图表
    • 在一张报表上显示一个图表和显示多个图表是不同的. 假设Query是select name,price,qty from xxx, 第一张图显示name-price, 第二张图显示name-qty, 如果还是按3.8的方法, 第二张图根本显示不出来! 为什么? 因为传入的是JRDataSource, 而JRDataSource仅仅是对ResultSet的简单封装, 在第一张图处理完后, 游标已经到了eof位置了, 在开始处理第二张图的时候,就必然抛出游标耗尽的异常! 怎么办?? 自己写个JRDataSourceAdapter, 把JRDataSource对象里面的值预先保存到一个Collection (相当于一个Offline的数据集), 然后把这个Collection传个getImage方法. 具体是, 建一个Variable? mydate, 类型是java.util.Map, Calculation Type- System, Initial Value Expression是JRDataSourceAdapter.JRDataSource2Map($P{REPORT_DATA_SOURCE}, new String[]{"NAME","PRICE","QTY"},new Class[]{java.lang.String.class,java.lang.Double.class,java.lang.Double.class}), JRDataSource2Map是自己写的一个Adapter. 然后在Image的Expression里面换成如''GraphProvider.getImage(mydata,title, other params...), 当然得修改getImage方法
  11. Export到Excel的问题
  12. 如何去掉报表头等
    • 直接把不需要的Band删除(把其高度设为0). 如果仅仅是export到Excel的时候不需要报表头, 而输出到PDF等仍然需要保留, 那么使用print when expression, 见4.4
  13. 如果让Excel看起来整齐
    • 不要有空白地方! 首先把所有的Field设成一样高, 对齐! 把所在Band的高度也设成和Field一样高, 让Field正好放入Band. 然后调整Field的宽度, 让每个Field都相邻,没有空隙. 最后,记得设置参数: exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,
      ??????????????????? Boolean.TRUE);
  14. 如何保留GridLine
    • 首先, 设置参数exporter.setParameter (JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE); 然后,把每个Field或者Static Text框的''Transparent''属性都勾上
  15. 如何使字段名只显示一次
    • 如果把字段名放在ColumnHead区域, 那么输出到Excel, 会每个Page都显示一遍. 在设计Report时候, 一般会设定Page大小. 然而对于Excel, 这个Page设定仍然存在,而且往往很讨厌, 因为在Excel里, 通常希望得到连续的数据, 然而Jasper仍然会''自作多情''进行分页. 比如说, 设计JasperReport的时候, 设定page size为Letter, Portrait, 那么输出到Excel的时候每隔大约30行(具体取决于Field的高度), page header, column header, column foot, page foot 会被重复一次, 而且还附带一个高度为0的Excel Row, 表示Page Break的地方. 把字段名放在title band里, 可以解决字段名重复的问题, 当然page header也不要显示了. 如果需要, 可以把title band的print when expression设成只有输出Excel的时候才显示
  16. 为什么Excel里面的数据是从第二行,第B列开始显示的?
    • 因为第一行和第A列分别是用来表示page top margin 和 page left margin的. 对于Excel来说, 纯粹多余. 解决方法是把page margin 设成0. 不过如果这个report还需要以PDF等显示, 那么设成0就不好看了. 最好能动态的改变page margin. 当然,这个改变只能在外部(调用Report的地方) 进行, 在设计Report的时候是无能为力的. 不幸的是, JasperReport类居然没有setMargin的方法,只有getter. 折中的方法只能是reflect了. 代码示意如下: //use reflect to set the private field of JRBaseReport
      ???????????????? java.lang.reflect.Field margin = JRBaseReport.class.getDeclaredField(
      ??????????????????????? "leftMargin");
      ??????????????? margin.setAccessible(true);
      ??????????????? margin.setInt(myRpt, 0); ??????????????? margin = JRBaseReport.class.getDeclaredField("topMargin");
      ??????????????? margin.setAccessible(true);
      ??????????????? margin.setInt(myRpt, 0); ??????????????? margin = JRBaseReport.class.getDeclaredField("bottomMargin");
      ??????????????? margin.setAccessible(true);
      ??????????????? margin.setInt(myRpt, 0);
  17. 如何去掉Excel中隐藏的行?
    • 如前说述, 由于page break的关系, Excel中每隔几十行,就有一个高度为0的row, 即使把page botom margin设为0, 把page footer去掉都没有办法. 唯一的解决办法是把page height设为很大. 同5.5一样, 不得不使用reflect:
      • java.lang.reflect.Field pageHeight = JRBaseReport.class.getDeclaredField(
        ??????????????????????? "pageHeight");
        ??????????????? pageHeight.setAccessible(true);
        ??????????????? pageHeight.setInt(myRpt, Integer.MAX_VALUE);
  18. 文档

    1. 哪里有文档?
      • JasperReport有份Ultimate Guide, 不过不是免费的, 和jFreeChart一个德行. 不过网上有流传, 写的还可以, 60多页, 不过也没详细到哪里去. 如果下载源代码版, 那么看看自带的Demo也不错. SF的论坛也是问问题的最好地方