티스토리 뷰

프로그래밍

비베 닷넷 인쇄하기

야라바 2015. 10. 23. 15:08


비주얼베이직 닷넷(이하 비베닷넷)에서 인쇄를 구현하는 것이 그리 쉽지만은 않은 작업입니다. 웹 페이지 처럼 화면에 HTML을 통해서 그림과 도표, 텍스트로 페이지를 출력하고 CSS를 이용해서 인쇄시점에 포함해야될 내용과 제외할 것을 지정해 놓으면 웹브라우저가 알아서 출력해 주는 것처럼 윈도우 폼에서도 자동으로 인쇄해 준다면 프로그래머는 편하겠지만 화면의 동작방식과 크기는 프린터의 동작 방식과 크기와 차이가 크기 때문에 인쇄용 양식과 내용을 별도로 구성해 주어야 합니다. 

다만 화면 출력에 사용하는 클래스나 함수를 그대로 프린터 출력에도 동일하게 사용할 수 있으며 시스템에서 제공하는 몇가지 컴포넌트와 클래스를 잘 활용하면 프린터의 종류와 관계없이 다양한 기종의 프린터에 동일한 페이지 내용을 간편하게 출력할 수 있습니다. 이런 인쇄 작업의 편리함을 위해서 보고서 제작 라이브러리를 사용하거나 PDF 출력을 통해 인쇄하는 사례도 있지만 본 포스팅에서는 비베닷넷에서 제공하는 컨트롤을 사용하는 방법을 다루겠습니다.


도구상자에는 위의 그림 같이 총 5가지의 인쇄 관련 컨트롤을 제공하고 있습니다. 각 컨트롤에 대한 간단한 설명은 아래와 같습니다.

  • PageSetupDialog : 마진(여백)과 인쇄 방향등 인쇄를 위한 페이지 설정을 하는 대화창 표시
  • PrintDialog : 프린터 종류, 매수, 시작-동료 페이지등의 선택을 위한 대화창 표시
  • PrintDocument : 실제 인쇄 관련 작업을 수행하는 메소드와 이벤트를 갖는 클래스
  • PrintPreviewControl : 사용자 화면에 인쇄 미리를 보기를 구현할 때 사용하는 컨트롤
  • PrintPreviewDialog : 인쇄 미리보기를 수행하는 대화창 표시


위의 그림에서 알 수 있듯이 PrintPreviewControl 외에는 윈도우 폼에 표시되지 않습니다. 하단 컨트롤 영역에서 개별 오브젝트를 선택할 수 있습니다. 인쇄 작업의 핵심 요소인 PrintDocument를 중심으로 다루겠습니다.


위의 그림은 PrintDocument의 주요 속성과 메소드로 주요한 항목에 대한 설명은 아래와 같습니다.


DefaultPageSettings 속성은 페이지 여백, 용지 방향등의 설정이 담긴 정보로 PageSetupDialog 대화창을 통해서 사용자의 설정을 받을 수 있습니다. 아래는 [페이지 설정] 버튼을 누르면 PageSetupDialog 대화창을 통해 페이지 설정을 받는 코드입니다.

        PageSetupDialog1.Document = PrintDocument1
        PageSetupDialog1.PageSettings = PrintDocument1.DefaultPageSettings
        PageSetupDialog1.PrinterSettings = PrintDocument1.PrinterSettings
        If PageSetupDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            PrintDocument1.DefaultPageSettings = PageSetupDialog1.PageSettings
            PrintDocument1.PrinterSettings = PageSetupDialog1.PrinterSettings
        End If


위의 그림은 페이지 설정 대화창입니다. 코드를 보면 PageSetupDialog 대화창을 호출하기 이전에 Document 속성에 PrintDocument 컨트롤의 오브젝트를 대입하고 PageSettings와 PrinterSettings 속성에 기존의 페이지 설정과 프린터 설정을 전달한 다음 ShowDialog 메소드를 대화창을 띄운것을 확인할 수 있습니다. 대화창에서 [확인]을 누르면 DialogResult.OK 를 리턴하는데 이 경우에만 PrintDocument 컨트롤의 페이지 설정과 프린터 설정을 업데이트 하고 있습니다.


DocumentName 속성은 인쇄 작업의 이름으로 활용하므로 적절하게 설정합니다. OriginAtMargins 속성은 실제 인쇄 시점에 사용하는 그래픽 오브젝트의 시작 위치가 여백을 감안한 것인지(True), 아니면 인쇄 가능 영역 전체의 좌상단인지(False)를 나타냅니다. PrintController 속성은 시스템에서 제공하는 인쇄 컨트롤러가 아닌 개발자 나름의 컨트롤러를 작성해 사용할 경우에 사용합니다. 


PrinterSettings 속성은 프린터 종류, 매수, 시작-동료 페이지등의 정보를 가지고 있는 것으로 PrintDialog 대화창을 통해서 프린터 선택을 비롯한 다양한 프린터 설정이 가능합니다. 일반적으로 프린터 설정 이후 바로 인쇄 작업을 수행합니다. 다음은 [인쇄] 버튼이 눌러 졌을 때 PrintDialog 대화창을 통해서 프린터 설정을 받고 사용자가 [확인] 버튼을 누르면 실제 인쇄를 시작하게 하는 코드입니다.

        PrintDialog1.Document = PrintDocument1
        PrintDialog1.PrinterSettings = PrintDocument1.PrinterSettings
        PrintDialog1.AllowSomePages = True
        If PrintDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            PrintDocument1.PrinterSettings = PrintDialog1.PrinterSettings
            PrintDocument1.Print()
        End If



