메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

C# 인쇄 기능

한빛미디어

|

2002-10-10

|

by HANBIT

24,263

저자: 부디 쿼니아완(Budi Kurniawan), 역 한동훈

텍스트와 그래픽을 인쇄하는 것은 윈도우 응용 프로그램 프로그래밍에서 중요한 작업들 중에 하나다. 닷넷에서 프린터에 문자열을 보내는 것과 같은 간단한 인쇄는 쉽지만 닷넷 프레임워크에는 복잡한 인쇄 작업을 캡슐화하여 바로 사용할 수 있는 클래스들이 부족하다. 예를 들어 사용자가 프린터와 인쇄할 페이지를 설정하고, 여백을 변경하고, 한 부 이상 인쇄하기 등의 작업을 할 수 있게 하려면 약간의 코딩 작업이 필요하다. 본 기사는 닷넷 프레임워크 클래스 라이브러리를 사용하여 인쇄에 대한 간단한 자습을 할 수 있게 해주는 지침서이다. 여러분이 작성한 윈도우 응용 프로그램에 인쇄 기능을 제공하려면 System.Drawing 네임스페이스에 있는 Graphics 클래스에 익숙해져야한다. System.Drawing 네임 스페이스의 Graphics 클래스에 대한 논의는 이전에 소개한 "System.Drawing with C#"이라는 기사를 참고하기 바란다.

인쇄를 하기 위해서는 System.Drawing.Printing 네임 스페이스를 사용해야 한다. 이 네임 스페이스에서 중요한 클래스는 프린터에 출력을 보내는 객체를 표현하는 PrintDocument 클래스다. PrintDocument 클래스는 간단한 인쇄 작업과 복잡한 인쇄 작업을 이 클래스 하나로 모두 수행할 수 있게 해주는 중심 클래스 역할을 한다. 그러나 앞으로 보게 될 것처럼 System.Drawing.Printing 네임 스페이스의 다른 클래스와 다른 네임 스페이스들은 코딩을 보다 쉽게 하는데 도움을 준다.

텍스트 또는 그래픽을 인쇄하려면 System.Drawing.Printing.PrintDocument 클래스의 Print 메소드를 호출한다. Print 메소드에서 사용하는 이벤트 중에 하나는 PrintPage 이벤트다. 따라서 여러분은 PrintPage 이벤트를 이벤트 핸들러와 연결해야 하며, 프린터에 출력을 보내는 코드를 작성해야 한다. 이벤트 핸들러는 PrintPage 이벤트와 관련된 데이터를 포함한 System.Drawing.Printing.PrintPageEventArgs 형식의 인자를 사용한다. PrintPageEventArgs의 속성 중에 하나인 Graphics를 사용하여 System.Drawing.Graphics 객체를 얻을 수 있다. 이 Graphics 객체는 하나의 인쇄 페이지를 나타낸다. 예를 들어 프린터에 문자열을 보내려면 Graphics 클래스의 DrawString 메소드를 사용한다. 물론 FillRectangle, DrawEllipse와 같은 Graphics 클래스의 다른 메소드를 호출할 수도 있다.

System.Drawing.Printing 네임 스페이스의 멤버들을 사용해서 인쇄 작업을 수행하는 방법을 설명하기 위해 예제 1에 있는 것과 같은 간단한 폼을 작성한다. 이 폼은 인쇄 기능이 없는 비어있는 폼이다. 이 클래스에 인쇄 기능을 추가하기 위해 코드를 점차적으로 추가한다. 목록 1의 코드는 하나의 메뉴 항목 fileMenuItem을 포함한 메뉴를 가진 폼 클래스이다. fileMenuItem은 차례대로 세 가지 하위 메뉴 항목 filePageSetupMenuItem, filePrintPreviewMenuItem, filePrintMenuItem을 포함한다.

