如何用printdocument在水平线上打印datagridview数据?
How to print datagridview data in horizontal line with printdocument?
我在 SqlServer 数据库中有一个查询,该查询的结果在 Datagridview 中播放,结果可以包含 0 到 100 个数据,如果您怀疑甚至更多。
我试图水平打印 Datagridview 的“标识”列,但没有成功。我在几个地方研究过,也没有。
screenshot of form with DataGridView
遵循表单代码:
Imports System.ComponentModel
Imports System.Data.SqlClient
Imports System.Drawing.Printing
Public Class frm_relatorio_entregas
' Variables used in the module
Dim RelatorioTitulo As String ' Report title
Dim paginaatual As Integer ' Page number being printed
Dim LinhaAtual As Integer ' Current line number being printed
Dim LinhasporPagina As Integer ' Number of lines per page
Dim PosicaoDaLinha As Single ' Position of the line being printed
Dim registro As Integer ' Record being printed
Private Sub Imprimir()
RelatorioTitulo = "Delivery Report"
Dim doc As PrintDocument = New PrintDocument
AddHandler doc.PrintPage, New Printing.PrintPageEventHandler(AddressOf Me.pdRelatorios_Printpage)
AddHandler doc.BeginPrint, New Printing.PrintEventHandler(AddressOf Me.Begin_Print)
Dim dialogo As PrintDialog = New PrintDialog
'dialogo.Document = doc
' If (dialogo.ShowDialog = DialogResult.OK) Then
Dim preview As PrintPreviewDialog = New PrintPreviewDialog()
preview.Document = doc
preview.WindowState = FormWindowState.Maximized
preview.PrintPreviewControl.Zoom = 1.0
preview.ShowDialog()
'End If
End Sub
Private Sub Begin_Print(ByVal sender As Object, ByVal e As Printing.PrintEventArgs)
' Assigning values to variables at the start of printing
LinhaAtual = 0
paginaatual = 1
PosicaoDaLinha = 0
registro = 0
End Sub
Private Sub pdRelatorios_Printpage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
' Margin variables (e.MarginBounds obtain the rectangular area that represents the part of the page within the margins.)
Dim MargemEsquerda As Single = e.MarginBounds.Left
Dim MargemDireita As Single = e.MarginBounds.Right
Dim MargemSuperior As Single = e.MarginBounds.Top
Dim MargemInferios As Single = e.MarginBounds.Bottom
'Pen class defines an object used to define lines and curves
Dim CanetaDaImpressora As Pen = New Pen(Color.Black, 1)
'Variables of the fonts used (the font class defines a specific format for text, including font face, size and style attributes.
Dim FonteNegrito As Font
Dim FonteTitulo As Font
Dim FonteSubTitulo As Font
Dim FonteRodape As Font
Dim FonteNormal As Font
Dim font1 As Font
'Define effects on fonts used
FonteNegrito = New Font("Arial", 9, FontStyle.Bold)
FonteTitulo = New Font("Arial", 13, FontStyle.Bold)
FonteSubTitulo = New Font("Arial", 9, FontStyle.Bold)
FonteRodape = New Font("Arial", 8)
FonteNormal = New Font("Calibri", 9)
font1 = New Font("Segoe UI", 8, FontStyle.Bold)
'Print the title of the report
e.Graphics.DrawString(RelatorioTitulo, FonteTitulo, Brushes.Black, MargemEsquerda + 200, 30, New StringFormat)
If DateTimePicker1.Value = DateTimePicker1.Value Then
e.Graphics.DrawString(DateTimePicker1.Value, FonteSubTitulo, Brushes.Black, MargemEsquerda + 900, 30, New StringFormat)
Else
e.Graphics.DrawString(DateTimePicker1.Value & " - " & DateTimePicker1.Value, FonteSubTitulo, Brushes.Black, MargemEsquerda + 900, 30, New StringFormat)
End If
'Define the number of lines per page
LinhasporPagina = CInt(e.MarginBounds.Height / New Font("Calibri", 18).GetHeight(e.Graphics) - 2)
While (LinhaAtual <= LinhasporPagina AndAlso registro <= DataGridView1.Rows.Count - 1)
PosicaoDaLinha = MargemSuperior + (LinhaAtual * New Font("Calibri", 18).GetHeight(e.Graphics) + 30)
e.Graphics.DrawString(DataGridView1.Rows(registro).Cells(0).Value.ToString, New Font("Calibri", 8, FontStyle.Bold), Brushes.Black, 30, PosicaoDaLinha, New StringFormat())
'Increment record
registro += 1
'increment line
LinhaAtual += 1
End While
'baseboard
e.Graphics.DrawLine(CanetaDaImpressora, 20, MargemInferios + 15, 1150, MargemInferios + 15)
e.Graphics.DrawString(System.DateTime.Now.ToString(), FonteRodape, Brushes.Black, 30, MargemInferios + 15, New StringFormat())
e.Graphics.DrawString("Página : " & paginaatual, FonteRodape, Brushes.Black, 1070, MargemInferios + 15, New StringFormat)
'Increase the page number
paginaatual += 1
'Here check if you are going to open a new page
If (LinhaAtual > LinhasporPagina) Then
' When you open a new page, you have to reset LlinhaAtual
e.HasMorePages = True
LinhaAtual = 0
Else
e.HasMorePages = False
End If
End Sub
Private Sub frm_relatorio_entregas_Load(sender As Object, e As EventArgs) Handles MyBase.Load
txtcod.Clear()
txtrazao.Clear()
TextBox1.Clear()
TextBox2.Clear()
TextBox3.Clear()
DateTimePicker1.ResetText()
DateTimePicker2.ResetText()
ComboBox1.SelectedIndex = 0
txtcod.Select()
End Sub
Private Sub txtcod_KeyUp(sender As Object, e As KeyEventArgs) Handles txtcod.KeyUp
If e.KeyCode = Keys.F2 Then
frm_consulta_cliente_cadastro.ShowDialog()
End If
End Sub
Private Sub consulta()
DataGridView1.Rows.Clear()
Cursor.Current = Cursors.WaitCursor
Dim consultando As New frm_aguarde_consultando
consultando.Show()
' Set cursor as hourglass
Application.DoEvents()
Dim ano, mes, dia As Integer
Dim var1data, var2data As Date
Dim dinicio, dfim As String
var1data = DateTimePicker1.Value '.ToString.Substring(0, 10)
dia = var1data.Day
mes = var1data.Month
ano = var1data.Year
dinicio = ano & "-" & mes & "-" & dia
var2data = DateTimePicker2.Value
dia = var2data.Day
mes = var2data.Month
ano = var2data.Year
dfim = ano & "-" & mes & "-" & dia
Using sqlcoon As SqlConnection = GetConnectionsql()
Dim READER As SqlDataReader
Try
sqlcoon.Open()
Dim Query As String
Query = "select MOV_IDENTIFICACAO,MOV_PROTOCOLO,MOV_DATADOC,MOV_SITUACAO,MOV_DATAENTREGA,MOV_HORAENTREGA,MOV_SITEND_CODIGO
from movimento where MOV_DATADOC = '" & dinicio & "'
AND MOV_CLI_CODIGO = '" & txtcod.Text & "' AND MOV_SITUACAO = '" & "E" & "'
AND CAST(MOV_DATAENTREGA AS DATE) = '" & dfim & "' "
Dim COMMAND As SqlCommand = New SqlCommand(Query, sqlcoon)
READER = COMMAND.ExecuteReader
While READER.Read
Dim MOV_IDENTIFICACAO = READER("MOV_IDENTIFICACAO")
Dim MOV_DATADOC = READER("MOV_DATADOC")
Dim MOV_DATAENTREGA = READER("MOV_DATAENTREGA")
Dim MOV_PROTOCOLO = READER("MOV_PROTOCOLO")
Dim MOV_SITUACAO = READER("MOV_SITUACAO")
Dim MOV_SITEND_CODIGO = READER("MOV_SITEND_CODIGO")
DataGridView1.Rows.Add(MOV_IDENTIFICACAO, MOV_PROTOCOLO, MOV_DATADOC, MOV_SITUACAO, MOV_DATAENTREGA, MOV_SITEND_CODIGO)
End While
READER.Close()
sqlcoon.Close()
''--------------'''''''''
Label9.Text = DataGridView1.Rows.Count
For Each linha In DataGridView1.Rows
Dim altura As Integer = 17
linha.height = altura
Next
If DataGridView1.Rows.Count >= 0 Then
' Set cursor as default arrow
Cursor.Current = Cursors.Default
' Hide the please wait form
consultando.Hide()
End If
Catch ex As SqlException
MessageBox.Show(ex.Message)
Finally
' sqlcoon.Dispose()
End Try
sqlcoon.Open()
Try
For r As Integer = 0 To DataGridView1.Rows.Count - 1
Dim COMMAND3 As SqlCommand
Dim READER3 As SqlDataReader
Dim Query_3 As String
Query_3 = "select IMOV_CODIGORECBTO from imovimento where IMOV_MOV_IDENTIFICACAO ='" & DataGridView1.Rows(r).Cells(0).Value.ToString & "'"
COMMAND3 = New SqlCommand(Query_3, sqlcoon)
READER3 = COMMAND3.ExecuteReader
While READER3.Read
Dim IMOV_CODIGORECBTO = READER3("IMOV_CODIGORECBTO")
'DataGridView1.Columns(6).HeaderCell.Value = "ID"
DataGridView1.Rows(r).Cells(6).Value = IMOV_CODIGORECBTO
End While
READER3.Close()
Next
DataGridView1.Sort(DataGridView1.Columns(6), ListSortDirection.Ascending)
sqlcoon.Close()
Catch ex As SqlException
MsgBox(ex.Message)
End Try
End Using
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
consulta()
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Imprimir()
End Sub
End Class
screenshot of what is currently being printed
screenshot of I would like the result to be:
有没有人有任何想法、工具或方法来帮助我?谢谢
另一种方法是:
- 仅获取所需的列值。
- 使用分隔符(例如制表符)连接 #1 中的值。
- 对 #2 中的值使用 Graphics.DrawString 方法 (documentation)。
需要注意一些事项:
- 您需要测量 #3 中的字符串,看它是否超出打印文档的范围
- 如果是这样,那么您将需要打印多页,从中断的地方继续打印。
更新
根据 OP 的要求,这里有一个例子。请记住,它没有考虑上面列出的注意事项。这将需要一些调试工作来解决这些问题:
Private Sub pdRelatorios_PrintPage(sender As Object, e As PrintPageEventArgs) Handles pdRelatorios.PrintPage
Dim title = "Relatorio de Entregas"
Dim titleFont = New Font(Font.FontFamily, Convert.ToSingle(Font.Size * 1.5), FontStyle.Bold)
Dim titlePosition = New PointF(Convert.ToSingle(e.MarginBounds.X * 2 - e.PageBounds.Width / 2), e.MarginBounds.Y)
Dim titleSize = e.Graphics.MeasureString(title, titleFont)
e.Graphics.DrawString(title, titleFont, SystemBrushes.ControlText, titlePosition)
Dim cellValues = DataGridView1.Rows.Cast(Of DataGridViewRow).Select(Function(row) row.Cells(0)?.Value?.ToString())
Dim joinedCellValues = String.Join(Constants.vbTab, cellValues)
Dim bodyBounds = New RectangleF(e.MarginBounds.X, Convert.ToSingle(titleSize.Height + e.MarginBounds.Y), e.PageBounds.Width - e.MarginBounds.X * 2, e.PageBounds.Height - e.MarginBounds.Y * 2)
e.Graphics.DrawString(joinedCellValues, Font, SystemBrushes.ControlText, bodyBounds)
End Sub
我在 SqlServer 数据库中有一个查询,该查询的结果在 Datagridview 中播放,结果可以包含 0 到 100 个数据,如果您怀疑甚至更多。
我试图水平打印 Datagridview 的“标识”列,但没有成功。我在几个地方研究过,也没有。
screenshot of form with DataGridView
遵循表单代码:
Imports System.ComponentModel
Imports System.Data.SqlClient
Imports System.Drawing.Printing
Public Class frm_relatorio_entregas
' Variables used in the module
Dim RelatorioTitulo As String ' Report title
Dim paginaatual As Integer ' Page number being printed
Dim LinhaAtual As Integer ' Current line number being printed
Dim LinhasporPagina As Integer ' Number of lines per page
Dim PosicaoDaLinha As Single ' Position of the line being printed
Dim registro As Integer ' Record being printed
Private Sub Imprimir()
RelatorioTitulo = "Delivery Report"
Dim doc As PrintDocument = New PrintDocument
AddHandler doc.PrintPage, New Printing.PrintPageEventHandler(AddressOf Me.pdRelatorios_Printpage)
AddHandler doc.BeginPrint, New Printing.PrintEventHandler(AddressOf Me.Begin_Print)
Dim dialogo As PrintDialog = New PrintDialog
'dialogo.Document = doc
' If (dialogo.ShowDialog = DialogResult.OK) Then
Dim preview As PrintPreviewDialog = New PrintPreviewDialog()
preview.Document = doc
preview.WindowState = FormWindowState.Maximized
preview.PrintPreviewControl.Zoom = 1.0
preview.ShowDialog()
'End If
End Sub
Private Sub Begin_Print(ByVal sender As Object, ByVal e As Printing.PrintEventArgs)
' Assigning values to variables at the start of printing
LinhaAtual = 0
paginaatual = 1
PosicaoDaLinha = 0
registro = 0
End Sub
Private Sub pdRelatorios_Printpage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
' Margin variables (e.MarginBounds obtain the rectangular area that represents the part of the page within the margins.)
Dim MargemEsquerda As Single = e.MarginBounds.Left
Dim MargemDireita As Single = e.MarginBounds.Right
Dim MargemSuperior As Single = e.MarginBounds.Top
Dim MargemInferios As Single = e.MarginBounds.Bottom
'Pen class defines an object used to define lines and curves
Dim CanetaDaImpressora As Pen = New Pen(Color.Black, 1)
'Variables of the fonts used (the font class defines a specific format for text, including font face, size and style attributes.
Dim FonteNegrito As Font
Dim FonteTitulo As Font
Dim FonteSubTitulo As Font
Dim FonteRodape As Font
Dim FonteNormal As Font
Dim font1 As Font
'Define effects on fonts used
FonteNegrito = New Font("Arial", 9, FontStyle.Bold)
FonteTitulo = New Font("Arial", 13, FontStyle.Bold)
FonteSubTitulo = New Font("Arial", 9, FontStyle.Bold)
FonteRodape = New Font("Arial", 8)
FonteNormal = New Font("Calibri", 9)
font1 = New Font("Segoe UI", 8, FontStyle.Bold)
'Print the title of the report
e.Graphics.DrawString(RelatorioTitulo, FonteTitulo, Brushes.Black, MargemEsquerda + 200, 30, New StringFormat)
If DateTimePicker1.Value = DateTimePicker1.Value Then
e.Graphics.DrawString(DateTimePicker1.Value, FonteSubTitulo, Brushes.Black, MargemEsquerda + 900, 30, New StringFormat)
Else
e.Graphics.DrawString(DateTimePicker1.Value & " - " & DateTimePicker1.Value, FonteSubTitulo, Brushes.Black, MargemEsquerda + 900, 30, New StringFormat)
End If
'Define the number of lines per page
LinhasporPagina = CInt(e.MarginBounds.Height / New Font("Calibri", 18).GetHeight(e.Graphics) - 2)
While (LinhaAtual <= LinhasporPagina AndAlso registro <= DataGridView1.Rows.Count - 1)
PosicaoDaLinha = MargemSuperior + (LinhaAtual * New Font("Calibri", 18).GetHeight(e.Graphics) + 30)
e.Graphics.DrawString(DataGridView1.Rows(registro).Cells(0).Value.ToString, New Font("Calibri", 8, FontStyle.Bold), Brushes.Black, 30, PosicaoDaLinha, New StringFormat())
'Increment record
registro += 1
'increment line
LinhaAtual += 1
End While
'baseboard
e.Graphics.DrawLine(CanetaDaImpressora, 20, MargemInferios + 15, 1150, MargemInferios + 15)
e.Graphics.DrawString(System.DateTime.Now.ToString(), FonteRodape, Brushes.Black, 30, MargemInferios + 15, New StringFormat())
e.Graphics.DrawString("Página : " & paginaatual, FonteRodape, Brushes.Black, 1070, MargemInferios + 15, New StringFormat)
'Increase the page number
paginaatual += 1
'Here check if you are going to open a new page
If (LinhaAtual > LinhasporPagina) Then
' When you open a new page, you have to reset LlinhaAtual
e.HasMorePages = True
LinhaAtual = 0
Else
e.HasMorePages = False
End If
End Sub
Private Sub frm_relatorio_entregas_Load(sender As Object, e As EventArgs) Handles MyBase.Load
txtcod.Clear()
txtrazao.Clear()
TextBox1.Clear()
TextBox2.Clear()
TextBox3.Clear()
DateTimePicker1.ResetText()
DateTimePicker2.ResetText()
ComboBox1.SelectedIndex = 0
txtcod.Select()
End Sub
Private Sub txtcod_KeyUp(sender As Object, e As KeyEventArgs) Handles txtcod.KeyUp
If e.KeyCode = Keys.F2 Then
frm_consulta_cliente_cadastro.ShowDialog()
End If
End Sub
Private Sub consulta()
DataGridView1.Rows.Clear()
Cursor.Current = Cursors.WaitCursor
Dim consultando As New frm_aguarde_consultando
consultando.Show()
' Set cursor as hourglass
Application.DoEvents()
Dim ano, mes, dia As Integer
Dim var1data, var2data As Date
Dim dinicio, dfim As String
var1data = DateTimePicker1.Value '.ToString.Substring(0, 10)
dia = var1data.Day
mes = var1data.Month
ano = var1data.Year
dinicio = ano & "-" & mes & "-" & dia
var2data = DateTimePicker2.Value
dia = var2data.Day
mes = var2data.Month
ano = var2data.Year
dfim = ano & "-" & mes & "-" & dia
Using sqlcoon As SqlConnection = GetConnectionsql()
Dim READER As SqlDataReader
Try
sqlcoon.Open()
Dim Query As String
Query = "select MOV_IDENTIFICACAO,MOV_PROTOCOLO,MOV_DATADOC,MOV_SITUACAO,MOV_DATAENTREGA,MOV_HORAENTREGA,MOV_SITEND_CODIGO
from movimento where MOV_DATADOC = '" & dinicio & "'
AND MOV_CLI_CODIGO = '" & txtcod.Text & "' AND MOV_SITUACAO = '" & "E" & "'
AND CAST(MOV_DATAENTREGA AS DATE) = '" & dfim & "' "
Dim COMMAND As SqlCommand = New SqlCommand(Query, sqlcoon)
READER = COMMAND.ExecuteReader
While READER.Read
Dim MOV_IDENTIFICACAO = READER("MOV_IDENTIFICACAO")
Dim MOV_DATADOC = READER("MOV_DATADOC")
Dim MOV_DATAENTREGA = READER("MOV_DATAENTREGA")
Dim MOV_PROTOCOLO = READER("MOV_PROTOCOLO")
Dim MOV_SITUACAO = READER("MOV_SITUACAO")
Dim MOV_SITEND_CODIGO = READER("MOV_SITEND_CODIGO")
DataGridView1.Rows.Add(MOV_IDENTIFICACAO, MOV_PROTOCOLO, MOV_DATADOC, MOV_SITUACAO, MOV_DATAENTREGA, MOV_SITEND_CODIGO)
End While
READER.Close()
sqlcoon.Close()
''--------------'''''''''
Label9.Text = DataGridView1.Rows.Count
For Each linha In DataGridView1.Rows
Dim altura As Integer = 17
linha.height = altura
Next
If DataGridView1.Rows.Count >= 0 Then
' Set cursor as default arrow
Cursor.Current = Cursors.Default
' Hide the please wait form
consultando.Hide()
End If
Catch ex As SqlException
MessageBox.Show(ex.Message)
Finally
' sqlcoon.Dispose()
End Try
sqlcoon.Open()
Try
For r As Integer = 0 To DataGridView1.Rows.Count - 1
Dim COMMAND3 As SqlCommand
Dim READER3 As SqlDataReader
Dim Query_3 As String
Query_3 = "select IMOV_CODIGORECBTO from imovimento where IMOV_MOV_IDENTIFICACAO ='" & DataGridView1.Rows(r).Cells(0).Value.ToString & "'"
COMMAND3 = New SqlCommand(Query_3, sqlcoon)
READER3 = COMMAND3.ExecuteReader
While READER3.Read
Dim IMOV_CODIGORECBTO = READER3("IMOV_CODIGORECBTO")
'DataGridView1.Columns(6).HeaderCell.Value = "ID"
DataGridView1.Rows(r).Cells(6).Value = IMOV_CODIGORECBTO
End While
READER3.Close()
Next
DataGridView1.Sort(DataGridView1.Columns(6), ListSortDirection.Ascending)
sqlcoon.Close()
Catch ex As SqlException
MsgBox(ex.Message)
End Try
End Using
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
consulta()
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Imprimir()
End Sub
End Class
screenshot of what is currently being printed
screenshot of I would like the result to be:
有没有人有任何想法、工具或方法来帮助我?谢谢
另一种方法是:
- 仅获取所需的列值。
- 使用分隔符(例如制表符)连接 #1 中的值。
- 对 #2 中的值使用 Graphics.DrawString 方法 (documentation)。
需要注意一些事项:
- 您需要测量 #3 中的字符串,看它是否超出打印文档的范围
- 如果是这样,那么您将需要打印多页,从中断的地方继续打印。
更新
根据 OP 的要求,这里有一个例子。请记住,它没有考虑上面列出的注意事项。这将需要一些调试工作来解决这些问题:
Private Sub pdRelatorios_PrintPage(sender As Object, e As PrintPageEventArgs) Handles pdRelatorios.PrintPage
Dim title = "Relatorio de Entregas"
Dim titleFont = New Font(Font.FontFamily, Convert.ToSingle(Font.Size * 1.5), FontStyle.Bold)
Dim titlePosition = New PointF(Convert.ToSingle(e.MarginBounds.X * 2 - e.PageBounds.Width / 2), e.MarginBounds.Y)
Dim titleSize = e.Graphics.MeasureString(title, titleFont)
e.Graphics.DrawString(title, titleFont, SystemBrushes.ControlText, titlePosition)
Dim cellValues = DataGridView1.Rows.Cast(Of DataGridViewRow).Select(Function(row) row.Cells(0)?.Value?.ToString())
Dim joinedCellValues = String.Join(Constants.vbTab, cellValues)
Dim bodyBounds = New RectangleF(e.MarginBounds.X, Convert.ToSingle(titleSize.Height + e.MarginBounds.Y), e.PageBounds.Width - e.MarginBounds.X * 2, e.PageBounds.Height - e.MarginBounds.Y * 2)
e.Graphics.DrawString(joinedCellValues, Font, SystemBrushes.ControlText, bodyBounds)
End Sub