1、使用Jaspersoft Studio制作PDF模板,生成一个jrxml文件。
2、编译jrxml文件,生成jasper文件,然后复制到springboot工程中的resources目录下。
3、引入所需依赖
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.19.0</version>
</dependency>
4、创建jasper文件的输入流对象,查询数据库,得到报表所需的数据,填充到PDF里面,然后将PDF文件以字节流的的形式导出到浏览器,实现文件下载,代码如下所示
@SneakyThrows
@GetMapping("/{id}/pdf")
public void pdf(@PathVariable String id, HttpServletResponse response){
ClassPathResource resource = new ClassPathResource("templates/profile.jasper");
FileInputStream fis = new FileInputStream(resource.getFile());
ServletOutputStream sos=null;
try {
response.addHeader("Content-Disposition","attachment;filename=employee.pdf");
sos= response.getOutputStream();
//员工详情
UserCompanyPersonal personal = userCompanyPersonalService.getById(id);
//员工岗位信息
UserCompanyJobs jobs = userCompanyJobsService.getById(id);
//员工头像
String staffPhoto = systemFeignClient.getPhoto(id);
Map<String,Object> params=new HashMap<>();
Map<String, Object> personalMap = BeanMapUtils.beanToMap(personal);
Map<String, Object> jobsMap = BeanMapUtils.beanToMap(jobs);
params.putAll(personalMap);
params.putAll(jobsMap);
params.put("staffPhoto",staffPhoto);
JasperPrint jasperPrint = JasperFillManager.fillReport(fis, params,new JREmptyDataSource());
JasperExportManager.exportReportToPdfStream(jasperPrint,sos);
}finally {
sos.flush();
sos.close();
}
}
其中,params是一个map对象,用来向PDF填充数据,如果先执行
params.put("staffPhoto",staffPhoto);
后执行
params.putAll(personalMap);
params.putAll(jobsMap);
会导致params中的staffPhoto值为空,最终导致PDF导出为空,代码运行报错,而且personalMap和jobsMap里面都不包含staffPhoto这个键。这种现象出现的很奇怪,因为这个错误,卡了我很久,后来通过debug打断点才发现问题所在。
5、JasperReport默认情况下不支持中文,因此会导致PDF中的中文不能显示,解决办法就是在resources中添加fonts.xml、stsong.TTF和jasperreports_extension.properties三个文件,如下所示
其中,stsong.TTF是华文宋体的字体文件,fonts.xml代码如下所示
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
<!--<fontFamily name="Lobster Two">-->
<!--<normal>lobstertwo/LobsterTwo-Regular.otf</normal>-->
<!--<bold>lobstertwo/LobsterTwo-Bold.otf</bold>-->
<!--<italic>lobstertwo/LobsterTwo-Italic.otf</italic>-->
<!--<boldItalic>lobstertwo/LobsterTwo-BoldItalic.otf</boldItalic>-->
<!--<pdfEncoding>Identity-H</pdfEncoding>-->
<!--<pdfEmbedded>true</pdfEmbedded>-->
<!--<!–-->
<!--<exportFonts>-->
<!--<export key="net.sf.jasperreports.html">'Lobster Two', 'Times New Roman', Times, serif</export>-->
<!--</exportFonts>-->
<!--–>-->
<!--</fontFamily>-->
<fontFamily name="华文宋体">
<normal>stsong/stsong.TTF</normal>
<bold>stsong/stsong.TTF</bold>
<italic>stsong/stsong.TTF</italic>
<boldItalic>stsong/stsong.TTF</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'华文宋体', Arial, Helvetica, sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'华文宋体', Arial, Helvetica, sans-serif</export>
</exportFonts>
<!--
<locales>
<locale>en_US</locale>
<locale>de_DE</locale>
</locales>
-->
</fontFamily>
</fontFamilies>
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.dejavu=stsong/fonts.xml