목록 1: 인쇄를 위한 폼 템플릿
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace CSharpPrinting
{
  public class Form1 : System.Windows.Forms.Form
  {
    public Form1() 
    {
      MenuItem fileMenuItem = new MenuItem("&File");
      MenuItem filePageSetupMenuItem = new MenuItem("Page Set&up...", 
        new EventHandler(filePageSetupMenuItem_Click));
      MenuItem filePrintPreviewMenuItem = new MenuItem("Print Pre&view", 
        new EventHandler(filePrintPreviewMenuItem_Click));
      MenuItem filePrintMenuItem = new MenuItem("&Print...", 
        new EventHandler(filePrintMenuItem_Click), Shortcut.CtrlP);

      fileMenuItem.MenuItems.Add(filePageSetupMenuItem);
      fileMenuItem.MenuItems.Add(filePrintPreviewMenuItem);
      fileMenuItem.MenuItems.Add(filePrintMenuItem);

      this.Menu = new MainMenu();
      this.Menu.MenuItems.Add(fileMenuItem);
    }
    // -------------- event handlers -------------------------------------
    private void filePrintMenuItem_Click(Object sender , EventArgs e) 
    {
    }
    private void filePrintPreviewMenuItem_Click(Object sender , 
            EventArgs e) 
    {
    }
    private void filePageSetupMenuItem_Click(Object sender , 
            EventArgs e) 
    {
    }
    //-------------- end of event handlers ------------------------------
    [STAThread]
    static void Main() 
    {
      Application.Run(new Form1());
    }
  }
}
fileMenuItem에 있는 세 가지 메뉴 항목 각각을 선언 부분에서 이벤트 핸들러와 연결하고 있다는 것을 알 수 있다. 세 가지 메뉴 항목에 대한 이벤트 핸들러는 다음 코드에 나와 있는 것처럼 filePageSetupMenuItem_Click, filePrintPreviewMenuItem_Click, filePrintMenuItem_Click이며 이 코드는 클래스 생성자 부분에 있다.
MenuItem filePageSetupMenuItem = new MenuItem("Page Set&up...", 
     new EventHandler(filePageSetupMenuItem_Click));
MenuItem filePrintPreviewMenuItem = new MenuItem("Print Pre&view", 
     new EventHandler(filePrintPreviewMenuItem_Click));
MenuItem filePrintMenuItem = new MenuItem("&Print...", 
     new EventHandler(filePrintMenuItem_Click), Shortcut.CtrlP);
목록 1의 코드에서 볼 수 있는 것처럼 세 가지 이벤트 핸들러는 현재 비어있다.
private void filePrintMenuItem_Click(Object sender , EventArgs e) 
{
}
private void filePrintPreviewMenuItem_Click(Object sender , EventArgs e) 
{
}
private void filePageSetupMenuItem_Click(Object sender , EventArgs e) 
{
}
이제, 이 템플릿에 인쇄 기능을 추가하기 위해 코드를 추가할 준비는 끝났다. 이제부터는 인쇄 기능을 추가해보자.
  1. System.Drawing.Printing.PrintDocument 형식의 클래스 수준 변수 printDoc를 추가한다.
    private PrintDocument printDoc = new PrintDocument();
    
  2. 클래스 생성자에서 printDocPrintPage 이벤트와 이벤트 핸들러를 연결한다. 여기서는 이벤트 핸들러는 printDoc_PrintPage다.
    printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage); 
    
  3. filePrintMenuItem_Click 이벤트 핸들러에 대한 코드를 추가한다.
    private void filePrintMenuItem_Click(Object sender, EventArgs e)
    {
      printDoc.Print();
    }
    
  4. printDoc_PrintPage에 코드를 추가한다.
    private void printDoc_PrintPage(Object sender , PrintPageEventArgs e)
    {
      String textToPrint = ".NET Printing is easy";
      Font printFont = new Font("Courier New", 12);
      e.Graphics.DrawString(textToPrint, printFont, Brushes.Black, 0, 0);
    }
    

C# in a Nutshell

참고 도서

C# in a Nutshell
Peter Drayton, Ben Albahari




결과 폼은 목록 2에 나와 있다.

