Você está na página 1de 9

C# - Imprimindo em uma aplicao Windows Forms

Imprimir textos e grficos uma das muitas tarefas que um programador tem que realizar em uma aplicao Windows Forms. Enviar um texto para a impressora muito simples , mas a plataforma .NET no fornece os recursos de impresso para tarefa mais complexas como configurar uma impressora ou uma pgina para impresso, definir margins e imprimir mais que uma cpia. Neste aspecto a Microsoft ficou devendo... Neste artigo eu vou apresentar uma breve introduo sobre como efetuar a impresso com as classes da .NET Framework usando a linguagem C#. Para fornecer as funcionalidades bsicas para imprimir em aplicaes Windows Forms devemos estar familiarizados com a classe Graphics do namespace System.Drawing. Para imprimir usamos o namespace System.Drawing.Printing onde a classe principal a classe PrintDocument que representa um objeto que envia a saida para a impressora. Para imprimir um texto ou um grfico chamamos o mtodo Print da classe PrintDocument e um dos eventos que o mtodo Print invoca o evento PrintPage. (Voc precisa vincular um manipulador de evento a este evento e escrever o cdigo para enviar a sada para a impressora. ) O manipulador de eventos ir receber um argumento do tipo PrintPageEventArgs contendo os dados relacionados ao evento PrintPage e uma das propriedades deste argumento a propriedade Graphics a partir da qual voc pode obter um objeto Graphics. Este objeto Graphics representa uma pgina a ser impressa e para enviar uma string para a impressora, por exemplo, voc pode usar o mtodo DrawString da classe Graphics. Voc pode chamar outros mtodo desta classe como FillRectangle, DrawEllipse, etc. Para ilustrar como imprimir usando os membros do namespce System.Drawing.Printing vamos usar um exemplo simples onde mostrarei como usar os recursos de impresso usando C#.

Criando o projeto Windows Forms - Editor de Textos bsico


Vou usar SharpDevelop mas podemos usar tambm o Visual C# Express Edition e criar um novo projeto do tipo Windows Application com o nome imprimindoC#;

Esta aplicao simula um editor de textos bsico usando o controle RichTextBox para exibir o contedo de um arquivo e permite salvar alteraes feitas, imprimir, configurar e visualizar impresso; No formulrio principal vamos definir o leiaute e incluir os componentes conforme demonstrado a seguir:

A partir da ToolBox seo Printing: PrintDialog PrintDocument PrintPreviewDi alog

A partir da ToolBox seo Windows Forms: MenuStrip OPenFileDialog SaveFileDialog RichTextBox

Os nomes dados aos itens do Menu so: AbrirArquivo Salvar ConfigurarImpr essao Imprimir VisualizarImpr essao Sair

