摘要:打印功能是絕大部分軟件項目中必不可以少的功能,該文從原理的角度介紹了通用打印模塊的設(shè)計方法。如果讀者能熟練地掌握這一設(shè)計原理,相信很快就可以設(shè)計出自已所需要的報表,用其它開發(fā)語言工具,也可以很快設(shè)計出自已所需要的打印模塊。
關(guān)鍵詞:打印模塊;自定義;.NET
中圖分類號:TP311 文獻標識碼:A 文章編號:1009-3044(2009)05-1093-03
Design and Implementation of Custom Printing Function Based on .NET
DU Cheng-long
(Hubei Professional College of Land Resource, Jingzhou 434002, China)
Abstract: Printing function is the vast majority of software projects will not be less functionality, this article from the principle point of view introduced the general printing module design. If the skilled reader can grasp the principles of design, will soon be able to have been designed from the required statements, with the development of other language tools, you can quickly design the printing module required.
Key words: printing function; custom; .NET
1 引言
隨著軟件技術(shù)的發(fā)展,越來越多的新的或更先進的開發(fā)工具出現(xiàn),軟件開發(fā)也越來越方便。但先進的工具出現(xiàn)也使得很多開發(fā)者疲于學(xué)習(xí)更多新的東西。實際上,我們更贊同使用通用性較好的原理性的開發(fā)方法,只要熟練掌握并熟練實現(xiàn),就不至于因工具的變化而干擾我們的工作思路。
打印功能很長時間都一直困繞著筆者,以至于筆者做軟件時總覺得不完美,要么是設(shè)計的功能不好用,要么就是設(shè)計得不合要求,總是感覺到欠缺什么,后來究其原因,原來這實際上是沒有真正掌握一種通用的好的設(shè)計方法所至,市面上又很少看到有關(guān)書籍介紹一種能快速地掌握自定義打印功能的方法??吹接行┕δ軓姶蟮拇蛴≡O(shè)計軟件,真想自已能擁有一套,但第三方提供商又要收取昂貴的使用費,心里真的很煩躁,相信做過軟件的人都有這個感覺。筆者經(jīng)過一段時間的淺心學(xué)習(xí)和研究,終于掌握了自定義打印功能的設(shè)計與實現(xiàn)方法,在此與大家共享,相信很多有此需求的人會受益非淺。
下面以.NET平臺下C#語言為例,提出具體的設(shè)計方案,并以具體的實例說明實現(xiàn)方法,相信大家一定能據(jù)此觸類旁通,很輕松地設(shè)計出自已所需要的自定義打印功能。
2 設(shè)計思路及分析
下面以庫存商品為例講解自定義打印向?qū)Ъ按蛴☆A(yù)覽的實現(xiàn),因自定義打印功能設(shè)計是通用的,所以如果要用在其它地方,只需改動一下輸入條件即可使用。
設(shè)計效果及思路如下:
1) 點擊如圖1下的打印按鈕后顯示如圖2對話框,這是向?qū)υ捒虻牡谝徊健?/p>
2) 如圖2點擊下一步后,會顯示如圖3對話框,這是向?qū)υ捒虻牡诙健?/p>
3) 如圖3點擊下一步后,會顯示如圖4的對話框,這是向?qū)υ捒虻牡谌健?/p>
4) 如圖4 點擊上一步后,會顯示如圖3第二步的對話框,可以對前面設(shè)置的內(nèi)容進行修改。
5) 如圖4點擊完成之后,會顯示如圖5打印預(yù)覽效果。
下面對以上操作的設(shè)計流程進行一下分析和說明:
首先是進行打印前數(shù)據(jù)的輸入,由于本功能做成了通用模式,所以只需重新設(shè)置輸入條件即可,那么本模塊可以直接用在其它類似的打印模塊中。
其次是進行打印前的標題及數(shù)據(jù)顯示設(shè)置,當設(shè)置好所有的條件及數(shù)據(jù)之后,就可以實現(xiàn)打印功能了。
最后是實現(xiàn)打印功能,只要掌握如何編寫在指定的位置繪制表格和文字的方法,即可很容易實現(xiàn)打印功能了。
3 關(guān)鍵技術(shù)設(shè)計與實現(xiàn)
要完整實現(xiàn)自定義打印功能,根據(jù)上面的設(shè)計主要包括數(shù)據(jù)輸入部分、顯示設(shè)置部分和打印預(yù)覽部分。下面按實現(xiàn)方案分別討論關(guān)鍵技術(shù)。
3.1 建立數(shù)據(jù)輸入程序
1) 首先在設(shè)計之前要定義一個專門用于存儲向?qū)гO(shè)置時的打印設(shè)置類,定義cReportInfo.cs文件,參考代碼如下:
class cReportInfo{
public static string PrimaryTitle;//主標題
public static string SecondaryTitle;//副標題
public static string StartDate;//起始時間
public static string EndDate;//結(jié)束時間
public static string Comments;//附注
public static string Author;//制表人
public static string Date;//制表日期
public static ArrayList ReportColumns = new ArrayList();//所有的供選擇的列名稱
public static ArrayList ReportSelectColumns=new ArrayList();//已選擇的列名稱
//對標題進行初始化
public static void ClearTitle(){……}
//清空列名稱
public static void ClearColumns(){……}
}
2) 下面是定義打印前的數(shù)據(jù)輸入設(shè)置方法,如果用在其它地方,只需在此修改輸入數(shù)據(jù)即可,當點擊打印按鈕后,就會進入向?qū)н^程,設(shè)計算法描述如下:
private void tlBtnPrint_Click(object sender, EventArgs e)
{ 清空打印設(shè)置類;
從數(shù)據(jù)顯示控件獲取所有供選擇的列名稱;
將數(shù)據(jù)顯示控件作參數(shù)傳給向?qū)Т绑w(1);
將向?qū)Т绑w(1)顯示出來;
}
3) 向?qū)Т绑w(1)主要是為了顯示一些提示信息及準備一些必需的數(shù)據(jù),顯示時需要進行一些初始化,即要傳入需要的參數(shù)。當在向?qū)Т绑w(1)中,點擊下一步按鈕時,要打開向?qū)Т绑w(2),并傳入需要的參數(shù),算法描述如下:
private void BtnNext_Click(object sender, EventArgs e){ 定義向?qū)Т绑w(2)對象并傳入?yún)?shù);
顯示向?qū)Т绑w(2);}
數(shù)據(jù)輸入程序的功能主要是獲取即將顯示的數(shù)據(jù)源問題,但這只是完成了第一步,下面是完成打印的設(shè)置問題。
3.2 建立顯示設(shè)置程序
建立顯示設(shè)置程序主要是為了確定打印顯示的內(nèi)容,此處實際上是設(shè)置cReportInfo類型的對象中的所有數(shù)據(jù)成員。
由于在每一步向?qū)Т翱陲@示本窗體時要將前階段有效的數(shù)據(jù)傳入,故要重載構(gòu)造函數(shù)用于設(shè)置傳入的參數(shù)。同時為了保存前階段傳入的數(shù)據(jù)設(shè)置,需要實現(xiàn)Load方法;
打印向?qū)?2)和打印向?qū)?3)窗體是顯示設(shè)置的主要窗口,操作方便是這兩個窗口要解決的首要任務(wù),此界面功能設(shè)計很簡單,在此不再闡述。
3.3 建立打印預(yù)覽程序
建立打印預(yù)覽程序是本功能模塊的核心,實現(xiàn)打印功能最主要是掌握打印過程實現(xiàn)的原理及繪圖方法。
當打印文檔對象PrintDocument被調(diào)用時,會激活PrintPage事件,在此方法中就可以實現(xiàn)繪制報表的任務(wù)。算法描述如下:
private void pd_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{初始化變量;
try{
繪制機密;
繪制標題;
繪制副標題;
//繪制矩形表格及數(shù)據(jù)
//1.繪制列名稱;
for (int col = 0; col < 所選擇的列數(shù);col++ )
{ 畫列標題;}
yPos += 50;
//2.繪制多行數(shù)據(jù)
while (rowindex < 行數(shù)-1)
{獲取整行最大的行高;
for (int col = 0; col <所選擇的列數(shù);col++)
{ 繪制該行每個單元格的數(shù)據(jù); }
yPos += rowHeight;
rowindex++;
if(當前高度大于底邊界值)
{e.HasMorePages = true;//分頁打印
return;
}
}
繪制附注;
繪制制表人;
繪制制表日期;
e.HasMorePages = 1;//結(jié)束打印
}catch (System.Exception ex)
{錯誤提示;}
}
繪制思路確定下來后,下面主要是掌握繪制單元格的方法。不管是文字部分還是矩形框部分,統(tǒng)一繪制矩形框,然后中間填寫文字內(nèi)容。如果只寫文字畫空邊即可,如果只畫矩形框?qū)懣瘴淖旨纯伞N覀儼颜麄€頁面分割成了一個個小單元格之后,就可以任意的根據(jù)需要畫矩形框了。下面自定義繪單元格的參考代碼如下:
private void DrawCell(Graphics g,Rectangle r,string s,string fontName,int fontSize,StringAlignment hAlign,StringAlignment vAlign,bool bold)
{ try
{Pen p=new Pen(Brushes.Gray);
g.DrawRectangle(p,r);
Font oldFont=new Font(fontName,fontSize);
Font newFont=new Font(oldFont,bold?oldFont.Style|FontStyle.Bold:oldFont.Style);
StringFormat sf=new StringFormat();
sf.Alignment=hAlign;
sf.LineAlignment=vAlign;
g.DrawString(s,newFont,Brushes.Black,r,sf);(下轉(zhuǎn)第1099頁)
(上接第1095頁)
}catch(Exception ex){錯誤提示; }
}
此處定義的繪單元格的方法基本可以通用,只需傳入合適的參數(shù)就可以繪出所需要的單元格。如果想要畫出更復(fù)雜的單元格,在此基礎(chǔ)上添加內(nèi)容即可。
4 結(jié)束語
打印功能是絕大部分軟件項目中必不可以少的功能,但是市面上絕大部分相關(guān)資料上都很少有設(shè)計通用性較強的打印模塊的介紹,如果讀者能熟練地掌握這一設(shè)計原理,相信很快就可以設(shè)計出其它的報表,即使用其它開發(fā)工具,也可以很快設(shè)計出自已所需要的打印模塊。
參考文獻:
[1] 張躍廷.C#數(shù)據(jù)庫系統(tǒng)開發(fā)完全手冊[M].北京:人民郵電出版社,2006.
[2] 李繼武.VisualC#.NET項目開發(fā)實戰(zhàn)[M].北京:清華大學(xué)出版社,2007.