若依集成积木报表(二),集成报表浏览到页签tab中
若依集成积木报表(二),集成报表浏览到页签tab中
编辑 淡月斜阳 · 2022-09-07 12:14:31 发布
先看效果!
接上文: 若依vue集成积木报表,加token校验
已经实现了:集成token校验,集成报表设计器
下面,先设计一个报表,格式为主子表。采用API数据源,用若依代码生成器的,获取 表单详细信息的接口。
那么需要
1.传参:传入表单号。
2.定义数据格式转换器。
一、数据格式转换器定义。原接口返回的数据格式为{,,,data:{...List[{},{}]}
而积木报表要求的数据格式为[{},{}],为了省事,积木报表中的API数据源,我用相同的接口,调用不同的转换器处理。
主表API数据集
子表API数据集。
主子表参数配置
下面是两个数据转换器
参考积木的帮助文档:7.API接口数据格式适配 · JimuReport 积木报表 · 看云
主表的数据格式转换器:这里把Params参数去掉了,把List子表数据也去掉了,getToale,getCount,因为不需要分页,删除就行。
。另外jsobject要处理成jsArray返回,否则会报错com.alibaba.fastjson.JSONException: field null expect ‘[‘, but {, pos 1, line 1,
@Component("ReportMainParser") public class MyApiDataConvertAdapterMain implements ApiDataConvertAdapter { /** * 返回list数据集,转换成积木报表需要格式[],没有嵌套 * 注意:需要json格式,不用data包裹起来了 * @param jsonObject 接口数据原始对象 * @return */ @Override public String getData(JSONObject jsonObject) { JSONObject jsdata = new JSONObject(); String js = jsonObject.toString(); JSONArray jsonArray = new JSONArray(); if(jsonObject.containsKey("data")){ jsdata=(JSONObject) jsonObject.get("data"); for (Map.Entry<String, Object> entry : jsdata.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); if (key.endsWith("List")) { jsdata.remove(key); jsdata.remove("params"); break; } else { continue; } } jsonArray.add(jsdata); String str = jsonArray.toJSONString(); return str; } return ""; } /** * 返回links(没有图表属性可以删掉) * @param jsonObject 接口数据原始对象 * @return */ @Override public String getLinks(JSONObject jsonObject) { return jsonObject.containsKey("links") ? jsonObject.get("links").toString() : ""; } }
子表数据格式转换器。因为考虑通用性,所有找jsobject.data中key 结尾为List的object,返回。同样,不需要分页,不要getTotal 和 getCount。
@Component("ReportDetailsParser") public class MyApiDataConvertAdapterDetails implements ApiDataConvertAdapter { /** * 返回list数据集,转换成积木报表需要格式{},没有嵌套 * 注意:需要json格式,不用data包裹起来了 * @param jsonObject 接口数据原始对象 * @return */ @Override public String getData(JSONObject jsonObject) { JSONArray rows = new JSONArray(); JSONObject jsdata = new JSONObject(); if(jsonObject.containsKey("data")){ jsdata=(JSONObject) jsonObject.get("data"); for (Map.Entry<String, Object> entry : jsdata.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); if (key.endsWith("List")) { rows = (JSONArray) jsdata.get(key); break; } else { continue; } } String jsonArray = rows.toJSONString(); return jsonArray; } return ""; } /** * 返回links(没有图表属性可以删掉) * @param jsonObject 接口数据原始对象 * @return */ @Override public String getLinks(JSONObject jsonObject) { return jsonObject.containsKey("links") ? jsonObject.get("links").toString() : ""; } }
以上,就可以成功解析了。
下面是,如果把设计好的报表装到页签中。
设计好的报表,点预览,就可以获得这个报表的预览编号。如下图,就是报表的访问地址,设计的每个报表,都有一个编号,需要把这个编号 token reportId参数传递过去。
设计一个报表浏览页面,view.vue,跟前面写的差不多。这里我加了一个刷新按钮,考虑后续可以把动态查询条件,放到页面里(积木报表本身也可以!)。
created事件中,先获取参数,this.$route.query.
注意:这里不是.$router,也不是params(一直传不过去,看了原代码才找到原因)
<template> <div v-loading="loading" :style="'height:'+ height" class="app-container"> <el-row style="margin-bottom: 10px;"> <el-col :span="1.5"> <el-button type="primary" plain icon="el-icon-refresh-right" size="mini" @click="handleRefresh">刷新</el-button> </el-col> </el-row> <iframe :src="src" id="reportView" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" /> </div> </template> <script> import { getToken } from '@/utils/auth' import { view } from '@/api/report/jimu' export default { name: "Ureport", data() { return { src: "", height: document.documentElement.clientHeight - 94.5 + "px;", loading: true, viewNum: "", reportId: "", }; }, created() { this.viewNum = this.$route.query.viewNum this.reportId = this.$route.query.reportId view().then(res => { this.src = res + "/" + this.viewNum + "?reportId=" + this.reportId + "&token=Bearer " + getToken(); }) }, methods: { handleRefresh() { document.getElementById("reportView").src = document.getElementById("reportView").src; }, }, mounted: function() { setTimeout(() => { this.loading = false; }, 230); const that = this; window.onresize = function temp() { that.height = document.documentElement.clientHeight - 94.5 + "px;"; }; } }; </script>
刷新可以用:没有找到别的办法,因为Iframe访问的是后端地址,有跨域问题。
document.getElementById("reportView").src = document.getElementById("reportView").src;
配置动态路由。router/index.js
// 动态路由,基于用户权限动态去加载 export const dynamicRoutes = [ { path: '/system/user-auth', component: Layout, hidden: true, permissions: ['system:user:edit'], children: [ { path: 'role/:userId(\\d+)', component: () => import('@/views/system/user/authRole'), name: 'AuthRole', meta: { title: '分配角色', activeMenu: '/system/user' } } ] }, { path: '/report', component: Layout, hidden: true, permissions: ['bre:DailyReport:list'], children: [ { path: 'breDailyReport', component: () => import('@/views/report/view'), name:'DailyReportReport', meta:{title:'报表-日报表',activeMenu:'/bre/DailyReport'}, }, ] },
在页面中,添加按钮,打开页签,需要把报表编号,id传递过去。
按钮事件代码为
/** 显示报表*/ handleReport(row){ const reportId = row.reportId; const viewNum = "726979918227357696"; const params = {viewNum,reportId}; this.$tab.openPage('报表-日报表','/report/breDailyReport',params); },