C# - Imprimindo com PrintDocument (revisão)


Este artigo é essencialmente prático e mostra como imprimir documentos com múltiplas páginas.

Uma das maneiras de realizar esta tarefa é criar uma classe que deriva de PrintDocument e no tratamento de evento PrintPage definir definir a propriedade PrintPageEventArgs.HasMorePages como true enquanto houver páginas a serem impressas.

O evento PrintDocument.PrintPage é acionado para permitir a impressão de apenas uma única página. Se você precisar imprimir mais páginas, você precisa definir a propriedade PrintPageEventArgs.HasMorePages como true no manipulador de evento PrintPage.

Enquanto HasMorePages é definida como true, a classe PrintDocument continuará disparando eventos PrintPage. No entanto, é melhor você controlar a pagina atual, qual página deve ser impressa e quando você deve encerrar a impressão definindo HasMorePages como false usando uma classe personalizada.

Vejamos então um exemplo que mostra como fazer isso...

Abra o Visual C# 2010 Express Edition e crie um novo projeto do tipo Windows Forms Application com o nome Impressao_PrintDocument;

Vamos começar criando a classe que deriva de PrintDocument.

No menu Project clique em Add Class e informe o nome da classe como ImprimirDocumento.cs;

A seguir inclua o código abaixo na classe:

using System.Drawing.Printing;

namespace Impressao_PrintDocument
{
    public class ImprimirDocumento : PrintDocument
    {
        private string[] texto;
        private int numeroPagina;
        private int offset;

        public string[] Texto
        {
            get { return texto; }
            set { texto = value; }
        }

        public int NumeroPagina
        {
            get { return numeroPagina; }
            set { numeroPagina = value; }
        }

        public int Offset
        {
            get { return offset; }
            set { offset = value; }
        }

        public ImprimirDocumento(string[] _texto)
        {
            this.Texto = _texto;
        }
    }
}

Nesta classe definimos 3 propriedades para tratar o texto , o numero da página. A classe herda de PrintDocument e dessa forma tem acesso a todos os métodos expostos por esta classe.

No formulário form1.cs inclua um botão de comando(btnImprimir) apenas para disparar a impressão e um controle CheckBox(chkVisualizaImpressao) para permitir que o usuário indique se deseja visualizar a impressão, conforme o leiaute abaixo:

Vamos iniciar a definição do código do formulário form1.cs declarando os namespaces usados :

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Printing;

A seguir no evento Click do botão - btnImprimir - para imprimir digite o código abaixo:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Printing;

namespace Impressao_PrintDocument
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnImprimir_Click(object sender, EventArgs e)
        {
            // Cria um documento com 150 linhas
            string[] textoParaImpressao = new string[151];
            for (int i = 0; i < 151; i++)
            {
                textoParaImpressao[i] = i.ToString();
                textoParaImpressao[i] += "http://www.macoratti.net - Quase tudo para Visual Basic.";
            }

            PrintDocument doc = new ImprimirDocumento(textoParaImpressao);
            doc.PrintPage += this.Doc_PrintPage;

            PrintDialog dialogo = new PrintDialog();
            dialogo.Document = doc;

            //  Se o usuário clicar em OK , imprime o documento
            if (dialogo.ShowDialog() == DialogResult.OK)
            {
                //verifica se o usuário deseja visualizar a impressao
                if (chkVisualizaImpressao.Checked)
                {
                    PrintPreviewDialog ppdlg = new PrintPreviewDialog();
                    ppdlg.Document = doc;
                    ppdlg.ShowDialog();
                }
                else
                {
                    doc.Print();
                }
            }
        }
    }
}

Basta agora definir o método Doc_PrintPage que vai usar a classe criada para realizar a impressão conforme o código a seguir:

        private void Doc_PrintPage(object sender, PrintPageEventArgs e)
        {
            // Recupera o documento que enviou este evento.
            ImprimirDocumento doc = (ImprimirDocumento)sender;

            // Define a fonte e determina a altura da linha
            using (Font fonte = new Font("Verdana", 10))
            {
                float alturaLinha = fonte.GetHeight(e.Graphics);

                // Cria as variáveis para tratar a posição na página
                float x = e.MarginBounds.Left;
                float y = e.MarginBounds.Top;

                // Incrementa o contador de página para refletir
                // a página que esta sendo impressa

                doc.NumeroPagina += 1;

                // Imprime toda a informação que cabe na página
                // O laço termina quando a próxima linha
                // iria passar a borda da margem ou quando não
                // houve mais linhas a imprimir

                while ((y + alturaLinha) < e.MarginBounds.Bottom &&
                  doc.Offset <= doc.Texto.GetUpperBound(0))
                {
                    e.Graphics.DrawString(doc.Texto[doc.Offset], fonte,
                      Brushes.Black, x, y);

                    // move para a proxima linha
                    doc.Offset += 1;

                    // Move uma linha para baixo (proxima linha)
                    y += alturaLinha;
                }

                if (doc.Offset < doc.Texto.GetUpperBound(0))
                {
                    // Havendo ainda pelo menos mais uma página.
                    // Sinaliza o evento para disparar novamente

                    e.HasMorePages = true;
                }
                else
                {
                    // A impressão terminou
                    doc.Offset = 0;
                }
            }
        }

Executando o projeto o formulário form1.cs será apresentado e clicando no botão de comando com o checkbox marcado para visualizar impressão teremos a apresentação do diálogo de impressão conforme figura a seguir:

Clicando no botão OK do diálogo teremos a visualização conforme abaixo:

A classe que criamos para tratar a impressão pode ser acrescida de outros recursos e refinamentos. Que tal exercitar ????

Pegue o projeto completo aqui : Impressao_PrintDocument.zip

João 8:31 Dizia, pois, Jesus aos judeus que nele creram: Se vós permanecerdes na minha palavra, verdadeiramente sois meus discípulos;
João 8:32
e conhecereis a verdade, e a verdade vos libertará.

Referências:


José Carlos Macoratti