2016-10-13 4 views
1

저는 vb.net에서 새로운 인쇄를하고 있습니다. 인쇄하려면 DataGridView을 입력하십시오. 코드를 온라인으로 검색했으며 MSDN에서이 소스를 찾았습니다. 오른쪽에서 왼쪽으로 DataGridView을 인쇄하려면 어떻게해야합니까? 덕분에 .DataGridView를 오른쪽에서 왼쪽으로 인쇄합니다.

Public Class Form1 

    ''' <summary> 
    ''' structire to hold printed page details 
    ''' </summary> 
    ''' <remarks></remarks> 
    Private Structure pageDetails 
     Dim columns As Integer 
     Dim rows As Integer 
     Dim startCol As Integer 
     Dim startRow As Integer 
    End Structure 
    ''' <summary> 
    ''' dictionary to hold printed page details, with index key 
    ''' </summary> 
    ''' <remarks></remarks> 
    Private pages As Dictionary(Of Integer, pageDetails) 

    Dim maxPagesWide As Integer 
    Dim maxPagesTall As Integer 

    ''' <summary> 
    ''' this just loads some text values into the dgv 
    ''' </summary> 
    ''' <param name="sender"></param> 
    ''' <param name="e"></param> 
    ''' <remarks></remarks> 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
     DataGridView1.RowHeadersWidth = CInt(DataGridView1.RowHeadersWidth * 1.35) 
     For r As Integer = 1 To 100 
      Dim y As Integer = r 
      Dim fmt As String = "R{0}C{1}" 
      DataGridView1.Rows.Add() 
      DataGridView1.Rows(r - 1).SetValues(Enumerable.Range(1, 10).Select(Function(x) String.Format(fmt, y, x)).ToArray) 
      DataGridView1.Rows(r - 1).HeaderCell.Value = r.ToString 
     Next 
    End Sub 

    ''' <summary> 
    ''' shows a PrintPreviewDialog 
    ''' </summary> 
    ''' <param name="sender"></param> 
    ''' <param name="e"></param> 
    ''' <remarks></remarks> 
    Private Sub btnPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPreview.Click 
     Dim ppd As New PrintPreviewDialog 
     ppd.Document = PrintDocument1 
     ppd.WindowState = FormWindowState.Maximized 
     ppd.ShowDialog() 
    End Sub 

    ''' <summary> 
    ''' starts print job 
    ''' </summary> 
    ''' <param name="sender"></param> 
    ''' <param name="e"></param> 
    ''' <remarks></remarks> 
    Private Sub btnPrint_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPrint.Click 
     PrintDocument1.Print() 
    End Sub 

    ''' <summary> 
    ''' the majority of this Sub is calculating printed page ranges 
    ''' </summary> 
    ''' <param name="sender"></param> 
    ''' <param name="e"></param> 
    ''' <remarks></remarks> 
    Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint 
     ''this removes the printed page margins 
     PrintDocument1.OriginAtMargins = True 
     PrintDocument1.DefaultPageSettings.Margins = New Drawing.Printing.Margins(0, 0, 0, 0) 

     pages = New Dictionary(Of Integer, pageDetails) 

     Dim maxWidth As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width) - 40 
     Dim maxHeight As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Height) - 40 + Label1.Height 

     Dim pageCounter As Integer = 0 
     pages.Add(pageCounter, New pageDetails) 

     Dim columnCounter As Integer = 0 

     Dim columnSum As Integer = DataGridView1.RowHeadersWidth 

     For c As Integer = 0 To DataGridView1.Columns.Count - 1 
      If columnSum + DataGridView1.Columns(c).Width < maxWidth Then 
       columnSum += DataGridView1.Columns(c).Width 
       columnCounter += 1 
      Else 
       pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol} 
       columnSum = DataGridView1.RowHeadersWidth + DataGridView1.Columns(c).Width 
       columnCounter = 1 
       pageCounter += 1 
       pages.Add(pageCounter, New pageDetails With {.startCol = c}) 
      End If 
      If c = DataGridView1.Columns.Count - 1 Then 
       If pages(pageCounter).columns = 0 Then 
        pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol} 
       End If 
      End If 
     Next 

     maxPagesWide = pages.Keys.Max + 1 

     pageCounter = 0 

     Dim rowCounter As Integer = 0 

     Dim rowSum As Integer = DataGridView1.ColumnHeadersHeight 

     For r As Integer = 0 To DataGridView1.Rows.Count - 2 
      If rowSum + DataGridView1.Rows(r).Height < maxHeight Then 
       rowSum += DataGridView1.Rows(r).Height 
       rowCounter += 1 
      Else 
       pages(pageCounter) = New pageDetails With {.columns = pages(pageCounter).columns, .rows = rowCounter, .startCol = pages(pageCounter).startCol, .startRow = pages(pageCounter).startRow} 
       For x As Integer = 1 To maxPagesWide - 1 
        pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter).startRow} 
       Next 

       pageCounter += maxPagesWide 
       For x As Integer = 0 To maxPagesWide - 1 
        pages.Add(pageCounter + x, New pageDetails With {.columns = pages(x).columns, .rows = 0, .startCol = pages(x).startCol, .startRow = r}) 
       Next 

       rowSum = DataGridView1.ColumnHeadersHeight + DataGridView1.Rows(r).Height 
       rowCounter = 1 
      End If 
      If r = DataGridView1.Rows.Count - 2 Then 
       For x As Integer = 0 To maxPagesWide - 1 
        If pages(pageCounter + x).rows = 0 Then 
         pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter + x).startRow} 
        End If 
       Next 
      End If 
     Next 

     maxPagesTall = pages.Count \ maxPagesWide 

    End Sub 

    ''' <summary> 
    ''' this is the actual printing routine. 
    ''' using the pagedetails i calculated earlier, it prints a title, 
    ''' + as much of the datagridview as will fit on 1 page, then moves to the next page. 
    ''' this is setup to be dynamic. try resizing the dgv columns or rows 
    ''' </summary> 
    ''' <param name="sender"></param> 
    ''' <param name="e"></param> 
    ''' <remarks></remarks> 
    Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage 
     Dim rect As New Rectangle(20, 20, CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width), Label1.Height) 
     Dim sf As New StringFormat 
     sf.Alignment = StringAlignment.Center 
     sf.LineAlignment = StringAlignment.Center 

     e.Graphics.DrawString(Label1.Text, Label1.Font, Brushes.Black, rect, sf) 

     sf.Alignment = StringAlignment.Near 

     Dim startX As Integer = 50 
     Dim startY As Integer = rect.Bottom 

     Static startPage As Integer = 0 

     For p As Integer = startPage To pages.Count - 1 
      Dim cell As New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.ColumnHeadersHeight) 
      e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell) 
      e.Graphics.DrawRectangle(Pens.Black, cell) 

      startY += DataGridView1.ColumnHeadersHeight 

      For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1 
       cell = New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.Rows(r).Height) 
       e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell) 
       e.Graphics.DrawRectangle(Pens.Black, cell) 
       e.Graphics.DrawString(DataGridView1.Rows(r).HeaderCell.Value.ToString, DataGridView1.Font, Brushes.Black, cell, sf) 
       startY += DataGridView1.Rows(r).Height 
      Next 

      startX += cell.Width 
      startY = rect.Bottom 

      For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1 
       cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.ColumnHeadersHeight) 
       e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell) 
       e.Graphics.DrawRectangle(Pens.Black, cell) 
       e.Graphics.DrawString(DataGridView1.Columns(c).HeaderCell.Value.ToString, DataGridView1.Font, Brushes.Black, cell, sf) 
       startX += DataGridView1.Columns(c).Width 
      Next 

      startY = rect.Bottom + DataGridView1.ColumnHeadersHeight 

      For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1 
       startX = 50 + DataGridView1.RowHeadersWidth 
       For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1 
        cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.Rows(r).Height) 
        e.Graphics.DrawRectangle(Pens.Black, cell) 
        e.Graphics.DrawString(DataGridView1(c, r).Value.ToString, DataGridView1.Font, Brushes.Black, cell, sf) 
        startX += DataGridView1.Columns(c).Width 
       Next 
       startY += DataGridView1.Rows(r).Height 
      Next 

      If p <> pages.Count - 1 Then 
       startPage = p + 1 
       e.HasMorePages = True 
       Return 
      Else 
       startPage = 0 
      End If 

     Next 

    End Sub 

End Class 
+0

단순히'RDLC' 보고서를 사용하여'DataGridView'를 인쇄 할 수 있는데 왜 GDI + 코드를 사용하여'DataGridView'를 인쇄하려고합니까? –

+0

어떤 이유로 든 rdlc 보고서를 사용하고 싶지 않거나 사용하지 않으려는 경우 html 코드가 포함 된 런타임 t4 템플릿을 사용하여 GDI +를 사용하는 것보다 좀 더 친숙한/유연한 방식으로 데이터 모델을 인쇄 할 수 있습니다. [이 예제] (http://stackoverflow.com/a/39713817/3110834)를 살펴보십시오. –

+0

RDLC 보고서에 대한 생각이 없기 때문에 불가능하고 쉽게 ?? 그리고 클라이언트 컴퓨터에 RDLC 보고서를 설치해야합니까? –

답변

1

당신은 당신은 StringFormat 데 사용해야

  1. 게시 된 코드에 약간의 변경이 필요합니다, 그 인쇄 RTL을 만들려면 :

    내가 Printing DataGridView Example에서 얻을 소스 코드입니다 StringFormatFlags.DirectionRightToLeft 형식으로 glag.
  2. 왼쪽에서 오른쪽으로 직사각형을 그리는 대신 오른쪽에서 왼쪽으로 그리기를 지원하는 좌표를 수정해야합니다.

첫 번째 문제를 해결하기 위해서는 문자열 형식으로 언급 플래그를 추가 충분 :

sf.FormatFlags = sf.FormatFlags Or StringFormatFlags.DirectionRightToLeft 

는 두 번째 문제를 해결하기 위해, 당신은 그런 방법을 만들어야합니다

Public Function GetRTLCoordinates(container As Rectangle, drawRectangle As Rectangle) _ 
    As Rectangle 
    Return New Rectangle(container.Width - drawRectangle.Width - drawRectangle.X, _ 
     drawRectangle.Y, drawRectangle.Width, drawRectangle.Height) 
End Function 

을 그런 다음 코드에서 cell이라는 사각형을 계산 한 각 코드 줄 뒤에 다음 코드 줄을 추가하십시오.

cell = GetRTLCoordinates(rect, cell) 
,

코드 여기

PrintDocument1_PrintPage 방법의 변경된 버전이다. 위에 언급 된 GetRTLCoordinates 방법을 복사하는 것을 잊지 마십시오.

Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage 
    Dim rect As New Rectangle(20, 20, CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width), Label1.Height) 
    Dim sf As New StringFormat 
    sf.Alignment = StringAlignment.Center 
    sf.LineAlignment = StringAlignment.Center 
    sf.FormatFlags = sf.FormatFlags Or StringFormatFlags.DirectionRightToLeft 

    e.Graphics.DrawString(Label1.Text, Label1.Font, Brushes.Black, rect, sf) 

    sf.Alignment = StringAlignment.Near 

    Dim startX As Integer = 50 
    Dim startY As Integer = rect.Bottom 

    Static startPage As Integer = 0 

    For p As Integer = startPage To pages.Count - 1 
     Dim cell As New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.ColumnHeadersHeight) 
     cell = GetRTLCoordinates(rect, cell) 
     e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell) 
     e.Graphics.DrawRectangle(Pens.Black, cell) 

     startY += DataGridView1.ColumnHeadersHeight 

     For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1 
      cell = New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.Rows(r).Height) 
      cell = GetRTLCoordinates(rect, cell) 
      e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell) 
      e.Graphics.DrawRectangle(Pens.Black, cell) 
      e.Graphics.DrawString(DataGridView1.Rows(r).HeaderCell.Value.ToString, DataGridView1.Font, Brushes.Black, cell, sf) 
      startY += DataGridView1.Rows(r).Height 
     Next 

     startX += cell.Width 
     startY = rect.Bottom 

     For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1 
      cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.ColumnHeadersHeight) 
      cell = GetRTLCoordinates(rect, cell) 
      e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell) 
      e.Graphics.DrawRectangle(Pens.Black, cell) 
      e.Graphics.DrawString(DataGridView1.Columns(c).HeaderCell.Value.ToString, DataGridView1.Font, Brushes.Black, cell, sf) 
      startX += DataGridView1.Columns(c).Width 
     Next 

     startY = rect.Bottom + DataGridView1.ColumnHeadersHeight 

     For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1 
      startX = 50 + DataGridView1.RowHeadersWidth 
      For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1 
       cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.Rows(r).Height) 
       cell = GetRTLCoordinates(rect, cell) 
       e.Graphics.DrawRectangle(Pens.Black, cell) 
       e.Graphics.DrawString(DataGridView1(c, r).Value.ToString, DataGridView1.Font, Brushes.Black, cell, sf) 
       startX += DataGridView1.Columns(c).Width 
      Next 
      startY += DataGridView1.Rows(r).Height 
     Next 

     If p <> pages.Count - 1 Then 
      startPage = p + 1 
      e.HasMorePages = True 
      Return 
     Else 
      startPage = 0 
     End If 

    Next 

End Sub 
+0

이것은 완벽합니다. 보고서 뷰어에 대해서도 읽었습니다. 흥미 롭습니다. 및 정말 고마워, 너 최고야 :) –

+0

당신은 환영합니다 :) - 잘 했어, 나는 MSDN에서 대중적인 예라고 생각하기 때문에 고칠 수 있습니다. –

+0

안녕하세요, 다시 보고서 뷰어에 대해 묻고 싶습니다. 새 보고서를 만들려고합니다. 이미 보고서 뷰어 dll 파일을 추가했지만 보고서를 추가하려고하면 범주로보고를 찾을 수 없습니다. [ 그림 1] (http://www8.0zz0.com/2016/10/13/20/889069519.png) 그림과 같이되어야합니다. [그림 2] (http://www8.0zz0.com/2016/ 10/13/20/597237159.png) 새로운 qustion을 물어 보시겠습니까 ?? –

관련 문제