搜档网
当前位置:搜档网 › 用cognos SDK将报表下载到本地

用cognos SDK将报表下载到本地

用cognos SDK将报表下载到本地
[i=s] 本帖最后由 kyo100900 于 2009-10-25 19:29 编辑 [/i]

先决条件:
1. 熟悉JAVA,会使用JAVA开发工具,比如说Netbeans, Eclipse等等
2. 下载依赖的cognos SDK jar包, 下载地址为:
[url=https://www.sodocs.net/doc/5817492057.html,/home/link.php?url=https://www.sodocs.net/doc/5817492057.html,%2Fclub%2Fforumdisplay.php%3Ffid%3D5]https://www.sodocs.net/doc/5817492057.html,/home/link.php?url=https://www.sodocs.net/doc/5817492057.html,%2Fclub%2Fforumdisplay.php%3Ffid%3D5[/url]
3.源代码可能太长了,帖子有字数限制,想要完整的,直接下载Lesson1.rar解压后,就行了。

由于工作需要,快速的了解了cognos SDK如果将服务器上的报表下载到本地。
我们的系统是 JavaEE + cognos, 将cognos的报表信息都另存一份在 Java EE系统中, 用户点击下载时, 便触发代码来调用cognos SDK,实现下载功能。而这一切对用户来所是透明的,这也是大家期望达到的效果。

好吧,咱们现在就来做一个最简单的报表导出吧。

首先,你得有张报表,如果还不清楚如何创建报表,“Anda教程” “Andy教程”一定有适合你的。 现在假设我已经有一张报表,请看下图

[img]https://www.sodocs.net/doc/5817492057.html,/home/attachment/200910/25/1464_1256467603O248.jpg[/img]

里面的内容为

[img]https://www.sodocs.net/doc/5817492057.html,/home/attachment/200910/25/1464_12564676043CBX.jpg[/img]

一会儿生成到本地的excel就包含上面内容。


然后编写一个JAVA程序,这个JAVA程序得有个几百行。 详细的代码注释,与说明都写上了, 你只要修改大概6到7处,才能保证正常运行。如果运行的时候,遇到什么问题,可以回贴,我有空就会回复的。

导出excel的流程就是:

1.连接cognos服务
2.登录cognos(没有配置CA,就不需要这一步)
3.设置cognos执行excel导出事件
4.不断的向cognos服务器发请示,判断是否已经生成excel
5.生成excel,下载到本机

运行程序的时候,可能有点慢,耐心等待一会,完成后,你可以看看你自己设定的盘符下是否已经生成了excel。其中程序运行的时候,如果输出,下列信息,则表示生成成功[code]报表: /content/package[@name='MSSQL']/report[@name='test']
将在 2009-10-25 19:09:35.687 开始运行。
cognos的event管理服务为其生成的事件唯一编号为: C0A8016801CF481301248A9EF7988002001248b631047
你可以在congos门户中的Cognos Administration->状态中,看到此即将进行的活动。
报表已经生成到本地文件系统 d:\test.xls中了。

导出完成.[/code]当然,你也可以在Cognos Administration看到这个计划的一系列变化:

加入到计划调度中:
[img]https://www.sodocs.net/doc/5817492057.html,/home/attachment/200910/25/1464_125646919927Fz.jpg[/img]

正在执行:
[img]https://www.sodocs.net/doc/5817492057.html,/home/attachment/200910/25/1464_1256469201ub78.jpg[/img]

执行完成:
[img]

https://www.sodocs.net/doc/5817492057.html,/home/attachment/200910/25/1464_1256469202XTk8.jpg[/img]


最后打开生成的excel,发现内容属实:

[img]https://www.sodocs.net/doc/5817492057.html,/home/attachment/200910/25/1464_12564693967gCZ.jpg[/img]



问题: 在使用cognos导出excel时,容易发生类似于死锁的问题——不得不重启数据库后,才能再次倒出,而且导出的时候是依靠设定的导出时间来判断excel属于哪个用户,如果在高并发的情况下,可能会出乱子。 而Cognos SDK的doc文件,连个注释说明都没有。哎,期待高手出现。



最后附上完整的源代码如下:
kyo100900 发表于 2009-10-25 19:25

[code]

import java.io.File;
import java.io.FileOutputStream;
import https://www.sodocs.net/doc/5817492057.html,.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import org.apache.axis.client.Stub;
import com.cognos.developer.schemas.bibus._3.BaseClass;
import com.cognos.developer.schemas.bibus._3.BiBusHeader;
import com.cognos.developer.schemas.bibus._3.ContentManagerService_Port;
import com.cognos.developer.schemas.bibus._3.ContentManagerService_ServiceLocator;
import com.cognos.developer.schemas.bibus._3.EventManagementService_Port;
import com.cognos.developer.schemas.bibus._3.EventManagementService_ServiceLocator;
import com.cognos.developer.schemas.bibus._3.Option;
import com.cognos.developer.schemas.bibus._3.Output;
import com.cognos.developer.schemas.bibus._3.ParameterValue;
import com.cognos.developer.schemas.bibus._3.ParmValueItem;
import com.cognos.developer.schemas.bibus._3.PropEnum;
import com.cognos.developer.schemas.bibus._3.QueryOptions;
import com.cognos.developer.schemas.bibus._3.RunOptionBoolean;
import com.cognos.developer.schemas.bibus._3.RunOptionEnum;
import com.cognos.developer.schemas.bibus._3.RunOptionStringArray;
import com.cognos.developer.schemas.bibus._3.SearchPathMultipleObject;
import com.cognos.developer.schemas.bibus._3.SearchPathSingleObject;
import com.cognos.developer.schemas.bibus._3.SimpleParmValueItem;
import com.cognos.developer.schemas.bibus._3.Sort;
import com.cognos.developer.schemas.bibus._3.XmlEncodedXML;

public class Lesson1{

public ContentManagerService_Port contentManagerService = null;
public EventManagementService_Port eventManagementService = null;

/**
*
方法名称: connectToReportServer描述: 连接cognos服务器


* @param cognosURL cognos服务器的服务URL
* @throws Exception
*/
public void connectToReportServer(String cognosURL) throws Exception{
// 创建一个连接cognos内容库的服务定位对象
ContentManagerService_ServiceLocator cmServiceLocator = new ContentManagerService_ServiceLocator();
// 创建一个连接cognos事件管理的服务定位对象
EventManagementService_ServiceLocator evtServiceLocator =

new EventManagementService_ServiceLocator();
try{
// 通过cognos服务器的服务URL,得到本机调用远程cognos内容库服务的入口方法
contentManagerService = cmServiceLocator.getcontentManagerService(new URL(cognosURL));
// 通过cognos服务器的服务URL,得到本机调用远程cognoscognos事件管理服务的入口方法
eventManagementService = evtServiceLocator.geteventManagementService(new URL(cognosURL));
}catch (Exception e){
System.out.println(e);
}
}

/**
*
方法名称: logon描述: LDAP登录。其实其它认证方式也类似。


* @param namespaceID LDAP命名空间
* @param uid LADP用户名
* @param pwd LDAP密码
* @return
* @throws Exception
*/
public String logon(String namespaceID, String uid, String pwd) throws Exception{
// 创建一个XML,用于存放认证所需要的相关信息
StringBuffer credentialXML = new StringBuffer();
credentialXML.append("");
credentialXML.append("").append(namespaceID).append("");
credentialXML.append("").append(uid).append("");
credentialXML.append("").append(pwd).append("");
credentialXML.append("");
String encodedCredentials = credentialXML.toString();
try{
// 执行cognos登录操作
contentManagerService.logon(new XmlEncodedXML(encodedCredentials), null);
BiBusHeader bibus = (BiBusHeader) ((Stub) contentManagerService).getHeaderObject("", "biBusHeader");
((Stub) eventManagementService).setHeader("", "biBusHeader", bibus);
return ("用户 " + uid + " 登录成功。");
}catch (Exception e){
e.printStackTrace();
return (e.toString());
}
}
[/code]
kyo100900 发表于 2009-10-25 19:26

[code]
/**
*
方法名称: executeReport描述: 执行将报表导出为excel


* @param reportSearchPath 你要导出的报表,在cognos服务器中的完整名称
* @param execTime 执行时间
* @throws Exception
*/
public void executeReport(String reportSearchPath, GregorianCalendar execTime) throws Exception{
// 导出设置
Option runOptions = new Option[3];
// 设置1:是否保存
RunOptionBoolean saveOutput = new RunOptionBoolean();
saveOutput.setName(RunOptionEnum.saveOutput);
saveOutput.setValue(true);
runOptions[0] = saveOutput;
//

设置2:导出格式 格式可以为CSV, HTMLFragment, MHT, PDF, singleXLS, XHTML, XLS,
// XLWA, XML, HTML
RunOptionStringArray outputFormat = new RunOptionStringArray();
outputFormat.setName(RunOptionEnum.outputFormat);
// 目前设置的为 excel
outputFormat.setValue(new String {"XLWA"});
runOptions[1] = outputFormat;
// 设置3:设置提示参数
RunOptionBoolean prompt = new RunOptionBoolean();
prompt.setName(RunOptionEnum.prompt);
prompt.setValue(false);
runOptions[2] = prompt;
// 下面为设置你的报表,页面需要传递的参数
// 假设我的报表需要输入4个参数, 年, 月, 数据来源, 企业名称
// 如果你的报表没有设置参数,那么就算设置了参数,也不会影响报表的正常运行
ParameterValue pvalue = new ParameterValue[4];
// 设置 年
SimpleParmValueItem item1 = new SimpleParmValueItem();
item1.setUse("2009"); // 使用的值
item1.setDisplay("2009"); // 显示用的值
item1.setInclusive(true);
ParmValueItem p1 = new ParmValueItem[1];
p1[0] = item1;
pvalue[0] = new ParameterValue();
pvalue[0].setName("year"); // 你在报表中定义的参数名称
pvalue[0].setValue(p1);
// 设置 月
SimpleParmValueItem item2 = new SimpleParmValueItem();
item2.setUse("6");
item2.setDisplay("6");
item2.setInclusive(true);
ParmValueItem p2 = new ParmValueItem[1];
p2[0] = item2;
pvalue[1] = new ParameterValue();
pvalue[1].setName("month");
pvalue[1].setValue(p2);
// 数据来源
SimpleParmValueItem item3 = new SimpleParmValueItem();
item3.setUse("1");
item3.setDisplay("1");
item3.setInclusive(true);
ParmValueItem p3 = new ParmValueItem[1];
p3[0] = item3;
pvalue[2] = new ParameterValue();
pvalue[2].setName("src");
pvalue[2].setValue(p3);
// 对企业名称的输入
SimpleParmValueItem item4 = new SimpleParmValueItem();
item4.setUse("1000");
item4.setDisplay("1000");
item4.setInclusive(true);
ParmValueItem p4 = new ParmValueItem[1];
p4[0] = item4;
pvalue[3] = new ParameterValue();// 数据来源
pvalue[3].setName("qybh");
pvalue[3].setValue(p4);
// 将执行时间

,导出设置,参数设置传递给cognos的event管理服务。于是cognos的event管理服务在设定的时间后开始异步执行。
String eventID = eventManagementService.runAt(execTime, new SearchPathSingleObject(reportSearchPath), pvalue,
runOptions);
System.out.println("\n报表: " + reportSearchPath);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String str = formatter.format(execTime.getTime());
System.out.println("将在 " + str + " 开始运行。");
System.out.println("cognos的event管理服务为其生成的事件唯一编号为: " + eventID);
System.out.println("你可以在congos门户中的Cognos Administration->状态中,看到此即将进行的活动。");
}
[/code]
kyo100900 发表于 2009-10-25 19:26

[code]
/**
*
方法名称: getExecutionTime描述: 设置导出的执行时间


* @param milliSeconds 在多少毫秒后开始执行
* @return
*/
private GregorianCalendar getExecutionTime(long milliSeconds){
Date execDate = new Date();
long execTimeInMillis = execDate.getTime();
execDate.setTime(execTimeInMillis + milliSeconds);
GregorianCalendar execTime = new GregorianCalendar();
execTime.setTime(execDate);
return execTime;
}

/**
*
方法名称: getOutput描述: 查询cognos的内容库,看看报表是否已经生成。


* @param searchPath 这里指的是生成的exceld在cognos的版本控制中的路径,客户端其实是从这里看excel有没有生成
* @return
*/
private BaseClass getOutput(String searchPath){
PropEnum props = {PropEnum.defaultName, PropEnum.data, PropEnum.defaultName, PropEnum.creationTime};
BaseClass bc = null;
try{
SearchPathMultipleObject spMulti = new SearchPathMultipleObject();
spMulti.setValue(searchPath);
bc = contentManagerService.query(spMulti, props, new Sort {}, new QueryOptions());
}catch (Exception e){
e.printStackTrace();
}
return bc;
}

/**
*
方法名称: saveOutput描述: 将生成的excel存到本机


* @param searchPath 这里指的是生成的excel会生成在cognos的版本控制中
* @param savePath 要保存在本机的目标路径
* @param gc
*/
public void saveOutput(String searchPath, String savePath, GregorianCalendar gc){
BaseClass reportOutput = null;
reportOutput = getOutput(searchPath);
// 不断的循环,看

看有没有生成excel报表
while(reportOutput == null reportOutput.length == 0){
try{
// 如果没有找到,先释放CPU,让别的进程继续运行
Thread.sleep(2000);
}catch (InterruptedException e){
e.printStackTrace();
}
reportOutput = getOutput(searchPath);
}
// 如果有生成excel,看看是不是属性自己的excel
while(reportOutput[0].getCreationTime().getValue().getTimeInMillis() < gc.getTimeInMillis()){
try{
// 如果没有找到,先释放CPU,让别的进程继续运行
Thread.sleep(2000);
}catch (InterruptedException e){
e.printStackTrace();
}
reportOutput = getOutput(searchPath);
}
// 得到属于自己的excel后,以流的方式写到本机上
if(reportOutput != null && reportOutput.length > 0){
Output o = (Output) reportOutput[0];
String fileName = savePath;
System.out.println("报表已经生成到本地文件系统 " + savePath + "中了。");
try{
File oFile = new File(fileName);
FileOutputStream fos = new FileOutputStream(oFile);
fos.write(o.getData().getValue());
fos.flush();
fos.close();
}catch (Exception e){
e.printStackTrace();
}
}
}

/**
*
方法名称: main描述: 方法入口,通过cognos SDK实现报表下载


* @param args
*/
public static void main(String args){
// 以下几处为相应的参数修改,
// 第一处修改:cognos服务URL,必选
String cognosURL = "http://localhost:9300/p2pd/servlet/dispatch";
// 第二处修改:LDAP在cognos中设置的命名空间,如果没有配置LDAP,则可选
String namespaceID = "LDAP";
// 第三处修改:LDAP用户名,如果没有配置LDAP,则可选
String userID = "ldap";
// 第四处修改:LDAP密码,如果没有配置LDAP,则可选
String password = "123";
// 第五处修改:要测试的报表名称,必选
String report_name = "test";
// 第六处修改:要保存在本机的目标路径,必选

String filePath = "d:\\" + report_name + ".xls";
// 第六处修改:你要保存的报表,在cognos服务器中的名称,必选
String reportSearchPath = "/content/package[@name='MSSQL']/report[@name='" + report_name + "']";
// 这里指的是生成的excel会生成在cognos的版本控制中
String outputSearchPath = reportSearchPath + "/reportVersion/output";
// 设置导出excel的执行时间为当前时间向后推迟20秒
long milliSeconds = 20000;
// 创建Lesson1测试对象
Lesson1 lession1 = new Lesson1();
try{
// 连接cognos服务器
lession1.connectToReportServer(cognosURL);
// 如果配置了LDAP则,下面的代码必须开启,否则没有权限执行报表导出操作。
// 由于我本机没有配置LDAP,故将此代码注释掉
// System.out.println(lession1.logon(namespaceID, userID,
// password));
// 得到cognos执行时间
GregorianCalendar gc = lession1.getExecutionTime(milliSeconds);
// 执行报表导出
lession1.executeReport(reportSearchPath, gc);
lession1.saveOutput(outputSearchPath, filePath, gc);
System.out.println("\n导出完成.");
}catch (Exception e){
e.printStackTrace();
}
}
}
[/code]
anda 发表于 2009-10-25 20:59

先存起来 呵呵
yumenhui 发表于 2009-10-26 09:37

:) 真好楼主 正好我们要用到。
licengyao 发表于 2009-10-26 10:09

