Dotnet總結(3)--打印 - 中國WEB開發者網絡 (http://www.webasp.net) -- 技術教程 (http://www.webasp.net/article/) --- Dotnet總結(3)--打印 (http://www.webasp.net/article/18/17581.htm) |
| -- 作者:未知 -- 發佈日期: 2005-04-18 |
| eg: private DataGridPrinter m_oDataGridPrinter; protected System.Windows.Forms.PrintPreviewDialog printPreviewDialog1; private System.Windows.Forms.PrintDialog printDialog1; public System.Drawing.Printing.PrintDocument printDocument1; // 預覽 try { m_oDataGridPrinter = new DataGridPrinter(this.dataGrid_Brand, printDocument1, (DataTable)this.dataGrid_Brand.DataSource); this.printPreviewDialog1.ShowDialog(); catch { MessageBox.Show("沒有找到打印機,不能預覽!"); } // 打印 public DialogResult Print() { try { // DataTable oDTTmp = (DataTable)this.dataGrid_Brand.DataSource; // if (oDTTmp==null || oDTTmp.Rows.Count<=0) // { // MessageBox.Show("主窗口中沒有數據,請進行\"查詢\"或者\"顯示所有\"等操作,將您要打印的數據顯示在主窗口中,然後再進行打印!"); // return DialogResult.Cancel; // } m_oDataGridPrinter = new DataGridPrinter(this.dataGrid_Brand, printDocument1, (DataTable)this.dataGrid_Brand.DataSource); if (this.printDialog1.ShowDialog() == DialogResult.OK) { this.printDocument1.Print(); return DialogResult.OK; } else { return DialogResult.Cancel; } } catch { MessageBox.Show("沒有找到打印機,不能打印!"); return DialogResult.Cancel; } return DialogResult.OK; } // 事件定義 this.printDocument1.DocumentName = "Brand"; this.printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.printDocument1_PrintPage); // 事件響應 private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { e.HasMorePages = m_oDataGridPrinter.DrawDataGrid(e.Graphics); if (e.HasMorePages) { m_oDataGridPrinter.PageNumber += 1; } else { m_oDataGridPrinter.PageNumber = 1; m_oDataGridPrinter.RowCount = 0; } // 基類定義 Imports System.Drawing.Printing Imports System.Windows.Forms Imports System.Drawing Public Class DataGridPrinter Public RowCount As Integer = 0 Public PageNumber As Integer = 1 Private m_DataTable As DataTable Private m_DataGrid As DataGrid Private m_ImageArray(2) As Image Private m_PageWidth As Integer Private m_PageWidthMinusMargins As Integer Private m_PageHeight As Integer Private m_AdjColumnBy As Integer Private m_IsTooWide As Boolean Private m_DataGridWidth As Integer Private m_sSelectString As String Private Const c_TopMargin As Integer = 50 Private Const c_BottomMargin As Integer = 50 Private Const c_LeftMargin As Integer = 50 Private Const c_RightMargin As Integer = 50 Private Const c_VerticalCellLeeway As Integer = 10 Public Sub New(ByVal dg As DataGrid, ByVal pd As PrintDocument, ByVal dt As DataTable) m_sSelectString = "" m_DataGrid = dg m_DataTable = dt 'set the document as landscape pd.DefaultPageSettings.Landscape = True 'extract our width and height values m_PageHeight = pd.DefaultPageSettings.PaperSize.Width m_PageWidth = pd.DefaultPageSettings.PaperSize.Height m_PageWidthMinusMargins = m_PageWidth - (c_LeftMargin + c_RightMargin) 'hard-coded images 'm_ImageArray(0) = Image.FromFile("images/major.gif") 'm_ImageArray(1) = Image.FromFile("images/medium.gif") 'm_ImageArray(2) = Image.FromFile("images/minor.gif") m_DataGridWidth = GetDataGridWidth() 'set up some adjustments to scale the output later If m_DataGrid.Width > m_PageWidthMinusMargins Then m_AdjColumnBy = m_DataGrid.Width - m_PageWidthMinusMargins m_DataGridWidth = m_DataGridWidth - m_AdjColumnBy m_IsTooWide = True Else m_AdjColumnBy = m_PageWidthMinusMargins - m_DataGrid.Width m_DataGridWidth = m_DataGridWidth + m_AdjColumnBy m_IsTooWide = False End If End Sub Public Sub New(ByVal dg As DataGrid, ByVal pd As PrintDocument, ByVal dt As DataTable, ByVal headString As String) m_sSelectString = headString m_DataGrid = dg m_DataTable = dt 'set the document as landscape pd.DefaultPageSettings.Landscape = True 'extract our width and height values m_PageHeight = pd.DefaultPageSettings.PaperSize.Width m_PageWidth = pd.DefaultPageSettings.PaperSize.Height m_PageWidthMinusMargins = m_PageWidth - (c_LeftMargin + c_RightMargin) 'hard-coded images 'm_ImageArray(0) = Image.FromFile("images/major.gif") 'm_ImageArray(1) = Image.FromFile("images/medium.gif") 'm_ImageArray(2) = Image.FromFile("images/minor.gif") m_DataGridWidth = GetDataGridWidth() 'set up some adjustments to scale the output later If m_DataGrid.Width > m_PageWidthMinusMargins Then m_AdjColumnBy = m_DataGrid.Width - m_PageWidthMinusMargins m_DataGridWidth = m_DataGridWidth - m_AdjColumnBy m_IsTooWide = True Else m_AdjColumnBy = m_PageWidthMinusMargins - m_DataGrid.Width m_DataGridWidth = m_DataGridWidth + m_AdjColumnBy m_IsTooWide = False End If End Sub Public Function DrawDataGrid(ByVal g As Graphics) As Boolean Try DrawPageHeader(g) Return DrawPageRows(g) Catch ex As Exception ' MessageBox.Show(ex.Message.ToString()) Return False End Try End Function Private Sub DrawPageHeader(ByVal g As Graphics) 'use this format when drawing later Dim cellFormat As New StringFormat cellFormat.Trimming = StringTrimming.Word cellFormat.FormatFlags = StringFormatFlags.NoWrap Or StringFormatFlags.LineLimit If m_sSelectString.Length > 0 Then 'temp width to draw this column Dim columnWidth As Integer = m_PageWidthMinusMargins - 10 'create a layout rectangle to draw within. Dim cellBounds As New RectangleF(c_LeftMargin + 12, c_TopMargin - 9, columnWidth, m_DataGrid.PreferredRowHeight + c_VerticalCellLeeway - 3) g.DrawString(m_sSelectString, m_DataGrid.Font, New SolidBrush(m_DataGrid.HeaderForeColor), cellBounds, cellFormat) 'create the header rectangle 'Dim headerBounds As New RectangleF(c_LeftMargin, c_TopMargin, m_PageWidthMinusMargins, m_DataGrid.HeaderFont.SizeInPoints + c_VerticalCellLeeway) Dim headerBounds As New RectangleF(c_LeftMargin + 12, c_TopMargin - 3 - 9 - 9 + m_DataGrid.PreferredRowHeight + c_VerticalCellLeeway, m_PageWidthMinusMargins - 10, m_DataGrid.PreferredRowHeight + c_VerticalCellLeeway - 3) 'draw the header rectangle g.FillRectangle(New SolidBrush(m_DataGrid.HeaderBackColor), headerBounds) Else 'create the header rectangle 'Dim headerBounds As New RectangleF(c_LeftMargin, c_TopMargin, m_PageWidthMinusMargins, m_DataGrid.HeaderFont.SizeInPoints + c_VerticalCellLeeway) Dim headerBounds As New RectangleF(c_LeftMargin + 12, c_TopMargin - 9, m_PageWidthMinusMargins - 10, m_DataGrid.PreferredRowHeight + c_VerticalCellLeeway - 3) 'draw the header rectangle g.FillRectangle(New SolidBrush(m_DataGrid.HeaderBackColor), headerBounds) End If Dim xPosition As Single = c_LeftMargin + 12 ' +12 for some padding 'find the column names from the tablestyle Dim cs As DataGridColumnStyle For Each cs In m_DataGrid.TableStyles(0).GridColumnStyles If cs.Width > 0 Then 'temp width to draw this column Dim columnWidth As Integer = cs.Width 'scale the summary column width 'note: just a quick way to fit the text to the page width 'this is not the best way to do this but it handles the most 'common ui path for this demo app If cs.MappingName = "TaskSummary" And m_IsTooWide Then columnWidth -= m_AdjColumnBy ElseIf cs.MappingName = "TaskSummary" Then columnWidth += m_AdjColumnBy End If If m_sSelectString.Length > 0 Then 'create a layout rectangle to draw within. Dim cellBounds As New RectangleF(xPosition, c_TopMargin - 9 + m_DataGrid.PreferredRowHeight + c_VerticalCellLeeway - 3, columnWidth, m_DataGrid.HeaderFont.SizeInPoints + c_VerticalCellLeeway) 'draw the column name g.DrawString(cs.HeaderText, m_DataGrid.HeaderFont, New SolidBrush(m_DataGrid.HeaderForeColor), cellBounds, cellFormat) Else 'create a layout rectangle to draw within. Dim cellBounds As New RectangleF(xPosition, c_TopMargin, columnWidth, m_DataGrid.HeaderFont.SizeInPoints + c_VerticalCellLeeway) 'draw the column name g.DrawString(cs.HeaderText, m_DataGrid.HeaderFont, New SolidBrush(m_DataGrid.HeaderForeColor), cellBounds, cellFormat) End If 'adjust the next X Pos xPosition += columnWidth End If Next End Sub Private Function DrawPageRows(ByVal g As Graphics) As Boolean 'Dim yPosition As Single = c_TopMargin + m_DataGrid.HeaderFont.SizeInPoints + (c_VerticalCellLeeway * 2) Dim yPosition As Single = c_TopMargin + m_DataGrid.PreferredRowHeight If m_sSelectString.Length > 0 Then yPosition += m_DataGrid.PreferredRowHeight End If 'use this format when drawing later Dim cellFormat As New StringFormat cellFormat.Trimming = StringTrimming.Word cellFormat.FormatFlags = StringFormatFlags.NoWrap Or StringFormatFlags.LineLimit Try If m_DataTable.DefaultView.Count <= 0 Then Dim xPosition As Single = c_LeftMargin + 12 ' +12 for some padding Dim cellBounds As New RectangleF(xPosition, yPosition, c_LeftMargin - c_RightMargin, m_DataGrid.PreferredRowHeight) g.DrawString("對不起,沒有找到您需要打印的數據,請您確認程序主窗口中有您需要打印的數據!", m_DataGrid.Font, New SolidBrush(m_DataGrid.HeaderForeColor), cellBounds, cellFormat) End If Catch ex As Exception Dim xPosition As Single = c_LeftMargin + 12 ' +12 for some padding Dim cellBounds As New RectangleF(xPosition, yPosition, c_LeftMargin - c_RightMargin, m_DataGrid.PreferredRowHeight) g.DrawString("對不起,沒有找到您需要打印的數據,請您確認程序主窗口中有您需要打印的數據!", m_DataGrid.Font, New SolidBrush(m_DataGrid.HeaderForeColor), cellBounds, cellFormat) Return False End Try 'loop each visible row Dim i As Integer = 0 For i = RowCount To (m_DataTable.DefaultView.Count - 1) Dim xPosition As Single = c_LeftMargin + 12 ' +12 for some padding 'g.DrawLine(New Pen(m_DataGrid.GridLineColor, 1), xPosition - 3, yPosition - 3, xPosition - 3, yPosition + m_DataGrid.PreferredRowHeight + c_VerticalCellLeeway - 1) 'loop the columns of this row, if the column is visible 'then print the cell value Dim cs As DataGridColumnStyle For Each cs In m_DataGrid.TableStyles(0).GridColumnStyles If cs.Width > 0 Then 'temp width to draw this column Dim columnWidth As Integer = cs.Width 'scale the summary column width 'note: just a quick way to fit the text to the page width 'this is not the best way to do this but it handles the most 'common ui path for this demo app If cs.MappingName = "TaskSummary" And m_IsTooWide Then columnWidth -= m_AdjColumnBy ElseIf cs.MappingName = "TaskSummary" Then columnWidth += m_AdjColumnBy End If 'create a layout rectangle to draw within. 'Dim cellBounds As New RectangleF(xPosition, yPosition, columnWidth, m_DataGrid.Font.SizeInPoints + c_VerticalCellLeeway) Dim cellBounds As New RectangleF(xPosition, yPosition, columnWidth, m_DataGrid.PreferredRowHeight) 'draw the item value If cs.MappingName = "商標圖片" Then Try 'draw image Dim by As Byte() = CType(m_DataTable.DefaultView.Item(i).Item(cs.MappingName), Byte()) Dim imageToDraw As Image Dim oMemoryStream As System.IO.MemoryStream oMemoryStream = New System.IO.MemoryStream(by, 0, by.Length) 'oMemoryStream = New System.IO.MemoryStream((byte[])this.GetColumnValueAtRow(source, rowNum), 0, CType(m_DataTable.DefaultView.Item(i).Item(cs.MappingName), Byte)) 'oMemoryStream = New System.IO.MemoryStream(CType(m_DataTable.DefaultView.Item(i).Item(cs.MappingName), [] Byte), 0, CType(m_DataTable.DefaultView.Item(i).Item(cs.MappingName), Byte)) 'MemoryStream oMemoryStream=new MemoryStream((byte[])this.GetColumnValueAtRow(source, rowNum),0,((byte[])this.GetColumnValueAtRow(source, rowNum)).Length); imageToDraw = System.Drawing.Image.FromStream(oMemoryStream) g.DrawImage(imageToDraw, New Rectangle(xPosition, yPosition, 125, 36)) 'Select Case m_DataTable.DefaultView.Item(i).Item("PriorityText") ' Case "Major" ' g.DrawImage(m_ImageArray(0), New Point(Convert.ToInt32(cellBounds.X) - 5, Convert.ToInt32(cellBounds.Y))) ' Case "Medium" ' g.DrawImage(m_ImageArray(1), New Point(Convert.ToInt32(cellBounds.X) - 5, Convert.ToInt32(cellBounds.Y))) ' Case "Minor" ' g.DrawImage(m_ImageArray(2), New Point(Convert.ToInt32(cellBounds.X) - 5, Convert.ToInt32(cellBounds.Y))) 'End Select Catch ex As Exception End Try Else 'draw as short date format or regular string 'If m_DataTable.DefaultView.Item(i).Item(cs.MappingName).GetType() Is GetType(DateTime) Then ' g.DrawString(String.Format("{0:d}", m_DataTable.DefaultView.Item(i).Item(cs.MappingName)), m_DataGrid.Font, New SolidBrush(m_DataGrid.HeaderForeColor), cellBounds, cellFormat) 'Else cellBounds.Y = cellBounds.Y + 8 'cellBounds.Height = cellBounds.Height - 8 Try g.DrawString(CType(m_DataTable.DefaultView.Item(i).Item(cs.MappingName), String), m_DataGrid.Font, New SolidBrush(m_DataGrid.HeaderForeColor), cellBounds, cellFormat) 'End If Catch ex As Exception End Try cellBounds.Y = cellBounds.Y - 8 'cellBounds.Height = cellBounds.Height + 8 End If g.DrawLine(New Pen(m_DataGrid.GridLineColor, 1), xPosition, yPosition - 4, xPosition, yPosition + m_DataGrid.PreferredRowHeight + c_VerticalCellLeeway - 1) 'adjust the next X Pos xPosition += columnWidth End If Next 'set the rowcount (which is used for a possible next page) RowCount += 1 g.DrawLine(New Pen(m_DataGrid.GridLineColor, 1), m_PageWidthMinusMargins + c_LeftMargin - 1, yPosition - 4, m_PageWidthMinusMargins + c_LeftMargin - 1, yPosition + m_DataGrid.PreferredRowHeight + c_VerticalCellLeeway - 1) 'finished with this row, draw a nice line g.DrawLine(New Pen(m_DataGrid.GridLineColor, 1), c_LeftMargin + 12, yPosition + m_DataGrid.PreferredRowHeight + c_VerticalCellLeeway - 2, m_PageWidthMinusMargins + c_LeftMargin, yPosition + m_DataGrid.PreferredRowHeight + c_VerticalCellLeeway - 2) 'adjust the next Y Pos 'yPosition += m_DataGrid.HeaderFont.SizeInPoints + c_VerticalCellLeeway + 3 yPosition += m_DataGrid.PreferredRowHeight + c_VerticalCellLeeway + 3 'if at end of page exit out for next page If yPosition * PageNumber > PageNumber * (m_PageHeight - (c_BottomMargin + c_TopMargin)) Then Return True End If Next Return False End Function Private Function GetDataGridWidth() As Integer Try Dim cs As DataGridColumnStyle Dim dgWidth As Integer = 0 For Each cs In m_DataGrid.TableStyles(0).GridColumnStyles If cs.Width <> 0 Then dgWidth = dgWidth + cs.Width End If Next Return dgWidth Catch ex As Exception Throw ex End Try End Function End Class |
| webasp.net |