[需求]

最近在项目开发过程中,客户要求用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输出来,直接输出到打印机上。