在 VB6 中列印 A4 文件,內容從 DB 或 DataGrid 動態獲取,實現非常簡單。但在 .NET 中,VB6 好用的 Printer 物件不見了,被 PrintDocument 元件取代。兩者行為不同,但多數情況可複製功能。查閱 MSDN 發現無直接對應用法,需自行實作。雖然 .NET 列印功能更強大,但極其複雜,教科書範例都要先開啟文件、LoadFile、計算行數、設定屬性,無法直接拿來用,只好自行改寫。
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;
}
}
// 列印 A4 用變數
#region 列印變數
DataSet dsPrintInfo; // 要列印資訊,表一 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);
// 每頁行數,超過需換頁
int linesPerPage = (int)(e.MarginBounds.Height * 1.05 / mainFont.GetHeight(e.Graphics));
// 文件格式:第一頁列印表頭
#region 文件格式
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 += 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 += 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 += 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 += mainFont.GetHeight(e.Graphics);
strLine = "Date: " + DateTime.Now;
e.Graphics.DrawString(strLine, mainFont, Brushes.Black, leftMargin, verticalPosition, new StringFormat());
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 += 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 += mainFont.GetHeight(e.Graphics) * 2;
// 表頭預計佔 15 行
linesPerPage -= 15;
// 總行數約為資料行數 + 15
lineQty = dsPrintInfo.Tables[0].Rows.Count + 15;
}
#endregion
// 列印 SN、BoxID、PalletID 明細列表
#region 明細列表
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 += mainFont.GetHeight(e.Graphics);
// 列印分隔線
mainFont = new Font("Courier New", 3);
e.Graphics.DrawLine(new Pen(Color.Black), leftMargin, verticalPosition, e.MarginBounds.Right, 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) {
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 += mainFont.GetHeight(e.Graphics);
count++; // 注意:放在 If 內,否則單頁時尾部資訊會跑到第二頁
}
lineNo++;
}
#endregion
// 判斷是否還有頁面
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 += 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 += 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 += mainFont.GetHeight(e.Graphics);
}
}
#endregion
printingPageNo++; // 頁號加一
}

如此簡單功能,在 .NET 實現確實複雜,尤其是自動分頁。雖然整體功能強大許多,但把原本好用的功能移除了。以上程式碼改寫成 VB.NET 也差不多。