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