목록 2 : 인쇄 코드를 추가한 폼
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace CSharpPrinting
{
        public class Form1 : System.Windows.Forms.Form
        {
    private PrintDocument printDoc = new PrintDocument();

    public Form1() 
    {
      MenuItem fileMenuItem = new MenuItem("&File");
      MenuItem filePageSetupMenuItem = new MenuItem("Page 
        Set&up...", new EventHandler(filePageSetupMenuItem_Click));
      MenuItem filePrintPreviewMenuItem = new MenuItem("Print 
        Pre&view", new EventHandler(filePrintPreviewMenuItem_Click));
      MenuItem filePrintMenuItem = new MenuItem("&Print...", 
        new EventHandler(filePrintMenuItem_Click), Shortcut.CtrlP);

      fileMenuItem.MenuItems.Add(filePageSetupMenuItem);
      fileMenuItem.MenuItems.Add(filePrintPreviewMenuItem);
      fileMenuItem.MenuItems.Add(filePrintMenuItem);

      this.Menu = new MainMenu();
      this.Menu.MenuItems.Add(fileMenuItem);
      printDoc.PrintPage += new PrintPageEventHandler(
              printDoc_PrintPage); 
    }
    
    // -------------- event handlers ---------------------------------
    private void filePrintMenuItem_Click(Object sender , 
            EventArgs e) 
    {
      printDoc.Print();
    }
    
    private void filePrintPreviewMenuItem_Click(Object sender , 
            EventArgs e) 
    {
    }
    
    private void filePageSetupMenuItem_Click(Object sender , 
            EventArgs e) 
    {
    }
    
    private void printDoc_PrintPage(Object sender , 
            PrintPageEventArgs e)
    {
      String textToPrint = ".NET Printing is easy";
      Font printFont = new Font("Courier New", 12);
      e.Graphics.DrawString(textToPrint, printFont, 
            Brushes.Black, 0, 0);
    }
//-------------- end of event handlers -------------------------------


[STAThread]
    static void Main() 
    {
      Application.Run(new Form1());
    }
  }
}
이제 폼을 실행하고 Ctrl+P를 누르면(물론, 여러분이 사용하고 있는 컴퓨터에 프린터가 연결되고 있고, 올바른 드라이버가 설치되어 있다고 가정한 것임), 프린터는 ".NET printing is easy."라는 문자열을 인쇄할 것이다. 쉽지 않은가?

PrintDialog 사용하기

일반적으로 윈도우 응용 프로그램은 인쇄하기 전에 인쇄 대화 상자를 보여준다. 인쇄 대화 상자는 사용자가 인쇄를 취소하거나, 프린터 속성을 변경하고, 인쇄 부수를 선택하거나, 인쇄할 페이지를 선택할 수 있는 기능을 제공한다. 목록 2에 있는 filePrintMenuItem_Click을 목록 3에 있는 것과 같이 수정하면 사용자가 인쇄를 하기 전에 인쇄 대화 상자가 표시될 것이다. 인쇄 대화 상자는 System.Windows.Forms.PrintDialog 클래스로 표현된다.

목록 3: PrintDialog 사용하기
private void filePrintMenuItem_Click(Object sender , EventArgs e) 
    {
      PrintDialog dlg = new PrintDialog();
      dlg.Document = printDoc;
      if (dlg.ShowDialog() == DialogResult.OK) 
      {
        printDoc.Print();
      }
    }
목록 3의 filePrintMenuItem_Click 이벤트 핸들러는 사용자가 인쇄 대화 상자의 OK 버튼을 클릭하는 경우에만 프린터에 출력을 보낸다. 그러나, 사용자가 인쇄 대화 상자에서 변경한 설정은 여러분이 이러한 옵션에 대한 코드를 작성하지 않는 한 적용되지 않는다.

페이지 설정

다음은 인쇄에 사용할 용지를 설정하는 기능을 추가하는 작업이다. 이 기능을 추가하기 위해 다음과 같은 단계를 따른다.
  1. System.Drawing.Printing.PageSettings 클래스의 인스턴스를 생성한다(이 예제에서는 폼 클래스의 선언 부분 다음에 추가했다).
    private PageSettings pgSettings = new PageSettings();
    
  2. 인쇄하기 전에 printDocDefaultPageSettings 속성에 pgSettings을 설정한다. 따라서, 폼의 filePrintMenuItem_Click 이벤트 핸들러에 강조된 부분의 코드를 추가한다.
    private void filePrintMenuItem_Click(Object sender , EventArgs e) 
        {
          printDoc.DefaultPageSettings = pgSettings;
          PrintDialog dlg = new PrintDialog();
          dlg.Document = printDoc;
          if (dlg.ShowDialog() == DialogResult.OK) 
          {
            printDoc.Print();
          }
        }
    
  3. 이제 사용자는 페이지의 설정을 변경할 수 있게 하자. 이 예제에서는 filePageSetupMenuItem_Click 이벤트 핸들러에 다음 코드를 추가한다.
    private void filePageSetupMenuItem_Click(Object sender , EventArgs e) 
        {
          PageSetupDialog pageSetupDialog = new PageSetupDialog();
          pageSetupDialog.PageSettings = pgSettings;
          pageSetupDialog.AllowOrientation = true;
          pageSetupDialog.AllowMargins = true;
          pageSetupDialog.ShowDialog();
        }
    
  4. 윗 여백과 왼쪽 여백을 설정할 수 있게 printDoc_PrintPage를 수정한다. 폼의 코드는 다음과 같다.
    private void printDoc_PrintPage(Object sender , PrintPageEventArgs e)
        {
          String textToPrint = ".NET Printing is easy";
          Font printFont = new Font("Courier New", 12);
          int leftMargin = e.MarginBounds.Left;
          int topMargin = e.MarginBounds.Top;
          e.Graphics.DrawString(textToPrint, printFont, Brushes.Black, 
                leftMargin, topMargin);
        }
    
이제 File 메뉴에서 Page Setup을 선택할 수 있으며, 화면에 나타나는 프린터 설정 대화 상자는 여러분이 사용하는 프린터 종류에 따라 다르게 나타날 것이다. 페이지 설정을 포함한 폼의 완전한 코드는 목록 4에 나와 있다.

목록 4: 사용자가 페이지 설정을 변경할 수 있는 폼 클래스
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace CSharpPrinting
{
        public class Form1 : System.Windows.Forms.Form
        {
    private PrintDocument printDoc = new PrintDocument();
    private PageSettings pgSettings = new PageSettings();

    public Form1() 
    {
      MenuItem fileMenuItem = new MenuItem("&File");
      MenuItem filePageSetupMenuItem = new MenuItem(
        "Page Set&up...", new EventHandler(
            filePageSetupMenuItem_Click));
      MenuItem filePrintPreviewMenuItem = new MenuItem(
        "Print Pre&view", new EventHandler(
            filePrintPreviewMenuItem_Click));
      MenuItem filePrintMenuItem = new MenuItem("&Print...", 
        new EventHandler(filePrintMenuItem_Click), 
            Shortcut.CtrlP);

      fileMenuItem.MenuItems.Add(filePageSetupMenuItem);
      fileMenuItem.MenuItems.Add(filePrintPreviewMenuItem);
      fileMenuItem.MenuItems.Add(filePrintMenuItem);

      this.Menu = new MainMenu();
      this.Menu.MenuItems.Add(fileMenuItem);
      printDoc.PrintPage += new PrintPageEventHandler(
            printDoc_PrintPage); 
    }
    
    
    // -------------- event handlers ----------------------
    private void filePrintMenuItem_Click(Object sender , 
            EventArgs e) 
    {


      printDoc.DefaultPageSettings = pgSettings;
      PrintDialog dlg = new PrintDialog();
      dlg.Document = printDoc;
      if (dlg.ShowDialog() == DialogResult.OK) 
      {
        printDoc.Print();
      }
    }
    
    private void filePrintPreviewMenuItem_Click(Object sender , 
            EventArgs e) 
    {
    }
    
    private void filePageSetupMenuItem_Click(Object sender , 
            EventArgs e) 
    {
      PageSetupDialog pageSetupDialog = new PageSetupDialog();
      pageSetupDialog.PageSettings = pgSettings;
      pageSetupDialog.AllowOrientation = true;
      pageSetupDialog.AllowMargins = true;
      pageSetupDialog.ShowDialog();
    }
    
     
    private void printDoc_PrintPage(Object sender , 
            PrintPageEventArgs e)
    {
      String textToPrint = ".NET Printing is easy";
      Font printFont = new Font("Courier New", 12);
      int leftMargin = e.MarginBounds.Left;
      int topMargin = e.MarginBounds.Top;
      e.Graphics.DrawString(textToPrint, printFont, 
        Brushes.Black, leftMargin, topMargin);
    }
    

    //-------------- end of event handlers ------------------

        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

    }
}
프린터 설정

다음 단계를 따라해서 사용자가 프린터 설정을 변경하는 것을 허용할 수 있다.
  1. System.Drawing.Printing.PrinterSettings 클래스의 인스턴스를 생성한다. 폼에서는 다음 코드 줄을 추가한다.
    private PrinterSettings prtSettings = new PrinterSettings();
    
  2. PageSetupDialog 클래스의 PrinterSettings 속성에 prtSettings를 설정한다.
    private void filePageSetupMenuItem_Click(Object sender , EventArgs e) 
        {
          PageSetupDialog pageSetupDialog = new PageSetupDialog();
          pageSetupDialog.PageSettings = pgSettings;
          pageSetupDialog.PrinterSettings = prtSettings;
          pageSetupDialog.AllowOrientation = true;
          pageSetupDialog.AllowMargins = true;
          pageSetupDialog.ShowDialog();
        }
    
이제 페이지 설정 대화 상자에 인쇄 버튼을 사용할 수 있으며, 인쇄 버튼을 클릭하면 프린터 설정 페이지가 표시될 것이다.

인쇄 미리보기

윈도우 응용 프로그램은 사용자가 인쇄를 하기 전에 종이에 인쇄가 어떻게 되는지 알아보기 위해 미리보기 화면을 볼 수 있는 기능을 제공한다. 따라서 여러분도 filePrintPreviewMenuItem_Click 이벤트 핸들러에 다음 코드를 추가하여 이 기능을 추가할 수 있다.
private void filePrintPreviewMenuItem_Click(Object sender , EventArgs e) 
    {
      PrintPreviewDialog dlg = new PrintPreviewDialog();
      dlg.Document = printDoc;
      dlg.ShowDialog();
    }
인쇄 미리 보기 대화 상자는 System.Windows.Forms.PrintPreviewDialog 클래스로 표현되어 있다. 인자를 사용하지 않는 생성자를 사용해서 인쇄 미리보기 대화 상자의 인스턴스를 생성할 수 있다. 인스턴스를 생성한 다음에 인쇄를 하기 위해 PrintDocument 객체를 PrintPreviewDialog 객체의 Document 속성에 할당한다. ShowDialog 메소드가 호출될 때 PrintDocument 객체의 PrintPage 이벤트가 호출된다. 그러나 출력은 프린터에 보내지지 않고 PrintPreviewDialog 객체로 보내진다. 전체 코드는 목록 5에 나와 있다.

목록 5: 페이지 설정과 인쇄 미리보기를 제공하는 전체 소스 코드
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace CSharpPrinting
{
        public class Form1 : System.Windows.Forms.Form
        {
    private PrintDocument printDoc = new PrintDocument();
    private PageSettings pgSettings = new PageSettings();
    private PrinterSettings prtSettings = new PrinterSettings();

    public Form1() 
    {
      MenuItem fileMenuItem = new MenuItem("&File");
      MenuItem filePageSetupMenuItem = new MenuItem("Page Set&up...", 
        new EventHandler(filePageSetupMenuItem_Click));
      MenuItem filePrintPreviewMenuItem = new MenuItem("Print Pre&view", 
        new EventHandler(filePrintPreviewMenuItem_Click));
      MenuItem filePrintMenuItem = new MenuItem("&Print...", 
        new EventHandler(filePrintMenuItem_Click), Shortcut.CtrlP);

      fileMenuItem.MenuItems.Add(filePageSetupMenuItem);
      fileMenuItem.MenuItems.Add(filePrintPreviewMenuItem);
      fileMenuItem.MenuItems.Add(filePrintMenuItem);

      this.Menu = new MainMenu();
      this.Menu.MenuItems.Add(fileMenuItem);
      printDoc.PrintPage += new PrintPageEventHandler(
        printDoc_PrintPage); 
    }
        
    // -------------- event handlers ------------------------------------
    private void filePrintMenuItem_Click(Object sender , 
        EventArgs e) 
    {

      printDoc.DefaultPageSettings = pgSettings;
      PrintDialog dlg = new PrintDialog();
      dlg.Document = printDoc;
      if (dlg.ShowDialog() == DialogResult.OK) 
      {
        printDoc.Print();
      }
    }
    
    private void filePrintPreviewMenuItem_Click(Object sender , 
        EventArgs e) 
    {
      PrintPreviewDialog dlg = new PrintPreviewDialog();
      dlg.Document = printDoc;
      dlg.ShowDialog();
    }
    
    private void filePageSetupMenuItem_Click(Object sender , 
        EventArgs e) 
    {
      PageSetupDialog pageSetupDialog = new PageSetupDialog();
      pageSetupDialog.PageSettings = pgSettings;
      pageSetupDialog.PrinterSettings = prtSettings;
      pageSetupDialog.AllowOrientation = true;
      pageSetupDialog.AllowMargins = true;
      pageSetupDialog.ShowDialog();
    }
    
    private void printDoc_PrintPage(Object sender , 
        PrintPageEventArgs e)
    {
      String textToPrint = ".NET Printing is easy";
      Font printFont = new Font("Courier New", 12);
      int leftMargin = e.MarginBounds.Left;
      int topMargin = e.MarginBounds.Top;
      e.Graphics.DrawString(textToPrint, printFont, Brushes.Black, 
            leftMargin, topMargin);
    }

    //-------------- end of event handlers -----------------------------

        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

    }
}
결론

여러분도 알 수 있는 것처럼, 이 기사는 직접 작성한 윈도우 응용 프로그램에 인쇄 기능을 제공하는 방법을 단계별로 보여주었다. 그러나 인쇄를 위한 코드가 다른 코드의 여기저기에 흩어져 있다. 따라서 코드를 "지저분"하지 않게 만들면서 인쇄 기능을 구현하기 위해 자신의 클래스로 인쇄 기능을 캡슐화하는 것도 좋은 생각이다.
부디 쿼니아완(Budi Kurniawan)은 VB와 VB 프로그래밍에 대한 풍부한 경험을 갖고 있는 독립 컨설턴트이다.
TAG :
댓글 입력
자료실

최근 본 책0