在计划任务的应用中,对于导出的报表数据,通过邮件发给多个用户时,都是同一份数据。实际中有可能需要对数据进行控制,比如同一个报表,同时发送给不同的用户,需要限制用户只能够看到各自权限内的数据。
注:此示例只支持“灵活分析”报表。
实现步骤
对于导出报表的数据权限控制,具体的实现步骤是:
1.首先创建好报表资源,报表上有一个接收用户名的参数,根据用户名参数,能够筛选出该用户所能查看的数据。
2.在数据库中维护一张表,这张表记录了要接收邮件的用户的名称。比如创建表t_user,其中包含username字段。这个字段记录了需要接收邮件的用户名称。
(3)在用户管理中,为用户添加一个扩展属性,如email,并在该项中设置用户的邮箱地址
增加用户扩展属性,可参考:https://history.wiki.smartbi.com.cn/pages/viewpage.action?pageId=27002165
4.创建一个任务,任务类型选择“定制”。
通过以下代码,获取需要接收邮件的用户的名称和邮箱。打开报表时,动态设置用户名参数,并将该用户名参数的报表数据批量发送邮件给指定用户。
具体代码可见下方
任务代码
以下为代码中的关键代码片段说明
(1)通过SQL查询出需要发送邮件的用户名称
var dsId = "DS.user";//数据源ID
var sql = "SELECT userName FROM t_user";
var gridDataGroup = datasrcService.executeNoCacheable(dsId, sql);
for (var i = 0; i < gridDataGroup.getRowsCount(); i++) {
var userName = gridDataGroup.get(i, 0).getValue();
......
}
(2)根据用户名称获取用户属性:email
//根据用户名获取用户对象
var user = usrManagerService.getUserByName(userName);
//根据key值获取用户扩展属性,此处获取用户的email地址
var email = usrManagerService.getUserAttribute(user.getId(), "email").getValue();
(3)通过设置用户名参数
//设置格式:{id:"OutputParameter.数据集ID.参数名称",value:参数真实值,displayValue:参数显示值}
var reportParamSetting = [{id:"OutputParameter.I2c9019810158fc12fc1224c00158fc2e21c50069.当前用户",value:userName,displayValue:userName}]
//参数值也可以设置为固定值,变量,或者默认值,其中默认值写法:"$默认值$"
如:{id:"OutputParameter.I2c9019810158fc12fc1224c00158fc2e21c50069.测试",value:"$默认值$",displayValue:"$默认值$"}
(4)打开报表
//打开报表的方法基本固定,无需作出更改。
var openReportOutput = execute('openResource', {
connector: connector,
reportId: reportID
});
(5)执行导出
var exportReportOutput = execute('exportResource', {
connector: connector,
resourceHandle: openReportOutput.resourceHandle,
paramSettingIterator: enumerateParamValuesOutput.getParamValues(),
exportSetting: {"delimiter":"","pathId":"","fileNameSufParams":false},
taskName: taskName,
exportType: "EXCEL2007"
});
(6)发送邮件
var title = "%TASKNAME_%DATE%TIME";//邮件标题,默认为:任务名称_日期时间 var text = "这是一个系统自动发送的邮件,所含附件是您订阅的报表";//邮件正文内容 var doZip = true;//是否需要压缩,默认:是。 var picInMail = false;//是否将图片作为正文内容,默认:否
var sendToMailOutput = execute('sendToMail', {
connector: connector,
taskName: taskName,
paramValueMap: null,
files: [outputFile],
//设置邮件
sendSetting: {"mailList":email,"doZip":doZip,"title":title,"text":text,"picInMail":picInMail}
});
(7)批量发送邮件
通过遍历第1步获取到的用户名称,重复执行第2、3、4、5、6步即可完成批量发送邮件。
附完整的定制任务代码
/** * 以下代码需要根据实际使用场景进行设置。设置的地方主要有两个: * 一、数据源与SQL,此处设置是为了获取邮件发送的对象,即工号。 * 二、报表参数信息,此处是设置准备发送报表的参数信息。 */ importPackage(Packages.java.io); importPackage(Packages.java.lang); importPackage(Packages.java.util); importPackage(Packages.smartbi.usermanager); importPackage(Packages.smartbi.sdk); importPackage(Packages.smartbi.sdk.service.user); importPackage(Packages.smartbi.sdk.service.datasource); var usrManagerService = new UserManagerService(connector); var datasrcService = new DataSourceService(connector); //设置报表ID var reportID = 'I4028818a015c345e345e04fd015c8076cbda0c41'; //开始设置数据源与SQL------------------------------------------------- var sql = "SELECT userName FROM t_user"; // 该SQL语句获取需要邮件推送的用户名称 var dsId = "DS.资源库_业务库"; //上一句SQL运行的数据源ID //结束设置数据源与SQL------------------------------------------------- var title = "%TASKNAME_%DATE%TIME";//邮件标题,默认为:任务名称_日期时间 var text = "这是一个系统自动发送的邮件,所含附件是您订阅的报表";//邮件正文内容 var doZip = true;//是否需要压缩,默认:是。 var picInMail = false;//是否将图片作为正文内容,默认:否 var gridDataGroup = datasrcService.executeNoCacheable(dsId, sql); for (var i = 0; i < gridDataGroup.getRowsCount(); i++) { var userName = gridDataGroup.get(i, 0).getValue(); //根据用户名获取用户对象 var user = usrManagerService.getUserByName(userName); //根据key值获取用户扩展属性,此处获取用户的email地址 var email = usrManagerService.getUserAttribute(user.getId(), "email").getValue(); //开始设置报表参数信息--------------------------------------------- //设置格式:{id:"OutputParameter.数据集ID.参数名称",value:参数真实值,displayValue:参数显示值},参数值可 //以设置为固定值,变量,或者默认值,默认值写法:"$默认值$" var reportParamSetting = [ {id:"OutputParameter.I4028818a015c345e345e04fd015c8076bf830c3d.用户",value:userName,displayValue:userName}//多个参数之间以逗号分隔 ]; //结束设置报表参数信息---------------------------------------------- //以下代码无需修改-------------------------------------------------- var openReportOutput = execute('openResource', { connector: connector, reportId: reportID }); var enumerateParamValuesOutput = execute('enumerateParamValues', { resourceHandle: openReportOutput.resourceHandle, byEveryParam: false, paramsSetting: reportParamSetting }); var exportReportOutput = execute('exportResource', { connector: connector, resourceHandle: openReportOutput.resourceHandle, paramSettingIterator: enumerateParamValuesOutput.getParamValues(), exportSetting: {"delimiter":"","pathId":"","fileNameSufParams":false}, taskName: taskName, exportType: "EXCEL2007" }); openReportOutput.resourceHandle.close(); var outputFile = exportReportOutput.file; var sendToMailOutput = execute('sendToMail', { connector: connector, taskName: taskName, paramValueMap: null, files: [outputFile], //设置邮件 sendSetting: {"mailList":email,"doZip":doZip,"title":title,"text":text,"picInMail":picInMail} }); }
更多
另外,需要接收邮件的用户及其邮箱地址也可直接存放在同一张表中。如下:
完整代码如下:
/** * 以下代码需要根据实际使用场景进行设置。设置的地方主要有两个: * 一、数据源与SQL,此处设置是为了获取邮件发送的对象,即工号。 * 二、报表参数信息,此处是设置准备发送报表的参数信息。 */ importPackage(Packages.java.io); importPackage(Packages.java.lang); importPackage(Packages.java.util); importPackage(Packages.smartbi.usermanager); importPackage(Packages.smartbi.sdk); importPackage(Packages.smartbi.sdk.service.user); importPackage(Packages.smartbi.sdk.service.datasource); var usrManagerService = new UserManagerService(connector); var datasrcService = new DataSourceService(connector); //设置报表ID var reportID = 'I4028818a015c345e345e04fd015c8076cbda0c41'; //开始设置数据源与SQL------------------------------------------------- var sql = "SELECT userName,email FROM t_user"; // 该SQL语句获取需要邮件推送的用户名称 var dsId = "DS.资源库_业务库"; //上一句SQL运行的数据源ID //结束设置数据源与SQL------------------------------------------------- var title = "%TASKNAME_%DATE%TIME";//邮件标题,默认为:任务名称_日期时间 var text = "这是一个系统自动发送的邮件,所含附件是您订阅的报表";//邮件正文内容 var doZip = true;//是否需要压缩,默认:是。 var picInMail = false;//是否将图片作为正文内容,默认:否 var gridDataGroup = datasrcService.executeNoCacheable(dsId, sql); for (var i = 0; i < gridDataGroup.getRowsCount(); i++) { var userName = gridDataGroup.get(i, 0).getValue(); var email = gridDataGroup.get(i,1).getValue(); //开始设置报表参数信息--------------------------------------------- //设置格式:{id:"OutputParameter.数据集ID.参数名称",value:参数真实值,displayValue:参数显示值},参数值可 //以设置为固定值,变量,或者默认值,默认值写法:"$默认值$" var reportParamSetting = [ {id:"OutputParameter.I4028818a015c345e345e04fd015c8076bf830c3d.用户",value:userName,displayValue:userName}//多个参数之间以逗号分隔 ]; //结束设置报表参数信息---------------------------------------------- //以下代码无需修改-------------------------------------------------- var openReportOutput = execute('openResource', { connector: connector, reportId: reportID }); var enumerateParamValuesOutput = execute('enumerateParamValues', { resourceHandle: openReportOutput.resourceHandle, byEveryParam: false, paramsSetting: reportParamSetting }); var exportReportOutput = execute('exportResource', { connector: connector, resourceHandle: openReportOutput.resourceHandle, paramSettingIterator: enumerateParamValuesOutput.getParamValues(), exportSetting: {"delimiter":"","pathId":"","fileNameSufParams":false}, taskName: taskName, exportType: "EXCEL2007" }); openReportOutput.resourceHandle.close(); var outputFile = exportReportOutput.file; var sendToMailOutput = execute('sendToMail', { connector: connector, taskName: taskName, paramValueMap: null, files: [outputFile], //设置邮件 sendSetting: {"mailList":email,"doZip":doZip,"title":title,"text":text,"picInMail":picInMail} }); }
注
发送邮件前需要注意在系统选项中配置发件箱
使用自定义定制任务小技巧
在使用可视化界面配置任务时,如果大部分都能通过配置达到需求,而只有一小部分无法配置实现,可以考虑先通过可视化配置界面配置好,然后通过查看运行脚本,将里面的脚本代码复制出来,然后即可根据里面的脚本代码作定制修改。
(1)配置好以后查看运行脚本
(2)将运行脚本复制出来
(3)新建一个任务,将上一步复制出来的脚本代码粘贴到定制代码中,然后作出定制修改即可。