在VB中,如果要打印打印A4文檔,且內容是從DB中,或者DataGrid中等動態獲取的,實現起來非常簡 單,諸如以下代碼(rs表示一記錄集):
rs.MoveFirst
Printer.PaperSize = vbPRPSA4
Printer.Orientation = vbPRORPortrait
Printer.FontName = "Courier New"
Printer.FontBold = True
Printer.FontSize = 24
Printer.Print " FQA Report"
Printer.FontSize = 16
Printer.Print " Pallet ID:" & Trim(rs("pallet_id"))
NewLine2 = String(100, " ")
Mid(NewLine2, 1, 5) = "NO#"
Mid(NewLine2, 10, 30) = "System S/N"
Mid(NewLine2, 35, 20) = "BOX_ID"
Mid(NewLine2, 60, 20) = "Pallet_ID"
While Not rs.EOF
NewLine2 = String(100, " ")
Mid(NewLine2, 1, 5) = Trim(rs("No"))
Mid(NewLine2, 10, 30) = Trim(rs("SN"))
Mid(NewLine2, 35, 20) = Trim(rs("BOX_ID"))
Mid(NewLine2, 60, 20) = "" & Trim(rs("Pallet_ID"))
Printer.Print NewLine2
rs.MoveNext
Wend
Printer.Print NewLine2
Printer.Print String(100, "-")
在上述代碼中,如果記錄集中的數量很多, 即內容超出了一頁紙,程序不用做任何設置,便會自動分頁,那麼到.Net中,如何實現這麼一個簡單的功 能呢?
查了好多資料,上網搜了好久,發現沒有類似的例子,看了MSDN後,才發現,到VB.Net中 ,VB中那麼好用的Printer不見了,一下為MSDN的描述:http://msdn.microsoft.com/zh- tw/library/cc438273(VS.71).aspx
"Visual Basic 6.0 中的 Printer 物件在 Visual Basic .NET 中是由 PrintDocument 組件取 代。兩者的行為不同,但在多數情況下可復制功能。下表將列出 Visual Basic 6.0 屬性 (Property)、 方法及事件與其 Visual Basic .NET 對等用法。如果沒有直接的對等用法,則會提供連結以取得其它信 息。除非另外注明,否則所有的對象都是在 System.Drawing 命名空間中。"
第一感覺是, 在.Net中有比這更好用的打印功能,而且功能更強大,於是開始翻書,上網找例子,花了好長時間後,終 於在網上找到了兩個例子,跟教科書(C#高級編程第四版第25章,VB 2005入門經典第7章)裡的例子差不 多,例子中都是要先打開文檔,LoadFile後,然後計算中共有多少行,然後設置一些屬性等等,雖然功能 強大,但是極其復雜,不能直接拿來用,於是只好自己改寫。。。
打印Function:
public bool PrintDoc()
{
try
{
//獲取需要打 印的內容
string strSQL = "exec [usp_PalletPrintDocInfo] '"
+ Parameters.strStation + "', '" + Parameters.strPalletID + "'";
dsPrintInfo = doDB.GetDataSet(strSQL);
if (dsPrintInfo.Tables[0].Rows.Count < 1 || dsPrintInfo.Tables[1].Rows.Count < 1)
{
Parameters.strMsg = "Get Print Information Error";
return false;
}
//打印
PrintDocument printDocument = new PrintDocument();
printDocument.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
printDocument.Print();
/**/////打印預覽,調試的時候,可以通過這個,節約紙張
//PrintPreviewDialog ppd = new PrintPreviewDialog();
//PrintDocument pd = new PrintDocument();
//pd.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
//ppd.Document = pd;
//ppd.ShowDialog();
return true;
}
catch(Exception ex)
{
Parameters.strMsg = ex.Message.ToString();
return false;
}
}
上面代碼中 ,核心的是下面這個事件,調用pd_PrintPage方法:
//打印
PrintDocument printDocument = new PrintDocument();
printDocument.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
printDocument.Print ();
pd_PrintPage方法:
//打印A4紙用的變量#region //打印A4紙用的變量
DataSet dsPrintInfo; //存放要打印的信息,資料從DB中獲取,表一位SN信息,表二為WO信息
private int lineNo; //存放當前要打印行的行號
private int lineQty; //存放總 共要打印的行數,可以是一個估算值,略大於實際行數
private int printingPageNo = 0; //當前 打印的頁號
#endregion
private void pd_PrintPage(object sender, PrintPageEventArgs e)
{
string strLine;//用於存放當前行打印的信息
float leftMargin = (e.MarginBounds.Left) * 3 / 4; //左邊距
float topMargin = e.MarginBounds.Top * 2 / 3; //頂邊距
float verticalPosition = topMargin; //初始化垂 直位置,設為頂邊距
Font mainFont = new Font("Courier New", 10);//打印的字 體
//每頁的行數,當打印行數超過這個時,要換頁(1.05這個值是根據實際情況中設定的,可 以不要)
int linesPerPage = (int)(e.MarginBounds.Height * 1.05 / mainFont.GetHeight (e.Graphics));
//Format of this DocReport#region //Format of this DocReport
if (printingPageNo == 0) //打印第一頁時,需要打印以下頭信息
{
mainFont = new Font("Courier New", 24, FontStyle.Bold);
strLine = String.Format("{0,21}", "FQA Report");
e.Graphics.DrawString(strLine, mainFont, Brushes.Black, leftMargin, verticalPosition, new StringFormat());
verticalPosition = verticalPosition + mainFont.GetHeight (e.Graphics);
mainFont = new Font("Courier New", 16, FontStyle.Bold);
strLine = "Pallet ID:" + dsPrintInfo.Tables[0].Rows [0]["Pallet_ID"].ToString();
e.Graphics.DrawString(strLine, mainFont, Brushes.Black, leftMargin, verticalPosition, new StringFormat());
verticalPosition = verticalPosition + mainFont.GetHeight(e.Graphics);
mainFont = new Font("3 of 9 Barcode", 24, FontStyle.Bold);
strLine = "*" + dsPrintInfo.Tables[0].Rows[0]["Pallet_ID"].ToString() + "*";
e.Graphics.DrawString(strLine, mainFont, Brushes.Black, leftMargin * 4, verticalPosition, new StringFormat());
verticalPosition = verticalPosition + mainFont.GetHeight(e.Graphics);
mainFont = new Font ("Courier New", 16, FontStyle.Bold);
strLine = "QCI_PN:" + dsPrintInfo.Tables[0].Rows[0]["PARTNUMBER"].ToString();
e.Graphics.DrawString(strLine, mainFont, Brushes.Black, leftMargin, verticalPosition, new StringFormat());
verticalPosition = verticalPosition + mainFont.GetHeight (e.Graphics);
strLine = "Date :" + DateTime.Now;
e.Graphics.DrawString(strLine, mainFont, Brushes.Black, leftMargin, verticalPosition, new StringFormat());
verticalPosition = verticalPosition + mainFont.GetHeight (e.Graphics);
strLine = "Line :" + dsPrintInfo.Tables[0].Rows[0] ["Mfg_Line"].ToString();
e.Graphics.DrawString(strLine, mainFont, Brushes.Black, leftMargin, verticalPosition, new StringFormat());
verticalPosition = verticalPosition + mainFont.GetHeight(e.Graphics);
strLine = "Model:" + dsPrintInfo.Tables[0].Rows[0]["Model"].ToString();
e.Graphics.DrawString(strLine, mainFont, Brushes.Black, leftMargin, verticalPosition, new StringFormat());
verticalPosition = verticalPosition + mainFont.GetHeight (e.Graphics) * 2;
//linesPerPage:上面的頭信息預計占的行數,因此第一頁還能打印 (linesPerPage - 15)行
linesPerPage = linesPerPage - 15;
//lineQty:lineQty行數大概是表行數加上15
lineQty = dsPrintInfo.Tables [0].Rows.Count + 15;
}
#endregion
//打印具體的SN,BoxID,PalletID列 表#region //打印具體的SN,BoxID,PalletID列表
//打印標題頭信息
mainFont = new Font("Courier New", 10);
strLine = String.Format("{0,-10}", "NO#") +
String.Format("{0,-25}", "System S/N") +
String.Format("{0,-25}", "BOX_ID") +
String.Format("{0,-25}", "Pallet_ID");
e.Graphics.DrawString (strLine, mainFont, Brushes.Black, leftMargin, verticalPosition, new StringFormat());
verticalPosition = verticalPosition + mainFont.GetHeight(e.Graphics);
//打印一 條橫線
mainFont = new Font("Courier New", 3);
e.Graphics.DrawLine(new Pen(Color.Black), leftMargin, verticalPosition, e.MarginBounds.Right, verticalPosition);
verticalPosition = verticalPosition + mainFont.GetHeight(e.Graphics);
//打印記錄集信息
int count = 0; //當前頁 的行數計數
mainFont = new Font("Courier New", 10);
//如果(當前頁 行計數器)小於(每頁可以打印的行數)且(要打印行的行號)小於(總共要打印的行數)
while (count < linesPerPage && lineNo < this.lineQty)
{
if (lineNo < dsPrintInfo.Tables[0].Rows.Count) //由於lineNo用於表中的下標值,因此需要加上該 判斷
{
string strLineTemp = String.Format("{0,-10}", dsPrintInfo.Tables[0].Rows[lineNo]["NO"].ToString()) +
String.Format("{0,-25}", dsPrintInfo.Tables[0].Rows[lineNo] ["SN"].ToString()) +
String.Format("{0,-25}", dsPrintInfo.Tables[0].Rows[lineNo]["BOX_ID"].ToString()) +
String.Format("{0,-25}", dsPrintInfo.Tables[0].Rows[lineNo] ["Pallet_ID"].ToString());
e.Graphics.DrawString(strLineTemp, mainFont, Brushes.Black, leftMargin, verticalPosition, new StringFormat());
verticalPosition = verticalPosition + mainFont.GetHeight(e.Graphics);
count++; //注意:這句要放到If中,否則,如果實際只有一頁的話,尾信息會跑到第二頁去
}
lineNo++;
}
#endregion
//如果總行數大於目前實 際行號,表明還有頁要打,lineQty是估計數,因此實際用時要仔細估算
if (lineQty > lineNo)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
//打印結尾信息#region //打印結尾 信息
if (!e.HasMorePages)
{
mainFont = new Font("Courier New", 10);
e.Graphics.DrawLine(new Pen(Color.Black), leftMargin, verticalPosition, e.MarginBounds.Right, verticalPosition);
verticalPosition = verticalPosition + mainFont.GetHeight(e.Graphics);
foreach (DataRow dr in dsPrintInfo.Tables[1].Rows)
{
mainFont = new Font ("Courier New", 16);
strLine = String.Format("{0,-3}", "WO:") + String.Format("{0,-16}",dr["WO"].ToString())
+ String.Format("{0,-7}", "Qty:") + String.Format(" {0,-10}",dr["Qty"].ToString());
e.Graphics.DrawString (strLine, mainFont, Brushes.Black, leftMargin, verticalPosition, new StringFormat());
verticalPosition = verticalPosition + mainFont.GetHeight(e.Graphics);
}
foreach (DataRow dr in dsPrintInfo.Tables[2].Rows)
{
mainFont = new Font("Courier New", 16);
strLine = String.Format("{0,-9}", "TotalQty:") + String.Format("{0,-10} ", dr["TotalQty"].ToString())
+ String.Format("{0, -7}", "BoxQty:") + String.Format("{0,-10}",dr ["BoxQty"].ToString());
e.Graphics.DrawString(strLine, mainFont, Brushes.Black, leftMargin, verticalPosition, new StringFormat());
verticalPosition = verticalPosition + mainFont.GetHeight(e.Graphics);
}
}
#endregion
printingPageNo++; //頁號加一
}
打印效果大 致截圖:(如果有多頁,尾部的信息只在最後一頁顯示)
總結:如此簡單的功 能,在.Net中實現起來確實那麼的復雜,尤其是對於自動分頁的功能,雖然總體上功能強大了好多,但是 把原先那麼好用的東西給去掉了。以上代碼改寫成VB.Net的話,都差不多。。。