위의 그림에서 페이지 범위를 설정할 수 있도록 되어 있는 것은 PrintDialog 대화창을 ShowDialog로 보여주기 직전에 PrintDialog의 AllowSomePages 속성을 True로 설정했기 때문입니다. PrintDialog 대화창을 띄우기 전에 기존의 프린터 설정값을 전달하고 사용자가 [인쇄] 버튼을 누르면 프린터 설정값을 다시 받아오고 Print() 메소드로 인쇄 시작을 지시하고 있습니다. Print() 메소드를 호출하면 실제 인쇄 작업은 PrintDocument의 아래와 같은 이벤트가 호출되는 방식으로 수행됩니다.



인쇄 작업의 시작은 BeginPrint 이벤트로 부터 시작합니다. 이 이벤트를 받으면 각 페이지별 인쇄를 위한 환경을 준비하면 되겠습니다. 각 페이지별 인쇄 시점에는 QueryPageSettings와 PrintPage 이벤트가 전달되는데 QueryPageSettings 이벤트가 먼저 도착하므로 이때 인쇄를 위한 데이터를 준비하고 PrintPage 이벤트에서 인쇄를 위한 출력작업을 하면 됩니다. 인쇄 작업이 모두 끝나면 최종적으로 EndPrint 이벤트를 전달합니다. 아래의 코드는 PrintPage 이벤트 시점에 인쇄를 위한 실제 출력 작업 예제입니다.

    Private Sub PrintDocument1_PrintPage(sender As System.Object, e As System.Drawing.Printing.PrintPageEventArgs) _
             Handles PrintDocument1.PrintPage
        e.Graphics.DrawString("인쇄 테스트 입니다. Good test!", _
                              New Font("맑은 고딕", 32, FontStyle.Bold), Brushes.Black, 10, 10)
        e.Graphics.DrawString("1/1 페이지", _
                              New Font("맑은 고딕", 10, FontStyle.Bold), Brushes.Black, 600, 800)
        e.Graphics.FillEllipse(Brushes.Red, 300, 300, 300, 50)
        e.HasMorePages = False
    End Sub

이벤트의 파라미터로 전달되는 e.Graphics를 통해서 텍스트와 다양한 그래픽 오브젝트를 드로잉 하면 자연스럽게 프린터로 인쇄됩니다. 실제로 컴퓨터와 프린터간에 어떤 정보가 주고 받는지를 개발자가 알 필요는 없습니다. 프린터 드라이버가 알아서 해주기 때문입니다. e.HasMorePages에 False로 설정한 것은 더이상 존재하는 페이지가 없다는 의미로 남은 페이지가 있다면 e.HasMorePages를 True로 설정하면 다음 페이지 인쇄를 다음 이벤트를 통해서 이어갈 수 있습니다.

인쇄 기능 개발이 쉽지만은 않은 이유중에 하나는 테스트가 단순하지 않다는 것입니다. 실제 종이로 인쇄하지 않고 이미지 프린터등을 사용할 수도 있지만 이 또한 번거롭기는 마찬가지입니다. 실제 인쇄 테스트 이전에 인쇄 관련 로직을 점검할 수 있는 방법이 바로 미리보기입니다. PrintPreviewControl 또는 PrintPreviewDialog 컨트롤로 수행할 수 있는 미리보기도 실제 인쇄와 마찬가지로 PrintDocument의 이벤트를 동일하게 사용하기 때문입니다. 나름의 윈도우 폼으로 미리보기를 제작할 경우에 사용하는 PrintPreviewControl은 다음의 코드와 같이 사용할 수 있습니다.

    Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
        PrintPreviewControl1.Document = PrintDocument1
        PrintPreviewControl1.Show()
    End Sub

물론 사전에 PrintDocument 관련 코드가 준비되어 있어야 합니다.


PrintPreviewDialog 컨트롤은 사용자의 윈도우 폼에 직접 미리보기를 구성하는 것이 아니라 시스템에서 제공하는 대화창을 사용하는 것으로 사용법은 PrintPreviewControl과 유사합니다.

    Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
        PrintPreviewDialog1.Document = PrintDocument1
        PrintPreviewDialog1.ShowDialog()
    End Sub

아래의 그림은 위의 코드를 통해 열린 인쇄 미리보기 대화창입니다.




댓글
  • 프로필사진 dokdoki 안녕하세요
    vb.net 초보자입니다.
    님께서 올려놓으신 자료들이 공부하는데 많은 도움이 되었습니다.
    제가 하나 궁금해 고수님에게 질문드립니다.
    현재 도트프린더기를 사용중인데, 인쇄버튼을 누르면 인쇄가 됩니다.
    그런데 인쇄가 끝나면 그기에 멈춰있습니다.
    용지가 다음페이지까지 자동으로 올라가게 하려면 어떻게 해야하나요?
    고수님의 조언 부탁드립니다.
    수고하세요 꾸벅^^
    2020.10.23 09:11 신고
  • 프로필사진 야라바 와우! 도트 프린터라니! 테스트 환경이 없어서 확신을 못 드리겠지만 prt1: 디바이스로 FF(Form Feed)나 LF(Line feed)를 직접 날리는 테스트 해보시면 어떨지...... 2020.10.23 20:22 신고
  • 프로필사진 dokdoki 네. 한번 시도해보겠습니다.
    조언 감사드립니다. ^^
    2020.10.24 03:50 신고
댓글쓰기 폼