曹勇 孟曉鑫 張維杰
摘要:介紹了一種基于AC Report組件的報(bào)表打印的解決方案,提出了解決組件數(shù)據(jù)讀取問(wèn)題的通用方法,并通過(guò)一個(gè)例子詳細(xì)說(shuō)明了報(bào)表打印的設(shè)計(jì)與實(shí)現(xiàn),具有較強(qiáng)的通用性和靈活性。
關(guān)鍵詞:AC Report;組件;報(bào)表打印
中圖分類(lèi)號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2014)10-2236-03
Abstract: This paper introduced a solution of report printing which is based on AC Report component. A method is proposed to solve the problem of reading data of the component. The design and implementation of the solution are illustrated through an instance, which have a strong versatility and flexibility.
Key words: AC report; component; report printing
報(bào)表打印作為信息管理系統(tǒng)的重要組成部分,是系統(tǒng)開(kāi)發(fā)工作的一項(xiàng)重要內(nèi)容。目前,由于傳統(tǒng)程序語(yǔ)言報(bào)表打印功能的處理能力較弱和用戶(hù)要求越來(lái)越豐富的實(shí)際情況,組件技術(shù)憑借其較強(qiáng)的通用性、靈活性等優(yōu)勢(shì),逐步成為軟件開(kāi)發(fā)人員進(jìn)行報(bào)表打印功能開(kāi)發(fā)的首要選擇[1-3]。
當(dāng)前應(yīng)用較多的報(bào)表組件主要有Crystal Report、Grid++ Report和AC Report等,其中AC Report是一款國(guó)內(nèi)最早的基于表格,支持圖文混排、公式和腳本的中國(guó)式報(bào)表組件。由于AC Report組件具有表格的靈活性、功能的全面性、樣式的多樣性等特性,并且更適合中國(guó)本土化報(bào)表習(xí)慣,從而成為了國(guó)內(nèi)報(bào)表開(kāi)發(fā)領(lǐng)域使用的主流組件。該文以某被裝管理信息系統(tǒng)中基于AC Report組件的報(bào)表打印的設(shè)計(jì)實(shí)現(xiàn)為例進(jìn)行討論。
1 報(bào)表打印的功能設(shè)計(jì)
1.1 打印流程
基于AC Report組件的報(bào)表數(shù)據(jù)是直接從數(shù)據(jù)庫(kù)讀取的,打印流程比較簡(jiǎn)單:
1)打印開(kāi)始;
2)系統(tǒng)讀取并加載數(shù)據(jù)庫(kù)中的報(bào)表數(shù)據(jù)到報(bào)表模板的數(shù)據(jù)集中;
3)系統(tǒng)調(diào)用報(bào)表模板,模板根據(jù)插入的數(shù)據(jù)字段讀取數(shù)據(jù)集中的數(shù)據(jù),并將其加載到報(bào)表中,完成打印或打印預(yù)覽動(dòng)作。
1.2 數(shù)據(jù)庫(kù)設(shè)計(jì)
如上節(jié)所述,AC Report組件在報(bào)表生成中會(huì)直接調(diào)用報(bào)表模板,模板再根據(jù)報(bào)表的數(shù)據(jù)字段讀取數(shù)據(jù)庫(kù)數(shù)據(jù)并將其輸出。在此過(guò)程中,往往有兩個(gè)問(wèn)題需要注意。
一是數(shù)據(jù)轉(zhuǎn)換問(wèn)題。由于組件技術(shù)的通用特征,數(shù)據(jù)庫(kù)中數(shù)據(jù)的格式和內(nèi)容不一定正是程序開(kāi)發(fā)人員想要的輸出,這就需要對(duì)那些不符合要求的數(shù)據(jù)進(jìn)行轉(zhuǎn)換,主要是增加需要的數(shù)據(jù),簡(jiǎn)單地如在日期數(shù)據(jù)中添加“年、月、日”等。為了不修改原始數(shù)據(jù),通用的解決方法是在數(shù)據(jù)庫(kù)中創(chuàng)建新的數(shù)據(jù)表,打印時(shí)將轉(zhuǎn)換之后的報(bào)表數(shù)據(jù)寫(xiě)入到相應(yīng)的表中,以備模板直接讀取進(jìn)行打印。
二是數(shù)據(jù)沖突問(wèn)題。以上方案雖然解決了報(bào)表數(shù)據(jù)轉(zhuǎn)換問(wèn)題,但由于每次打印都需要讀寫(xiě)數(shù)據(jù)庫(kù),這在分布式系統(tǒng)中,特別是在報(bào)表打印比較集中的時(shí)期,極有可能造成數(shù)據(jù)讀寫(xiě)沖突。為此,提出了另一種解決方案,即在本地創(chuàng)建一個(gè)輕便的Access數(shù)據(jù)庫(kù),用它來(lái)儲(chǔ)存打印所需的全部數(shù)據(jù),打印時(shí)先清空相應(yīng)的數(shù)據(jù)表,再把所需數(shù)據(jù)轉(zhuǎn)換后寫(xiě)入其中,當(dāng)系統(tǒng)調(diào)用報(bào)表模板后,模板讀取庫(kù)中數(shù)據(jù)并將其加載到報(bào)表中。由于數(shù)據(jù)庫(kù)的讀寫(xiě)都在本地,從而很好的解決了沖突問(wèn)題。
1.3 報(bào)表模板設(shè)計(jì)
報(bào)表模板的設(shè)計(jì)都是在AC Report組件的報(bào)表設(shè)計(jì)器中完成的,它的風(fēng)格近Word表格風(fēng)格,但它比Word或Excel表格更加靈活,而且功能全面,支持多種報(bào)表樣式和多種單元格樣式。系統(tǒng)開(kāi)發(fā)人員可以根據(jù)用戶(hù)需求,很方便的完成清單式、分組式、交叉式以及子報(bào)表等樣式設(shè)計(jì),也可以在單元格中完成圖像、圖表、RICH文本、條形碼等的編輯,還可以在報(bào)表中嵌入Word或Excel文檔。設(shè)計(jì)完報(bào)表和單元格樣式后,再插入需要的數(shù)據(jù)字段、變量、公式等。
2 報(bào)表打印的功能實(shí)現(xiàn)
為了更好的討論報(bào)表打印的實(shí)現(xiàn)過(guò)程,現(xiàn)以Visual Studio 2005環(huán)境下MFC編寫(xiě)的基于AC Report2.89組件的被裝服務(wù)系統(tǒng)為例,進(jìn)行具體的闡述說(shuō)明。
2.1 數(shù)據(jù)庫(kù)的設(shè)計(jì)實(shí)現(xiàn)
在被裝服務(wù)系統(tǒng)中,需要對(duì)進(jìn)出庫(kù)各項(xiàng)業(yè)務(wù)的相關(guān)清單報(bào)表進(jìn)行打印,現(xiàn)在以正常入庫(kù)為例來(lái)介紹數(shù)據(jù)庫(kù)的設(shè)計(jì)實(shí)現(xiàn)。使用Access軟件創(chuàng)建一個(gè)print.mdb數(shù)據(jù)庫(kù),建一張bzfw_order數(shù)據(jù)表來(lái)儲(chǔ)存訂單基本信息。由于正常入庫(kù)的一個(gè)訂單中可能包含多個(gè)被裝條目,因此還需要再建一張bzfw_orderdetail表來(lái)儲(chǔ)存訂單中被裝條目的信息,它們的設(shè)計(jì)如下圖所示。
2.2 報(bào)表模板的設(shè)計(jì)實(shí)現(xiàn)
報(bào)表模板的設(shè)計(jì)實(shí)現(xiàn)是報(bào)表打印的核心工作,主要包括兩方面的內(nèi)容:報(bào)表設(shè)計(jì)器中數(shù)據(jù)集的加載和報(bào)表模板設(shè)計(jì)。
2.2.1 報(bào)表設(shè)計(jì)器中數(shù)據(jù)集的加載
模板中數(shù)據(jù)字段的插入是通過(guò)模板設(shè)計(jì)器的數(shù)據(jù)集來(lái)完成的,因此需要用記錄集對(duì)象指針來(lái)獲取報(bào)表數(shù)據(jù),得到記錄集后加載到設(shè)計(jì)器的數(shù)據(jù)集里。仍然以正常入庫(kù)為例,首先創(chuàng)建一個(gè)CPrintDlg類(lèi),然后在頭文件中定義bzfw_order和bzfw_orderdetail兩個(gè)記錄集對(duì)象指針,在Createobjects()函數(shù)中創(chuàng)建記錄集對(duì)象實(shí)例,代碼如下:
HRESULT hr;
hr = bzfw_order.CreateInstance(__uuidof(Recordset));
if(!SUCCEEDED(hr))
return -1;
hr = bzfw_orderdetail.CreateInstance(__uuidof(Recordset));
if(!SUCCEEDED(hr))
return -1;
然后在RefreshData()函數(shù)中調(diào)用AddDataToAc(CString sql, CString sTableName, _RecordsetPtr rs)函數(shù)來(lái)得到記錄集,并將其加載到設(shè)計(jì)器的數(shù)據(jù)集中。其代碼如下:
AddDataToAc("select * from bzfw_order ","bzfw_order",bzfw_order);
AddDataToAc("select * from bzfw_orderdetail","bzfw_orderdetail",
bzfw_orderdetail);
2.2.2 報(bào)表模板設(shè)計(jì)實(shí)現(xiàn)
在AC Report組件提供的報(bào)表設(shè)計(jì)器中,可以很方便的編輯報(bào)表格式和內(nèi)容。根據(jù)正常入庫(kù)清單特性,設(shè)計(jì)上下兩個(gè)表格分別用來(lái)顯示訂單基本信息和被裝條目信息。在報(bào)表樣式設(shè)置對(duì)話(huà)框中將其樣式設(shè)置為主細(xì)報(bào)表,并設(shè)置主項(xiàng)、細(xì)項(xiàng)、頁(yè)尾、表尾的位置以及主項(xiàng)數(shù)據(jù)和明細(xì)數(shù)據(jù)的數(shù)據(jù)連接等。設(shè)計(jì)好報(bào)表版式,再向模板中插入文本、數(shù)據(jù)字段、日期頁(yè)碼等數(shù)據(jù)。一個(gè)設(shè)計(jì)完成的報(bào)表模板如下圖2所示,最后將其保存到項(xiàng)目指定的文件夾中,等待打印程序的調(diào)用。
2.3 打印和打印預(yù)覽的實(shí)現(xiàn)
當(dāng)用戶(hù)觸發(fā)某一報(bào)表的打印后,系統(tǒng)首先將相應(yīng)的報(bào)表數(shù)據(jù)寫(xiě)入到數(shù)據(jù)表中。然后創(chuàng)建一個(gè)CPrintDlg對(duì)象,利用對(duì)象的ReportName成員來(lái)存儲(chǔ)打印所用的模板名稱(chēng),最后彈出打印對(duì)話(huà)框,代碼如下:
CPrintDlg printdlg;
printdlg.ReportName = "bzfw_NI.apt";
printdlg.DoModal();
在打印對(duì)話(huà)框中有“打印”和“打印預(yù)覽”兩各選項(xiàng),選擇后執(zhí)行以下代碼:
mac→SetReportFile((_bstr_t)(ReportPath + ReportName));
if (((CButton *)this→GetDlgItem(IDC_RADIO1))→GetCheck())
mac→Preview();
else
if (((CButton *)this→GetDlgItem(IDC_RADIO2))→GetCheck())
mac→Print();
通過(guò)SetReportFile函數(shù)設(shè)置模板調(diào)用的完整路徑。而后面5行代碼則是根據(jù)用戶(hù)選擇執(zhí)行打印或者打印預(yù)覽動(dòng)作。而在打印預(yù)覽中可以根據(jù)用戶(hù)需要將報(bào)表導(dǎo)出成多種格式的文件。正常入庫(kù)清單的打印預(yù)覽如圖3所示。
3 結(jié)論
綜上所述,基于AC Report的報(bào)表打印方案具有較強(qiáng)的通用性和靈活性,而且功能豐富,可以根據(jù)不同的打印需求,高效地完成報(bào)表輸出的程序設(shè)計(jì),大大縮短系統(tǒng)開(kāi)發(fā)周期。
參考文獻(xiàn):
[1] 張曦澤,王華文,王中秋.基于組件的報(bào)表自動(dòng)生成系統(tǒng)的研究與實(shí)現(xiàn)[J].計(jì)算機(jī)工程與設(shè)計(jì),2005,26(5):1358-1360.
[2] 戚瑋瑋,宋朝輝,宋大雷,欒新.B/S模式下條形碼票證自定義打印的設(shè)計(jì)和實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用與軟件,2010,27(12):170-173.
[3] 陶劍青,黃志球,沈國(guó)華.一個(gè)通用報(bào)表工具的設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)工程與設(shè)計(jì),2003,24(10):34-36.