Embora no seja o objetivo deste artigo vou exibir, sem entrar em detalhes, o cdigo no evento click dos itens de menu Abrir e Salvar. A rotina para abrir um arquivo colocada no evento Click do item Abrir do menu exibida no cdigo abaixo onde usamos um StreamReader para ler um arquivo a partir da opo de seleo do usurio usando um componente OpenFileDialog;
void AbrirArquivoClick(object sender, System.EventArgs e) { try { if (this.openFileDialog1.ShowDialog() == DialogResult.OK) { FileStream fs = new FileStream(openFileDialog1.FileName , FileMode.Open, FileAccess.Read); StreamReader m_streamReader = new StreamReader(fs); // Lendo para o arquivo usando a classe StreamReader m_streamReader.BaseStream.Seek(0, SeekOrigin.Begin); // L cada linha do stream e efetua o parse at alcanar a ltima linha this.richTextBox1.Text = ""; string linha = m_streamReader.ReadLine(); while (linha != null) { this.richTextBox1.Text += linha + "\n";

linha = m_streamReader.ReadLine(); } //Fecha o Stream m_streamReader.Close(); } } catch(Exception em) { MessageBox.Show(" Erro : "+ em.Message.ToString()); } }

A rotina para salvar alteraes feitas no arquivo dada a seguir no evento Click do item de menu Salvar onde usamos um StreamWriter para salvar as alteraes feitas usando um componente SaveFileDialog para escolher o caminho onde o arquivo ser salvo;
void SalvarClick(object sender, EventArgs e) { try { // Obtem o nome do arquivo para salvar if (this.saveFileDialog1.ShowDialog() == DialogResult.OK) { //abre o stream para escrever e cria um StreamWriter para usar na implementacao do stream FileStream fs = new FileStream(@saveFileDialog1.FileName , FileMode.OpenOrCreate, FileAccess.Write); StreamWriter m_streamWriter = new StreamWriter(fs); m_streamWriter.Flush(); // Escreve o artigo usando a classe StreamWriter m_streamWriter.BaseStream.Seek(0, SeekOrigin.Begin); // Escrever no controle rich edit control m_streamWriter.Write(this.richTextBox1.Text); // fecha o arquivo m_streamWriter.Flush(); m_streamWriter.Close(); } } catch(Exception em) { MessageBox.Show(" Erro : "+ em.Message.ToString()); } }

Para imprimir o arquivo aberto vamos usar o evento Click do item de menu Imprimir usando o cdigo a seguir: void ImprimirClick(object sender, EventArgs e) { printDialog1.Document = printDocument1; string texto = this.richTextBox1.Text; leitor = new StringReader(texto);

if (printDialog1.ShowDialog() == DialogResult.OK) { this.printDocument1.Print(); } } Esta rotina atribui o compononte PrintDialog ao documento a ser impresso: printDialog1.Document = printDocument1; O dilogo exibir usando o componente ShowDialog de maneira que o usurio pode definir as suas opes de impresso e decidir se imprime ou no o documento: if (printDialog1.ShowDialog() == DialogResult.OK) Depois que o mtodo Print do componente PrintDocument chamado this.printDocument1.Print(); - a impresso iniciada.
Um exemplo bem simples de como enviar um texto para a impressora exibido no cdigo abaixo: void printDocument1_PrintPage(object sender, PrintPageEventArgs e) { Graphics g = e.Graphics; using( Font font = new Font("Lucida Console", 36) ) { g.DrawString("Um alo do Macoratti...,\n para todos", font, ...); } }

Para concluir a impresso precisamos definir o cdigo no evento PrintPage conforme mostro abaixo:
void PrintDocument1PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { //variaveis usadas para definir as configuraes da impresso float linhasPorPagina = 0; float yPosicao = 0; int contador = 0; float margemEsquerda = e.MarginBounds.Left; float margemSuperior = e.MarginBounds.Top; string linha = null; Font fonteImpressao = this.richTextBox1.Font; SolidBrush mCaneta = new SolidBrush(Color.Black); // Define o numero de linhas por pagina, usando MarginBounds. linhasPorPagina = e.MarginBounds.Height / fonteImpressao.GetHeight(e.Graphics); // Itera sobre a string usando StringReader, imprimindo cada linha while(contador < linhasPorPagina && ((linha=leitor.ReadLine()) != null)) { // calcula a posicao da proxima linha baseada // na altura da fonte de acordo com o dispositivo de impresso yPosicao = margemSuperior + (contador * fonteImpressao.GetHeight(e.Graphics)); // desenha a proxima linha no controle RichTextBox e.Graphics.DrawString(linha, fonteImpressao, mCaneta, margemEsquerda, yPosicao, new StringFormat());

contador++; } // Verifica se existe mais linhas para imprimir if(linha != null) e.HasMorePages = true; else e.HasMorePages = false; //libera recursos mCaneta.Dispose(); }

O evento PrintPage automaticamente chamado pelo sistema para imprimir a pgina selecionada. O evento e do tipo PrintPageEventArgs contm o contexto do dispositivo e.Graphics usado para imprimir para a impressora.

A propriedade PageBounds da classe PrintPageEventArgs representa um retngulo da p representa um retngulo da rea do interior das margens conforme mostra a figura ao l

Ambas as propriedades so usadas na unidade de 100 dpi, de maneira que um formato c PageBounds de medida igual a {0, 0, 850, 1100}. Com uma margem padro de 1 poleg {100, 100, 650, 900}.

A margem til porque muitas impressoras no podem imprimir a partir do incio das b nestes casos o objetop Graphics que voc manuseia quando voc imprime, inicia a impr pgina.

Neste exemplo efetuamos a leitura de cada linha de texto do controle RichTextBox usando um StringReader que nos d a habilidade de tratar uma string como um stream e tomar vantagem da funo ReadLine para ler cada linha de texto no controle. Podemos calcular a posio das linhas baseadas nas margens e na altura da fonte, e com o objetivo de prever a altura da fonte para a impressora ns passamos a ela o contexto do dispositivo da impressora na funo GetHeight (printFont.GetHeight(ev.Graphics()), pois a altura da fonte na tela em pixels diferente da fonte na impressora. O atributo HasMorePages da classe PrintPageEventArg continuamente verificado de maneira que o evento PrintPage disparado se existirem mais linhas do que a pgina atual pode suportar. O cdigo para visualizar a impresso atribuido ao evento Click do item de menu Visualizar Impresso dado abaixo:
void VisualizarImpressaoClick(object sender, EventArgs e) { try { string texto = this.richTextBox1.Text; leitor = new StringReader(texto);

PrintPreviewDialog printPreviewDialog1 = new PrintPreviewDialog(); printPreviewDialog1.Document = this.printDocument1 ; printPreviewDialog1.FormBorderStyle = FormBorderStyle.Fixed3D ; printPreviewDialog1.ShowDialog(); } catch(Exception exp) { MessageBox.Show(" Erro : "+ exp.Message.ToString()); } }

O componente PrintPreview tambm dispara o evento PrintPage mas ao invs de direcionar para a impressora a saida direcionada para a tela de visualizao:

Vemos acima o resultado da visualizao da impresso para a aplicao exemplo.

O controle PreviewPrintController , o qual usado para visualizar um documento antes de sua impresso, incia pelo controle PrintPreviewControl o qual mostra previamente uma pgina do documento. O controle PrintPreview disponvel na Toolbos e usa os comandos de desenho realizados no evento PrintPage para exibir uma rea de visu impresso.

No evento Click do item do menu Configurar Impresso temos o cdigo que permite ao usurio configurar a impresso atravs da janela PrintDialog:
void ConfigurarImpressaoClick(object sender, EventArgs e) { this.printDialog1.Document = this.printDocument1; printDialog1.ShowDialog(); }

Quando voc cria uma instncia de PrintDialog , as propriedades read/write so definidas para os valores iniciais os quais so:

Propriedade Valor Inicial AllowSomePages false AllowPrintToFile true AllowSelection false Document null (Nothing no VB) PrinterSettings null (Nothing no VB) PrintToFile false ShowHelp false ShowNetwork true Para obter as configuraes que so modificadas pelo usurio com o PrintDialog utilize a propriedade PrinterSettings. Finalmente, e apenas para constar , abaixo temos o cdigo para encerrar a aplicao associado ao evento Click do item de menu Sair:

void SairClick(object sender, EventArgs e) { DialogResult result1 = MessageBox.Show("Confirma encerramento da aplicao?", "Encerrar?",MessageBoxButtons if (result1 == DialogResult.Yes ) { Application.Exit(); } }

E para encerrar um dica lega: Obtendo informao sobre as impressoras instaladas Para isso basta ler os nomes na coleo InstalledPrinters da classe
System.Drawing.Printing.PrinterSettings veja abaixo um exemplo de cdigo: Obs: No esquea de definir a declarao do namespace System.Drawing.Printing; void ImpressorasInstaladasClick(object sender, EventArgs e) { foreach (string printerName in PrinterSettings.InstalledPrinters) { // Exibe o nome da impressora Console.WriteLine("Impressora: {0}", printerName); // Retorna as configuraes da impressora PrinterSettings printer = new PrinterSettings(); printer.PrinterName = printerName; // Verifica se a impressora vlida if (printer.IsValid) { // Exibe a lista de resolues vlidas Console.WriteLine("Resolues suportadas:"); foreach (PrinterResolution resolution in printer.PrinterResolutions) { Console.WriteLine(" {0}", resolution);

} Console.WriteLine(); // Exibe uma lista de tamanho de papeis validos Console.WriteLine("Tamanho de papeis suportados:"); foreach (PaperSize size in printer.PaperSizes) { if (Enum.IsDefined(size.Kind.GetType(), size.Kind)) { Console.WriteLine(" {0}", size); } } Console.WriteLine(); } } Console.ReadLine(); }

E com isso dei uma viso geral sobre os aspectos mais importantes da impresso em WIndows Forms usando a linguagem C#. Pegue o projeto completo aqui: impressaoCSharp.zip

Eu sei apenas C# , mas eu gosto... Referncias:


Impresso e Visualizao. O que h de novo ? VB .NET - Imprimindo via cdigo Visualizandoa impresso no VB VB 2008 - Cadastro de Alunos
Jos Carlos Macoratti