Impressão

Este guia mostra como trabalhar com a API de impressão.

Visão geral

A página Web pode ser impressa das seguintes formas:

  1. A função JavaScript window.print(). Pode ser invocada a partir do código JavaScript numa página Web.
  2. O método IFrame.Print() da API DotNetBrowser. Ele solicita a impressão do frame. Se você precisar imprimir a página inteira, chame o método Print() no frame principal. Veja o exemplo de código abaixo:
browser.MainFrame?.Print();
If browser.MainFrame IsNot Nothing Then
    browser.MainFrame.Print()
End If

A página Web não é impressa imediatamente. O RequestPrintHandler será invocado para dizer ao engine como tratar o pedido de impressão. Por padrão, todos os pedidos de impressão são cancelados.

Configurar a impressão

Existem três handlers que podem ser utilizados para configurar a impressão:

  • RequestPrintHandler é utilizado para determinar como tratar os pedidos de impressão. Este manipulador pode ser utilizado para cancelar completamente a impressão, mostrar a pré-visualização da impressão ou dizer ao browser para imprimir o conteúdo de forma programática.
  • O PrintHtmlContentHandler é utilizado para configurar a forma de imprimir o conteúdo HTML de forma programática.
  • O PrintPdfContentHandler é utilizado para configurar a forma de imprimir o conteúdo do PDF de forma programática.

Cancelar impressão

Para cancelar qualquer pedido de impressão ou desativar a impressão, registre o RequestPrintHandler, tal como indicado na amostra de código abaixo:

browser.RequestPrintHandler =
    new Handler<RequestPrintParameters, RequestPrintResponse>(p =>
    {
        return RequestPrintResponse.Cancel();
    });
browser.RequestPrintHandler = 
    New Handler(Of RequestPrintParameters, RequestPrintResponse)(Function(p)
        Return RequestPrintResponse.Cancel()
    End Function)

Pré-visualização da impressão

Para permitir o pedido de impressão e apresentar a caixa de diálogo Print Preview , utilize o exemplo de código abaixo:

browser.RequestPrintHandler =
    new Handler<RequestPrintParameters, RequestPrintResponse>(p =>
    {
        return RequestPrintResponse.ShowPrintPreview();
    });
browser.RequestPrintHandler = 
    New Handler(Of RequestPrintParameters, RequestPrintResponse)(Function(p)
        Return RequestPrintResponse.ShowPrintPreview()
    End Function)

Na caixa de diálogo Print Preview, você pode selecionar as opções de impressão preferidas:

Pré-visualização da Impressão

A caixa de diálogo Print Preview também pode ser utilizada para imprimir o conteúdo em PDF. Na caixa de diálogo, você tem que clicar no botão Alterar… na seção Destino e selecionar Salvar como PDF. A página Web será salva depois de apertar o botão Salvar.

Eventos de pré-visualização de impressão

Para ser notificado quando a caixa de diálogo Pré-visualização de impressão tiver sido aberta ou fechada, utilize os eventos PrintPreviewOpened e PrintPreviewClosed:

Browser.PrintPreviewOpened += (sender, args) =>
{
    // A caixa de diálogo Visualizar impressão está aberta.
};

Browser.PrintPreviewClosed += (sender, args) =>
{
    // A caixa de diálogo Pré-visualização de impressão está fechada.
};
AddHandler Browser.PrintPreviewOpened, Sub(sender, args)
    ' A caixa de diálogo Visualizar impressão está aberta.
End Sub

AddHandler Browser.PrintPreviewClosed, Sub(sender, args)
    ' A caixa de diálogo Pré-visualização de impressão está fechada.
End Sub

Imprimir o conteúdo de forma programática

Para imprimir o conteúdo de forma programática e configurar as definições de impressão sem mostrar quaisquer caixas de diálogo, é necessário utilizar vários handlers.

Em primeiro lugar, é necessário registrar o RequestPrintHandler, tal como indicado no exemplo de código abaixo:

browser.RequestPrintHandler =
    new Handler<RequestPrintParameters, RequestPrintResponse>(p =>
    {
        return RequestPrintResponse.Print();
    });
browser.RequestPrintHandler = 
    New Handler(Of RequestPrintParameters, RequestPrintResponse)(Function(p)
        Return RequestPrintResponse.Print()
    End Function)

Quando se diz ao Chromium para efetuar a impressão de forma programática, ele utiliza PrintHtmlContentHandler ou PrintPdfContentHandler para determinar como o conteúdo deve ser impresso.

O handler que será invocado depende do conteúdo atual carregado no navegador - o PrintHtmlContentHandler será utilizado para páginas Web normais e o PrintPdfContentHandler será utilizado para imprimir os arquivos PDF.

Selecionar uma impressora

