Pregunta Imprimir un FlowDocument de WPF


Estoy construyendo una aplicación de demostración en WPF, que es nueva para mí. Actualmente estoy mostrando texto en un FlowDocument y necesito imprimirlo.

El código que estoy usando se ve así:

        PrintDialog pd = new PrintDialog();
        fd.PageHeight = pd.PrintableAreaHeight;
        fd.PageWidth = pd.PrintableAreaWidth;
        fd.PagePadding = new Thickness(50);
        fd.ColumnGap = 0;
        fd.ColumnWidth = pd.PrintableAreaWidth;

        IDocumentPaginatorSource dps = fd;
        pd.PrintDocument(dps.DocumentPaginator, "flow doc");

fd es mi FlowDocument, y por ahora estoy usando la impresora predeterminada en lugar de permitir que el usuario especifique las opciones de impresión. Funciona bien, excepto que después de que se imprime el documento, el FlowDocument que se muestra en la pantalla ha cambiado a para usar la configuración que especifiqué para imprimir.

Puedo solucionar esto restableciendo manualmente todo después de imprimir, pero ¿es esta la mejor manera? ¿Debo hacer una copia del FlowDocument antes de imprimirlo? ¿O hay otro enfoque que debería considerar?


32
2017-12-05 20:22


origen


Respuestas:


sí, haga una copia del FlowDocument antes de imprimirlo. Esto se debe a que la paginación y los márgenes serán diferentes. Esto funciona para mí

    private void DoThePrint(System.Windows.Documents.FlowDocument document)
    {
        // Clone the source document's content into a new FlowDocument.
        // This is because the pagination for the printer needs to be
        // done differently than the pagination for the displayed page.
        // We print the copy, rather that the original FlowDocument.
        System.IO.MemoryStream s = new System.IO.MemoryStream();
        TextRange source = new TextRange(document.ContentStart, document.ContentEnd);
        source.Save(s, DataFormats.Xaml);
        FlowDocument copy = new FlowDocument();
        TextRange dest = new TextRange(copy.ContentStart, copy.ContentEnd);
        dest.Load(s, DataFormats.Xaml);

        // Create a XpsDocumentWriter object, implicitly opening a Windows common print dialog,
        // and allowing the user to select a printer.

        // get information about the dimensions of the seleted printer+media.
        System.Printing.PrintDocumentImageableArea ia = null;
        System.Windows.Xps.XpsDocumentWriter docWriter = System.Printing.PrintQueue.CreateXpsDocumentWriter(ref ia);

        if (docWriter != null && ia != null)
        {
            DocumentPaginator paginator = ((IDocumentPaginatorSource)copy).DocumentPaginator;

            // Change the PageSize and PagePadding for the document to match the CanvasSize for the printer device.
            paginator.PageSize = new Size(ia.MediaSizeWidth, ia.MediaSizeHeight);
            Thickness t = new Thickness(72);  // copy.PagePadding;
            copy.PagePadding = new Thickness(
                             Math.Max(ia.OriginWidth, t.Left),
                               Math.Max(ia.OriginHeight, t.Top),
                               Math.Max(ia.MediaSizeWidth - (ia.OriginWidth + ia.ExtentWidth), t.Right),
                               Math.Max(ia.MediaSizeHeight - (ia.OriginHeight + ia.ExtentHeight), t.Bottom));

            copy.ColumnWidth = double.PositiveInfinity;
            //copy.PageWidth = 528; // allow the page to be the natural with of the output device

            // Send content to the printer.
            docWriter.Write(paginator);
        }

    }

35
2018-05-12 15:44



Puede usar el código de la siguiente URL, envuelve el documento de flujo en un documento fijo e imprime eso, la gran ventaja es que puede usarlo para agregar márgenes, encabezados y pies de página.

http://blogs.msdn.com/fyuan/archive/2007/03/10/convert-xaml-flow-document-to-xps-with-style-multiple-page-page-size-header-margin.aspx


7
2017-12-09 15:45



Lo siguiente funciona con visuales de texto y sin texto:

//Clone the source document
var str = XamlWriter.Save(FlowDoc);
var stringReader = new System.IO.StringReader(str);
var xmlReader = XmlReader.Create(stringReader);
var CloneDoc = XamlReader.Load(xmlReader) as FlowDocument;

//Now print using PrintDialog
var pd = new PrintDialog();

if (pd.ShowDialog().Value)
{
  CloneDoc.PageHeight = pd.PrintableAreaHeight;
  CloneDoc.PageWidth = pd.PrintableAreaWidth;
  IDocumentPaginatorSource idocument = CloneDoc as IDocumentPaginatorSource;

  pd.PrintDocument(idocument.DocumentPaginator, "Printing FlowDocument");
}

1
2017-11-22 15:25



También estoy generando un informe de WPF a partir de un documento de flujo, pero estoy utilizando deliberadamente el documento de flujo como una pantalla de vista previa de impresión. Quiero que los márgenes sean los mismos. Puedes leer sobre como lo hice aquí.

En su escenario, estoy pensando por qué no solo hago una copia de su configuración, en lugar de todo el documento de flujo. Luego puede volver a aplicar la configuración si desea devolver el documento a su estado original.


0
2018-05-01 19:26