Gerenciamento de Impressoras em C#

Este artigo demonstra como interagir com impressoras usando C#, abordando a listagem de dispositivos disponíveis, a obtenção de bandejas de papel, e a implementação de métodos para impressão de imagens. O código é reestruturado para reduzir a semelhança com exemplos convencionais, mantendo a funcionalidade.

Listagem de Impressoras Instaladas

Para obter todos os nomes de impressoras disponíveis no sistema, utilize a propriedade estática InstalledPrinters da classe PrinterSettings. O exemplo abaixo coleta os nomes em uma lista.

using System.Collections.Generic;
using System.Drawing.Printing;

var listaImpressoras = new List<string>();
foreach (string nomeImpressora in PrinterSettings.InstalledPrinters)
{
    listaImpressoras.Add(nomeImpressora);
}

Recuperação de Bandejas de Papel

Para enumerar as bandejas de papel de uma impressora específica, configure um objeto PrinterSettings com o nome desejado e itere sobre a coleção PaperSources.

using System.Drawing.Printing;

var configuracoes = new PrinterSettings { PrinterName = nomeImpressora };
var bandejas = new List<string>();
foreach (PaperSource fonte in configuracoes.PaperSources)
{
    bandejas.Add(fonte.SourceName);
}

Evento de Impressão de Imagens

Um manipulador de eventos para a página de impressão pode carregar uma imagem de um arquivo e desenhá-la no contexto gráfico. Este método é adaptado para usar fluxos de bytes de forma alternativa.

using System.Drawing;
using System.Drawing.Printing;
using System.IO;

private void ManipuladorPaginaImpressao(object sender, PrintPageEventArgs args)
{
    byte[] dadosImagem = File.ReadAllBytes(caminhoArquivo);
    using (var memoria = new MemoryStream(dadosImagem))
    {
        Image imagem = Image.FromStream(memoria);
        args.Graphics.DrawImage(imagem, 0, 0);
    }
    args.HasMorePages = false;
}

Configuração e Execução da Impressão

Para enviar um trabalho de impressão, associe o manipulador de eventos a um objeto PrintDocument, defina a impressora alvo e envoque o método Print.

using System.Drawing.Printing;

using (var documento = new PrintDocument())
{
    documento.PrintPage += ManipuladorPaginaImpressao;
    documento.PrinterSettings.PrinterName = nomeImpressora;
    documento.Print();
}

Classe Utilitária para Impressão Avançada

A classe a seguir encapsula operações de impressão com suporte a múltiplas imagens, rotação e configurações baseadas em parâmetros. Ela utiliza configurações de aplicativo para dimensões e posições.

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Web;

namespace UtilidadesImpressao
{
    public class GerenciadorImpressao
    {
        private static string caminhoTemporario = string.Empty;

        // Configurações para layouts específicos
        private static readonly int posicaoXLayoutA = ObterConfigInteiro("LayoutA_X");
        private static readonly int posicaoYLayoutA = ObterConfigInteiro("LayoutA_Y");
        private static readonly int larguraImagemLayoutA = ObterConfigInteiro("LayoutA_Largura");
        private static readonly int alturaImagemLayoutA = ObterConfigInteiro("LayoutA_Altura");
        private static readonly int espacamentoVertical = ObterConfigInteiro("LayoutA_EspacamentoV");

        private static readonly int posicaoXLayoutB = ObterConfigInteiro("LayoutB_X");
        private static readonly int posicaoYLayoutB = ObterConfigInteiro("LayoutB_Y");
        private static readonly int larguraImagemLayoutB = ObterConfigInteiro("LayoutB_Largura");
        private static readonly int alturaImagemLayoutB = ObterConfigInteiro("LayoutB_Altura");
        private static readonly int espacamentoHorizontal = ObterConfigInteiro("LayoutB_EspacamentoH");
        private static readonly int espacamentoVerticalB = ObterConfigInteiro("LayoutB_EspacamentoV");

        private static readonly int larguraPaginaA4 = ObterConfigInteiro("PaginaA4_Largura");
        private static readonly int alturaPaginaA4 = ObterConfigInteiro("PaginaA4_Altura");

