Chart图表
创建模板
- 创建模板,删除不需要的band,保留title和summary。
- 创建fifileds
- 创建chart图标
第一步:palette面板找到chart图表,拖拽到Summary中
第二步:选择需要的图表类型
第三步:设置图表参数
Key: 圆饼图的内容是什么,也就是下面的 First,Second…的内容
Value:这个圆饼图的比例依据,根据 Value 属性来显示每个 Key 占的比例
Label:显示标签
骚戴理解:可以通过下面的图来更好的理解
PDF输出
实体类
package cn.itcast.domain; public class UserCount { private String company; private Long count; public UserCount(String company, Long count) { this.company = company; this.count = count; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } public Long getCount() { return count; } public void setCount(Long count) { this.count = count; } }
骚戴理解:上面的这个对象的属性名要和Jaspersoft Studio的Fields里面的保持一致!
PDF输出
package cn.itcast.controller; import cn.itcast.domain.User; import cn.itcast.domain.UserCount; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JasperExportManager; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController public class JasperController06 { /** * charts图形报表 */ @GetMapping("/testJasper6") public void createPdf(HttpServletRequest request, HttpServletResponse response) throws Exception { //1.引入jasper文件 Resource resource = new ClassPathResource("templates/testCharts.jasper"); FileInputStream fis = new FileInputStream(resource.getFile()); //2.创建JasperPrint,向jasper文件中填充数据 ServletOutputStream os = response.getOutputStream(); try { Map parameters = new HashMap<>(); //构建javaBean的数据源 //1.获取到对象的list集合 List<UserCount> userList = getUserCountList(); //2.通过list集合创建javaBean的数据源对象 JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(userList); JasperPrint print = JasperFillManager.fillReport(fis,parameters,ds); JasperExportManager.exportReportToPdfStream(print,os); } catch (JRException e) { e.printStackTrace(); }finally { os.flush(); } } public List<UserCount> getUserCountList() { List<UserCount> list = new ArrayList<>(); UserCount uc1 = new UserCount("传智播客",1000l); UserCount uc2 = new UserCount("黑马程序员",1000l); UserCount uc3 = new UserCount("baidu",1000l); list.add(uc1); list.add(uc2); list.add(uc3); return list; } }
父子报表
概述
复杂报表或数据内容较多的时候,可以使用子报表解决。
制作父报表
首先制作父报表,就是调用子报表的一个基础报表。主报表的作用有如下两种: 父报表中需要显示数据,使用子报表弥补studio设计的不足,父报表不需要显示任何数据,只是作为子报表的载体。适用于复杂报表的设计
制作子报表
点击组件面板上的“Subreport”按钮,拖动到报表工作区上。
系统会自动弹出子报表选择窗口。可以选择创建一个新报表,还是使用一个已有的报表作为子报表。
选择“Create a new report”,可以立即制作新的子报表;
如果选择“Just create the subreport element”,系统会生成一个子报表区,可以在之后挂接需要的子报表。
如果选择“Select an existing report”,则可以调用已经有的报表作为子报表;然后选择“Select a report file...”,选择第一个从控制台资源里获取子报表
选择需要导入的子报表,例如我这里选择mysql这个子报表
生成的效果就是下面这样的!
参数传递
PDF输出
package cn.itcast.controller; import cn.itcast.domain.UserCount; import net.sf.jasperreports.engine.*; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController public class JasperController07 { /** * 父子报表 */ @GetMapping("/testJasper7") public void createPdf(HttpServletRequest request, HttpServletResponse response) throws Exception { //1.引入jasper文件 Resource resource = new ClassPathResource("templates/main01.jasper"); FileInputStream fis = new FileInputStream(resource.getFile()); //2.创建JasperPrint,向jasper文件中填充数据 ServletOutputStream os = response.getOutputStream(); try { Map parameters = new HashMap<>(); //参数 子报表的路径 子报表需要的数据 Resource subResout = new ClassPathResource("templates/testCharts.jasper"); parameters.put("sublist",getUserCountList());//子报表需要的数据 parameters.put("subpath",subResout.getFile().getPath());// 子报表的路径 JasperPrint print = JasperFillManager.fillReport(fis,parameters,new JREmptyDataSource()); JasperExportManager.exportReportToPdfStream(print,os); } catch (JRException e) { e.printStackTrace(); }finally { os.flush(); } } public List<UserCount> getUserCountList() { List<UserCount> list = new ArrayList<>(); UserCount uc1 = new UserCount("传智播客",1000l); UserCount uc2 = new UserCount("黑马程序员",1000l); UserCount uc3 = new UserCount("baidu",1000l); list.add(uc1); list.add(uc2); list.add(uc3); return list; } }
用户档案下载
搭建环境
配置坐标
<dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>6.5.0</version> </dependency> <dependency> <groupId>org.olap4j</groupId> <artifactId>olap4j</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> <version>2.1.7</version> </dependency>
解决乱码问题
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.lobstertwo=stsong/fonts.xml
骚戴理解:通过在导出pdf报表时候会出现中文乱码的问题,只需要把上面标出来的部分导入到项目里即可,然后在设计模板的时候中文都用华文宋体!
实现用户档案下载
/** * 打印员工pdf报表 */ @RequestMapping(value = "/{id}/pdf" , method = RequestMethod.GET) public void pdf(@PathVariable String id) throws IOException { //1.引入jasper文件 org.springframework.core.io.Resource resource = new ClassPathResource("templates/profile.jasper"); FileInputStream fis = new FileInputStream(resource.getFile()); //2.构造数据 //用户详情数据 UserCompanyPersonal personal = userCompanyPersonalService.findById(id); //用户岗位信息数据 UserCompanyJobs jobs = userCompanyJobsService.findById(id); //用户头像http://ruya1a2n3.hd-bkt.clouddn.com/1659438854295257088?t=1684575706082 String staffPhoto = "http://ruya1a2n3.hd-bkt.clouddn.com/" + id + "?t=100"; //3.填充pdf模版数据,并输出pdf Map 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); ServletOutputStream sos = response.getOutputStream(); try{ JasperPrint print = JasperFillManager.fillReport(fis , params , new JREmptyDataSource()); JasperExportManager.exportReportToPdfStream(print , sos); }catch (JRException e){ e.printStackTrace(); }finally { sos.flush(); } }
骚戴理解:注意上面的 staffPhoto图片路径要写自己的七牛云域名!!!然后要用要把数据库里bs_user表里的staff_photo都改成七牛云的url路径(因为只有有的是data url的路径),不然通过Postman测试会下面的报错
BeanMapUtils
package com.ihrm.common.utils; import org.springframework.cglib.beans.BeanMap; import java.util.HashMap; import java.util.Map; public class BeanMapUtils { /** * 将对象属性转化为map结合 */ public static <T> Map<String, Object> beanToMap(T bean) { Map<String, Object> map = new HashMap<>(); if (bean != null) { BeanMap beanMap = BeanMap.create(bean); for (Object key : beanMap.keySet()) { map.put(key+"", beanMap.get(key)); } } return map; } /** * 将map集合中的数据转化为指定对象的同名属性中 */ public static <T> T mapToBean(Map<String, Object> map,Class<T> clazz) throws Exception { T bean = clazz.newInstance(); BeanMap beanMap = BeanMap.create(bean); beanMap.putAll(map); return bean; } }
导入替换src\module-employees\pages\details.vue前端代码
<template> <div class="dashboard-container"> <div class="app-container"> <el-card> <el-tabs v-model="activeName" class="infoPosin"> <el-tab-pane name="first" class="rInfo"> <div class="fr"> <a class="fa fa-print" aria-hidden="true" title="打印" @click='handleExport()'></a> <el-tooltip class="item" effect="dark" content="点击打印按钮->右击打印预览界面->点击'打印'" placement="top-end"> <i class="fa fa-question-circle-o" aria-hidden="true"></i> </el-tooltip> </div> <span slot="label">登录账户设置</span> <component v-bind:is="accountInfo" :objId='objId' ref="user"></component> </el-tab-pane> <el-tab-pane name="two" class="rInfo"> <span slot="label">个人详情</span> <component v-bind:is="userInfo" :objId='objId' ref="user"></component> </el-tab-pane> <el-tab-pane name="third" class="rInfo"> <span slot="label">岗位信息</span> <component v-bind:is="postInfo" :objId='objId'></component> </el-tab-pane> </el-tabs> </el-card> </div> </div> </template> <script> import accountInfo from './../components/details-account-info' import userInfo from './../components/details-user-info' import postInfo from './../components/details-post-info' export default { name: 'employeesDetails', components: { accountInfo, userInfo, postInfo}, data() { return { accountInfo:'accountInfo', userInfo: 'userInfo', postInfo: 'postInfo', activeName: 'first', objId: this.$route.params.id, dataList: [] } }, methods: { // 下载文件 handleExport() { let id = this.$route.params.id; location.href="http://localhost:9003/employees/"+id+"/pdf" }, } } </script> <style rel="stylesheet/scss" lang="scss"> .el-tabs__content { overflow: initial; } .logInfo { width: 250px; float: right; h2 { margin: 0 0 0 20px; padding: 0 0 0 20px; height: 40px; line-height: 40px; border-bottom: 2px solid #e4e7ed; font-size: 14px; font-weight: normal; } } .logList { li { list-style: none; padding-left: 80px; .logRinfo { position: relative; padding: 25px 0 0; margin-left: 15px; .time { position: absolute; left: -100px; top: 25px; } .logContent { position: relative; } .logContent:before { content: ''; width: 14px; height: 14px; display: block; border-radius: 50px; position: absolute; left: -24px; top: 0; z-index: 20; border: 1px solid #26a69a; background: #fff; } } .logRinfo:before { content: ''; position: absolute; left: -18px; top: -15px; width: 2px; height: 40px; background-color: #e0e0e0; } } } </style> <style rel="stylesheet/scss" lang="scss" scoped> </style>