Os parâmetros para PrintHtmlContentHandler e PrintPdfContentHandler contêm a propriedade Printers - um conjunto de impressoras atualmente disponíveis para impressão. Por exemplo, eis como obter a impressora de que você necessita na implementação PrintHtmlContentHandler:

browser.PrintHtmlContentHandler 
    = new Handler<PrintHtmlContentParameters, PrintHtmlContentResponse>(p =>
    {
        // Obter a coleção das impressoras disponíveis.
        var printers = p.Printers;

        // Obter a impressora predefinida no ambiente.
        var defaultPrinter = printers.Default;

        // Obter a impressora PDF incorporada.
        var pdfPrinter = printers.Pdf;

        // Encontrar uma impressora pelo seu nome de dispositivo.
        var xpsPrinter = printers.FirstOrDefault(pr => pr.DeviceName.Contains("XPS"));

        // Imprimir o conteúdo utilizando a impressora específica.
        return PrintHtmlContentResponse.Print(xpsPrinter);
    });
browser.PrintHtmlContentHandler = 
    New Handler(Of PrintHtmlContentParameters, PrintHtmlContentResponse)(Function(p)
        ' Obter a coleção das impressoras disponíveis.
        Dim printers = p.Printers

        ' Obter a impressora predefinida no ambiente.
        Dim defaultPrinter = printers.Default

        ' Obter a impressora PDF incorporada.
        Dim pdfPrinter = printers.Pdf

        ' Procurar uma impressora pelo nome do dispositivo.
        Dim xpsPrinter = 
            printers.FirstOrDefault(Function(pr) pr.DeviceName.Contains("XPS"))

        ' Imprimir o conteúdo utilizando a impressora específica.
        Return PrintHtmlContentResponse.Print(xpsPrinter)
    End Function)

A resposta Print() nos handlers é utilizada para especificar a impressora a ser utilizada para a impressão.

Cada impressora tem as suas próprias capacidades, que incluem os tamanhos de papel, os modelos de cor e os modos duplex suportados pela impressora em questão. Por exemplo, eis como verificar se a impressora suporta A4:

bool a4Supported = xpsPrinter.Capabilities.PaperSizes.Contains(PaperSize.IsoA4);
Dim a4Supported As Boolean = xpsPrinter.Capabilities.PaperSizes.Contains(PaperSize.IsoA4)

Configurar definições de impressão

Cada impressora contém um PrintJob que representa a operação de impressão atual. As definições de impressão para a operação de impressão específica estão disponíveis como parte da tarefa de impressão. Eis como personalizar e aplicar as definições de impressão:

pdfPrinter.PrintJob.Settings.Apply((s) =>
{
    s.Orientation = Orientation.Landscape;
    s.PageRanges = new[] { new PageRange(2, 5) };
    s.PaperSize = PaperSize.IsoA4;
    s.PdfFilePath = pdfFilePath;
    // Outras definições.
});
pdfPrinter.PrintJob.Settings.Apply(Sub(s)
    s.Orientation = Orientation.Landscape
    s.PageRanges = { New PageRange(2, 5) }
    s.PaperSize = PaperSize.IsoA4
    s.PdfFilePath = pdfFilePath
    ' Outras configurações.
End Sub)

Durante a aplicação das definições de impressão, a apresentação da página é efetuada e o documento de pré-visualização da impressão que será posteriormente enviado para a impressora é gerado novamente. Consequentemente, a chamada Apply() pode demorar algum tempo a ser executada.

Se as definições aplicadas pela implementação do gestor não corresponderem às capacidades da impressora, uma exceção será lançada.

É necessário especificar o caminho totalmente qualificado através de PdfFilePath quando a impressora PDF incorporada é utilizada para impressão. Se o caminho não estiver especificado, a operação de impressão será cancelada.

Evento PageCountUpdated

Depois de concluída a apresentação da página, é ativado o evento PageCountUpdated, que fornece a contagem de páginas resultante. Eis como se inscrever neste evento para uma determinada impressora:

printer.PrintJob.PageCountUpdated += (s, e) => 
{
    int newPageCount = e.PageCount;
};
AddHandler printer.PrintJob.PageCountUpdated, Sub(s, e)
    Dim newPageCount As Integer = e.PageCount
End Sub

Evento PrintCompleted

Depois de a impressora ter sido selecionada para impressão através de PrintHtmlContentResponse.Print() ou PrintPdfContentResponse.Print(), o evento PrintCompleted é ativado para a respectiva tarefa de impressão assim que a operação de impressão estiver concluída. Eis como se inscrever neste evento:

printer.PrintJob.PrintCompleted += (s, e) => 
{
    var printJob = e.PrintJob;
    bool completed = e.IsCompletedSuccessfully;
};
AddHandler printer.PrintJob.PrintCompleted, Sub(s, e)
    Dim printJob = e.PrintJob
    Dim completed As Boolean = e.IsCompletedSuccessfully
End Sub

Imprimir página Web em PDF de forma programática

