[需求]
最近在項目開發過程中,客戶要求用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輸出來,直接輸出到打印機上。