        private static int ObterConfigInteiro(string chave)
        {
            return Convert.ToInt32(ConfigurationManager.AppSettings[chave]);
        }

        public void ImprimirLayoutA(List<Image> imagens, string nomeImpressora, string nomeBandeja)
        {
            using (var superficie = new Bitmap(larguraPaginaA4, alturaPaginaA4))
            using (var grafico = Graphics.FromImage(superficie))
            {
                grafico.Clear(Color.White);
                for (int i = 0; i < imagens.Count; i++)
                {
                    int offsetY = i * (alturaImagemLayoutA + espacamentoVertical);
                    grafico.DrawImage(imagens[i], posicaoXLayoutA, posicaoYLayoutA + offsetY, larguraImagemLayoutA, alturaImagemLayoutA);
                }
                ExecutarTrabalhoImpressao(superficie, nomeImpressora, nomeBandeja);
            }
        }

        public void ImprimirLayoutB(List<Image> imagens, string nomeImpressora, string nomeBandeja)
        {
            using (var superficie = new Bitmap(larguraPaginaA4, alturaPaginaA4))
            using (var grafico = Graphics.FromImage(superficie))
            {
                grafico.Clear(Color.White);
                for (int i = 0; i < imagens.Count; i++)
                {
                    int coluna = i % 2;
                    int linha = i / 2;
                    int posX = posicaoXLayoutB + coluna * (larguraImagemLayoutB + espacamentoHorizontal);
                    int posY = posicaoYLayoutB + linha * (alturaImagemLayoutB + espacamentoVerticalB);
                    using (var rotacionada = RotacionarImagem(imagens[i]))
                    {
                        grafico.DrawImage(rotacionada, posX, posY, larguraImagemLayoutB, alturaImagemLayoutB);
                    }
                }
                ExecutarTrabalhoImpressao(superficie, nomeImpressora, nomeBandeja);
            }
        }

        private Bitmap RotacionarImagem(Image original)
        {
            var bmp = new Bitmap(original);
            bmp.RotateFlip(RotateFlipType.Rotate270FlipXY);
            return bmp;
        }

        private void ExecutarTrabalhoImpressao(Image imagem, string nomeImpressora, string nomeBandeja)
        {
            string idSessao = Guid.NewGuid().ToString("N");
            caminhoTemporario = Path.Combine(HttpContext.Current.Server.MapPath("~/temp"), $"{idSessao}.png");
            try
            {
                imagem.Save(caminhoTemporario);
                using (var docImpressao = new PrintDocument())
                {
                    var configImpressora = new PrinterSettings { PrinterName = nomeImpressora };
                    foreach (PaperSource fonte in configImpressora.PaperSources)
                    {
                        if (fonte.SourceName == nomeBandeja)
                        {
                            docImpressao.DefaultPageSettings.PaperSource = fonte;
                            break;
                        }
                    }
                    docImpressao.PrintPage += ManipuladorPaginaImpressao;
                    docImpressao.PrinterSettings.PrinterName = nomeImpressora;
                    docImpressao.Print();
                }
            }
            finally
            {
                if (File.Exists(caminhoTemporario))
                {
                    File.Delete(caminhoTemporario);
                }
            }
        }

        public static double MilimetrosParaPixels(double comprimentoEmMilimetros)
        {
            using (var painel = new System.Windows.Forms.Panel())
            using (var grafico = Graphics.FromHwnd(painel.Handle))
            {
                IntPtr hdc = grafico.GetHdc();
                int pixelsPorPolegadaLog = GetDeviceCaps(hdc, 8);
                int larguraTelaPixels = GetDeviceCaps(hdc, 4);
                grafico.ReleaseHdc(hdc);
                return (pixelsPorPolegadaLog / 25.4) * comprimentoEmMilimetros;
            }
        }

        [DllImport("gdi32.dll")]
        private static extern int GetDeviceCaps(IntPtr hdc, int capacidade);
    }
}

Tags: CSharp dotnet System.Drawing.Printing PrintDocument PrinterSettings

Publicado em 6-24 19:03