[需求]
最近在项目开发过程中,客户要求用Crystal Reports生成pdf格式的报表,并实现自动打印功能。
[实施索引]
1、创建水晶报表;
2、Java中利用报表组件包将报表结果生成pdf;
3、完成自动打印功能。
[详细步骤]
1、创建水晶报表
如果业务要求比较复杂,要先创建临时表和存储过程,假设DB是ORACLE。
1.1、创建临时表
CREATE global TEMPORARY TABLE table_name_temporary
( ......... ) on commit preserve rows;
注:这种方式确保session之间,数据互不干扰。
1.2、创建存储过程
创建包体,包体内声明游标。
根据业务逻辑,将数据保存在临时表中,返回水晶报表所需要的结果集。
1.3、创建水晶报表
以存储过程做为数据源,创建水晶报表。
2、Java中利用报表组件包将报表结果生成pdf
主要步骤如下:
(1)登录CrystalEnterprise;
(2)设置report参数,检索report;
(3)登录DB Server;
(4)输出结果到pdf。
主要代码如下:
IEnterpriseSession enterpriseSession = null;
ReportClientDocument clientDoc = null; ISessionMgr sessionMgr = CrystalEnterprise.getSessionMgr();
enterpriseSession = sessionMgr.logon(
RAS_ADMINISTRATOR,
RAS_ADMIN_PWD, RASServer,
RAS_SEC);
IInfoStore iStore = (IInfoStore) enterpriseSession
.getService(EAPTPrintConstants.RAS_INFOSTORE);
IReportAppFactory reportAppFactory = (IReportAppFactory) enterpriseSession
.getService(EAPTPrintConstants.RAS_REPORT_FACTORY);
String query = "Select SI_ID From CI_INFOOBJECTS Where SI_NAME = '"
+ reportname + "' And SI_INSTANCE = 0 ";
IInfoObjects result = null;
try {
result = iStore.query(query);
} catch (SDKException e) {
e.printStackTrace();
}
IInfoObject firstResult = (IInfoObject) result.get(0);
clientDoc = reportAppFactory.openDocument(firstResult, 0,
Locale.ENGLISH); //logon to DataBase
DatabaseController db = clientDoc.getDatabaseController(); // need to transfer arguments
db.logonEx(dbServer, sid, username,
password); clientDoc.refreshReportDocument();
this.setParameters(clientDoc, map);
ByteArrayInputStream byteIS = (ByteArrayInputStream) clientDoc
.getPrintOutputController().export(ReportExportFormat.PDF); byte byteArray[] = new byte[byteIS.available()];
FileOutputStream fileOS = new FileOutputStream(filename);
ByteArrayOutputStream byteOS = new ByteArrayOutputStream(byteIS
.available());
int x = byteIS.read(byteArray, 0, byteIS.available());
byteOS.write(byteArray, 0, x);
byteOS.writeTo(fileOS);
byteOS.close();
fileOS.close();
3、完成自动打印功能
(1) 利用Itext技术重新处理pdf,在已生成的pdf里加上以下代码:
String js = "var pp = this.getPrintParams();\n";
js = js + "var fv = pp.constants.flagValues;\n";
js = js + "pp.flags = fv.setPageSize;\n";
js = js + "pp.interactive = pp.constants.interactionLevel.automatic;\n";
js = js + "pp.printerName = \"" + printer + "\";\n";
js = js + "this.print(pp);\n";
(2)jsp中需要IFrame标签,然后自动调用Servlet,在servlet里将pdf输出来,直接输出到打印机上。