前言:
之前写了2篇关于JasperSoft的文章,当时调通了,以为万事大吉了就放了一段时间。
结果等到现在用的时候重新捡起来发现问题是真的多,下面就一一罗列一下。
前2篇文章传送门:jasperreport JAVA API集成到spring boot中
jasperreport+jaspersoft生成报表并集成到spring boot中
一 PDF中文问题
之前的技术是Jasper 5.6.0版本,解决中文用了itext-2.1.7.js2.jar和
itextasian-2.1.7.js2.jar两个文件,而且需要自己手动maven安装也很麻烦。但是
这次我按照这个方法配置的时候竟然死活出不来中文,只好放弃,另寻办法。
参考Jasperreports6.3.1+Jaspersoft studio6.3.1进行报表开发实战教程(七)-PDF中文显示
Jasperreports6.4.1+Jaspersoft studio6.4.1进行报表开发实战教程-PDF中文显示
这2篇干货之后发现了一个比较好的办法。懒的话,可以直接看我下面总结的办法。
1.1 给jaspersoft studio添加中文字体。
核心:安装jaspersoft studio,然后手动添加中文字体,比如微软雅黑,然后给模板中涉及到
中文的地方设定字体为新增加的字体。
首先搞到自己想要的字体,网上下载或者windows系统里复制也行,我用的是ttf格式,ttc的没试
过,估计也能用。
如下图打开jaspersoft studio的设置
点击add,找到准备好的字体。
给编辑器增加好自己的字体后,中文显示的时候选择刚添加的字体即可
这样一来在studio里面预览的时候就能展示中文了。
1.2 java API 使用中文字体
如下图在resources或classes下增加一些文件。
1.2.1 jasperreports_extension.properties
net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.msyh=jaspertemplate/fonts/fonts.xml
第一行不用改,打开SimpleFontExtensionsRegistryFactory可以看到定义了这2个配置。
net.sf.jasperreports.extension.simple.font.families. 是关键字,后面的内容随便写都行,建议和字体名称一样。
后面的value指向fonts.xml文件,使用相对路径即可。
1.2.2 fonts.xml
jaspertemplate/fonts/msyh.ttf
jaspertemplate/fonts/msyh.ttf
jaspertemplate/fonts/msyh.ttf
jaspertemplate/fonts/msyh.ttf
Identity-H
true
'msyh', Arial, Helvetica, sans-serif
'msyh', Arial, Helvetica, sans-serif
这里有意思的是,我的字体文件是msyh.ttf,上面配置的时候用的是msyh.TTF,注意这里的
大小写区别。使用TTF的配置在macos和windows均测试通过,但是部署到远端centos时会报
net.sf.jasperreports.engine.util.JRFontNotFoundException:
Font ‘msyh‘ is not available to the JVM. See the Javadoc for more details.
遍寻网上解决办法,花了2天没一个能解决问题。后来改了小写与文件名匹配后就能展示了。
如果不信的可以自己改了试试。
1.2.3 放入之前下好的ttf文件即可
以上3步即可解决中文字体问题。如果是添加多个字体也是一样的操作。
二 使用javabean作为数据源
我前面2篇文章提到了2种连接数据的方式,
1 使用报表模板自身配置好的sql语句
2 在java中创建DataSource dbSource并执行代码写好的sql语句
但是实际业务中会复杂的多,需要考虑到权限等等。
我目前的业务需求是在列表页查询数据并勾选某几条进行打印。
核心是调用已经写好的查询数据接口返回data数据,将其塞到JRBeanCollectionDataSource
中作为数据源即可。这样就能很好的与现有的业务逻辑相结合。
@GetMapping("/order")
public ModelAndView getOrderReport(final ModelMap modelMap,
@RequestParam("reportName") final String reportName,
@RequestParam("format") final String format,
@RequestParam("code") final List codeList) {
List list = new ArrayList<>();
if (CollectionUtils.isNotEmpty(codeList)) {
for (String code : codeList) {//根据订单号查询订单信息,可改成自己的业务逻辑
PurchaseOrderData orderData = purchaseOrderFacade.getPurchaseOrderByCode(code);
list.add(orderData);
}
JRDataSource jrDataSource = new JRBeanCollectionDataSource(list);
modelMap.put("datasource", jrDataSource);
modelMap.put("format", format);
return new ModelAndView(reportName, modelMap);
}
return null;
}
上面的逻辑是根据传过来的订单号获取订单信息,并打印到报表,仅供参考。
需要注意的是:比如PurchaseOrderData里定义了
String a;
Integer b;
....
等属性,那么在设计报表的时候每一个field和类型都需要一一对应。
这两个地方对应上之后,设计报表就可以无需写任何sql,只要你的bean有数据就可以直接展示。
------------------------------------------------------------------------------------------------------------------------------
个人记录一下方便以后自己查看。
如果有做复杂点的报表比如子报表等可以看我的下一篇文章。