前言
數據庫在企業軟件系統中應用廣泛,而報表的顯示與打印成為此類軟件必備的功能。可惜VC++並沒有集成報表處理工具,但其強大的功能再加上市面上功能完備的報表處理工具使這一工作變得容易,本文介紹了在VC++環境中利用Seagate公司的Crystal report(水晶報表)來實現報表的顯示與打印,並提供示例代碼。
一、准備工作
(1)安裝Crystal Report軟件Crystal Report 4.6是一個免費的報表工具,可以在VB5或WINDOWS NT 4.0 BackOffice等光盤上找到,Crystal report4.6中包含了報表設計工具與報表打印控件。程序的發行只需要安裝打印控件相關部分即可。
(2)設計報表
我們生成一個名為sample.rpt的報表,這一過程可以參考 Crystal report自帶的幫助文檔,本文不作詳細介紹。
二、創建VC工程添加報表控件
在VC集成環境中用AppWizard新建一個MFC單文檔工程,其余選項都為默認。菜單中選擇Project->Add To Project->Components and Controls……彈出組件、控件選擇對話框,進入Registered ActiveX Controls,選中Crystal Report Control 4.6 ,單擊Insert按鈕,確認後進入類配置對話框,按默認即可。關閉控件選擇對話框完成控件的添加。
三、實現報表的顯示與打印
下面我們將在對話框中演示控件的靜態創建過程,在主視圖中演示控件的動態創建過程。
3.1在對話框中打印出報表
在資源編輯器中打開ID為IDD_ABOUTBOX的對話框模板,在Controls工具條中我們可以找到剛加入到工程中的Crystal Report Control 4.6控件按鈕,把它插入到對話框合適的位置處。
右鍵單擊對話框中的控件,選擇屬性,此時可以設置控件的許多屬性。我們在Control選項頁ReportFileName中輸入報表文件名sample.rpt(可以加上完整路徑),在Print Window選項頁中設置控件的合適位置,回到對話框模板中按住Ctrl鍵,雙擊鼠標左鍵,彈出Add Member Variable對話框,我們將成員變量命名為m_CrystalReport,打開ClassWizard,為CAboutDlg對話框添加WM_INITDIALOG消息的處理函數:BOOL OnInitDialog(),並在函數中做如下處理
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
/////此行設置控件的父窗口,你也可以去掉該行看看運行效果/////////
m_CrystalReport.SetWindowParentHandle((long)(this->m_hWnd));
/////打印報表到窗口中/////
m_CrystalReport.PrintReport();
return TRUE;
}
至此,程序的第一部分編寫完成,編譯運行,打開About對話框看看效果吧!
哦!還不錯!
假如您並沒有顯示出報表,有如下可能原因:
(1)控件沒有放置在合適的位置或尺寸不對。
(2)報表文件本身存在諸如數據源不可用等錯誤。
控件窗口中的工具條提供了縮放、打印等功能,您也可以試試在打印機上打印出來的效果。
3.2 在程序主視窗中顯示報表
打開ClassWizard增加對ID_FILE_OPEN和ID_FILE_PRINT的處理函數,代碼如下
void CMyReportView::OnFileOpen()
{
char Filter[] = "Crystal Report files(*.rpt)|*.rpt|All files(*.*)|*.*||";
CRect rect;
CFileDialog OpenDlg(TRUE,0,0,OFN_HIDEREADONLY|OFN_FILEMUSTEXIST,(LPCTSTR)Filter,NULL);
if(OpenDlg.DoModal()!=IDOK) ///顯示文件對話框
return;
CString m_fName=OpenDlg.GetPathName(); ///取得文件名
if(m_CrystalReport)
m_CrystalReport.DestroyWindow();
GetClientRect(rect);
///////////////////創建控件///////////////
if (!m_CrystalReport.Create(AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW)),WS_CHILD|
_ WS_VISIBLE,rect,this,IDC_CRYSTALREPORT1))
{
AfxMessageBox("控件創建失敗!");
return ;
}
m_CrystalReport.SetWindowParentHandle((long)(this->m_hWnd));///設置父窗口
m_CrystalReport.SetWindowBorderStyle(0); ///設置為沒有邊框
m_CrystalReport.SetWindowLeft(0); ///左空間
m_CrystalReport.SetWindowTop(0); ///頂部空間
m_CrystalReport.SetWindowControls(FALSE); ///不顯示工具條
m_CrystalReport.SetReportFileName(m_fName); ///設置報表文件
m_CrystalReport.SetWindowWidth(rect.Width()); ///設置窗口寬度
m_CrystalReport.SetWindowHeight(rect.Height()); ///設置窗口高度
m_CrystalReport.SetFormulas(0, "Company=\"VC知識庫\"");
///將報表中的Company變量的值設置為VC知識庫
m_CrystalReport.SetDestination(0); ///設置輸出對象是屏幕
m_CrystalReport.PrintReport(); ///顯示報表
}
void CMyReportView::OnFilePrint()
{
if(m_CrystalReport && m_CrystalReport.GetReportFileName() != "")
{
m_CrystalReport.SetDestination(1); ///設置輸出對象是打印機
m_CrystalReport.PrintReport(); ///打印
}
}
後記:我們利用Crystal Report 4.6在VC++環境下實現了報表處理,但Crystal Report 4.6報表控件的功能及可控性能可能無法滿足您的要求,Seagate公司此款軟件的最新版本是Crystal Report 8.0,各方面表現都非常出色,但此款軟件的免費版本並不包括報表設計器,可喜的是8.0中的報表顯示控件兼容以前版本的報表格式,所以筆者建議用4.6版本來設計報表,依靠8.0中的報表顯示控件來顯示、打印。