Eis o fragmento de código que demonstra a abordagem geral para imprimir a página Web em PDF de forma programática:

// Redimensiona o navegador para a dimensão necessária.
browser.Size = new Size(1024, 768);

// Carrega a página Web pretendida e aguarda até estar completamente carregada.
Console.WriteLine($"Carregando {url}");
browser.Navigation.LoadUrl(url).Wait();


// Configura os handlers de impressão.
browser.RequestPrintHandler =
    new Handler<RequestPrintParameters, RequestPrintResponse
    >(p => RequestPrintResponse.Print());

TaskCompletionSource<string> printCompletedTcs =
    new TaskCompletionSource<string>();
browser.PrintHtmlContentHandler
    = new Handler<PrintHtmlContentParameters, PrintHtmlContentResponse
    >(p =>
    {
        try
        {
            // Obter o trabalho de impressão para a impressora PDF incorporada.
            PdfPrinter<PdfPrinter.IHtmlSettings> pdfPrinter =
                p.Printers.Pdf;
            IPrintJob<PdfPrinter.IHtmlSettings> printJob =
                pdfPrinter.PrintJob;

            // Aplica as definições de impressão necessárias.
            printJob.Settings.Apply(s =>
            {
                IReadOnlyCollection<PaperSize> paperSizes =
                    pdfPrinter.Capabilities.PaperSizes;
                s.PaperSize =
                    paperSizes.First(size => size.Name.Contains("A4"));

                s.PrintingHeaderFooterEnabled = true;
                // Especifica o caminho para salvar o resultado.
                s.PdfFilePath = pdfFilePath;
            });

            string browserUrl = p.Browser.Url;
            printJob.PrintCompleted += (sender, args) =>
            {
                // Define o resultado da tarefa quando a impressão estiver concluída.
                printCompletedTcs.TrySetResult(browserUrl);
            };

            // Diz ao Chromium para usar a impressora PDF integrada
            // para impressão.
            return PrintHtmlContentResponse.Print(pdfPrinter);
        }
        catch (Exception e)
        {
            printCompletedTcs.TrySetException(e);
            throw;
        }
    });

// Inicia a impressão e aguarda até estar concluída.
Console.WriteLine("URL carregado. Iniciar impressão");
browser.MainFrame.Print();
string printedUrl = printCompletedTcs.Task.Result;
Console.WriteLine($"Impressão concluída para o URL: {printedUrl}");
' Redimensiona o navegador para a dimensão desejada.
browser.Size = New Size(1024, 768)

' Carrega a página Web pretendida e aguarda até estar completamente carregada.
Console.WriteLine($"Carregando {url}")
browser.Navigation.LoadUrl(url).Wait()

' Configura os manipuladores de impressão.
browser.RequestPrintHandler =
    New Handler(Of RequestPrintParameters, RequestPrintResponse )(
        Function(p) RequestPrintResponse.Print())

Dim printCompletedTcs As New TaskCompletionSource(Of String)()
browser.PrintHtmlContentHandler =
    New Handler(Of PrintHtmlContentParameters, PrintHtmlContentResponse )(
        Function(p)
            Try
                ' Obtem a tarefa de impressão para a impressora PDF incorporada.
                Dim pdfPrinter As PdfPrinter(Of PdfPrinter.IHtmlSettings) =
                        p.Printers.Pdf
                Dim printJob As IPrintJob(Of PdfPrinter.IHtmlSettings) =
                        pdfPrinter.PrintJob

                ' Aplica as definições de impressão necessárias.
                printJob.Settings.Apply(Sub(s)
                    Dim paperSizes As IReadOnlyCollection(Of PaperSize) =
                            pdfPrinter.Capabilities.PaperSizes
                    s.PaperSize = 
                        paperSizes.First(
                            Function(size) size.Name.Contains("A4"))

                    s.PrintingHeaderFooterEnabled = True
                    ' Especifica o caminho para salvar o resultado.
                    s.PdfFilePath = pdfFilePath
                End Sub)

                Dim browserUrl As String = p.Browser.Url
                AddHandler printJob.PrintCompleted, Sub(sender, args)
                    ' Define o resultado da tarefa quando a impressão estiver concluída.
                    printCompletedTcs.TrySetResult(browserUrl)
                End Sub

                ' Diz ao Chromium para utilizar a impressora PDF incorporada
                ' para imprimir.
                Return PrintHtmlContentResponse.Print(pdfPrinter)
            Catch e As Exception
                printCompletedTcs.TrySetException(e)
                Throw
            End Try
        End Function)

' Inicia a impressão e aguarda a sua conclusão.
Console.WriteLine("URL carregado. Iniciar impressão")
browser.MainFrame.Print()
Dim printedUrl As String = printCompletedTcs.Task.Result
Console.WriteLine($"Impressão concluída para o URL: {printedUrl}")
Go Top