看看 看看:D :D
冰华敏 发表于 2009-10-26 11:37

哇,太好了,多谢经验分享{:2_31:}
King 发表于 2009-10-26 11:40

谢谢 兄弟你分享了 太感谢了
lanxing2210 发表于 2009-10-26 13:20

好东西! 谢谢分享
jiayong81 发表于 2009-10-26 14:16

谢谢分享
licengyao 发表于 2009-10-26 14:40

报错啊

[color=Red]AxisFault
faultCode: {[url]https://www.sodocs.net/doc/5817492057.html,/soap/envelope/[/url]}Client
faultSubcode:
faultString: CNC-BAL-0503 Client 已失败。
faultActor:
faultNode:
faultDetail:
{[url]https://www.sodocs.net/doc/5817492057.html,/schemas/bibus/3/[/url]}exception:
error

CNC-BAL-0502 错误号码: 0506



CNC-BAL-0506 未在 Content Manager 中找到凭证。

0





CNC-BAL-0503 Client 已失败。[/color]
sd_fxz 发表于 2009-10-26 15:53

正好用到
licengyao 发表于 2009-10-26 15:53

我用过了 您那个方法 对于设置权限的表报 就是需要logon的时候 会报我前面贴出来的错

还有怎么可以获取用户动态选择的参数(每张表报的参数都不

一样)
helene620 发表于 2009-10-27 09:08

cognos本身不就能导出成excel吗?为什么还要自己再开发导出功能呢?
licengyao 发表于 2009-10-27 16:32

cognos本身确实可以导出的

但是用户要求 那个toolbar 只有导出这一个菜单选项
我该js文件 让它只有一个菜单选项

但是用户说 那上面没有文字提示 啊啊啊啊啊啊啊啊啊啊啊啊啊
tgy 发表于 2009-10-27 16:40

这个好。不错,。
yuzhucu 发表于 2009-10-27 22:43

非常不错 有时间试试
wgwgw 发表于 2009-10-28 12:45

好东西 谢谢
自己研究了两个月
看sdk user guilder真是痛苦
licengyao 发表于 2009-10-28 13:59

sdk user guilder 还有这东西??


页: [1] 2 3 4 查看完整版本: 用cognos SDK将报表下载到本地

相关主题