0

I decided to modernize our product and replace the old printer code with WINRT printing. In order to send something to the printer you need to call

printDoc.AddPage(printElement);

https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.printing.printdocument.addpages?view=windows-app-sdk-1.4

Note tht this method doesn't have overload that accept anything other than UIElement. This means if you want to print something with the new print API you need to obtain UIElement instance. XPS or PDF format are not supported.

To get a UIElement from a pdf file document, I used the WINRT and rasterized a pdf page to a BitmapSource like that

        private async Task<Microsoft.UI.Xaml.UIElement> GetPdfImage(uint pageNumber)
        {
            PdfPageRenderOptions options = new PdfPageRenderOptions();

            using PdfPage page = pdfDoc.GetPage(Math.Max(0, pageNumber - 1));

            InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();
            await page.RenderToStreamAsync(stream, options);
            BitmapImage src = new BitmapImage();



            await src.SetSourceAsync(stream);

            Microsoft.UI.Xaml.Controls.Image image = new Microsoft.UI.Xaml.Controls.Image();
            image.Source = src;
            image.Stretch = Microsoft.UI.Xaml.Media.Stretch.None;
            image.Width = (int)page.Size.Width;
            return image;
        }

As you can guess the printed text looks awful and blurry. The only way to be able to print high quality text is to pass XAML that looks like this

    <Grid x:Name="PrintableArea">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="3*"/>
            <RowDefinition Height="3*"/>
            <RowDefinition Height="4*"/>З
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="6*" />
            <ColumnDefinition Width="4*"/>
        </Grid.ColumnDefinitions>

        <StackPanel x:Name="Header" Grid.Row="0" Grid.ColumnSpan="2" Height="75"  Visibility="Collapsed">
            <StackPanel Orientation="Horizontal" >
                <Image Source="ms-appx:///Assets/smallTile-sdk.png" HorizontalAlignment="Left" Stretch="None"/>
                <RichTextBlock Foreground="Black"  FontSize="20" TextAlignment="Left" FontFamily="Segoe UI">
                    <Paragraph>Windows SDK Sample</Paragraph>
                </RichTextBlock>
            </StackPanel>
            <RichTextBlock Foreground="Black" x:Name="SdkTitle" FontSize="22" FontWeight="Bold" FontFamily="Segoe UI" >
                <Paragraph>PrintSample</Paragraph>
            </RichTextBlock>
        </StackPanel>

        <RichTextBlock Foreground="Black" x:Name="TextSelection" FontSize="18" Grid.Row="1"  Grid.ColumnSpan="2" OverflowContentTarget="{Binding ElementName=FirstLinkedContainer}"
            IsTextSelectionEnabled="True" TextAlignment="Left" FontFamily="Segoe UI" VerticalAlignment="Top" HorizontalAlignment="Left" Visibility="Collapsed"/>

        <RichTextBlock Foreground="Black" x:Name="TextContent" FontSize="18" Grid.Row="1"  Grid.ColumnSpan="2" OverflowContentTarget="{Binding ElementName=FirstLinkedContainer}"
            IsTextSelectionEnabled="True" TextAlignment="Left" FontFamily="Segoe UI" VerticalAlignment="Top" HorizontalAlignment="Left">
            <Paragraph FontSize="32">Lorem ipsum dolor sit amet, consectetur</Paragraph>
            <Paragraph></Paragraph>
            <Paragraph >...</Paragraph>
            <Paragraph></Paragraph>
            <Paragraph >...</Paragraph>
            <Paragraph></Paragraph>
            <Paragraph >...</Paragraph>
            <Paragraph></Paragraph>
            <Paragraph>... inceptos himenaeos.</Paragraph>
            <Paragraph></Paragraph>
            <Paragraph >...</Paragraph>
        </RichTextBlock>
        <RichTextBlockOverflow x:Name="FirstLinkedContainer" OverflowContentTarget="{Binding ElementName=ContinuationPageLinkedContainer}" Grid.Row="2" Grid.Column="0"/>
        <RichTextBlockOverflow x:Name="ContinuationPageLinkedContainer" Grid.Row="3" Grid.ColumnSpan="2"/>
        <Image Source="ms-appx:///Assets/print_1.png" x:Name="ScenarioImage" HorizontalAlignment="Center" Grid.Row="2" Grid.Column="1" Margin="10"/>

        <StackPanel x:Name="Footer" Grid.Row="4" Grid.ColumnSpan="2">
            <TextBlock Foreground="Black" FontSize="16" TextAlignment="Left" FontFamily="Segoe UI">
                Copyright © Microsoft Corporation. All rights reserved.
            </TextBlock>
        </StackPanel>
    </Grid>
</Page>

My question is - am I do something wrong or the only way to print PDF, XPS with WinRT print API is to convert it to XAML?

7
  • Yes, PrintDocument can only print UIElement currently. Could you please tell me what is your need, is it just to simply print a document? Do you need to edit the document in Winui3? Commented Apr 23, 2024 at 6:05
  • We have multiple apps that are similar to MS Office. They can read and write docx, excel files, pdf and etc. So far we used old windows API and convert them to XPS to send it to the printer. With WinRT I don't see how we can print them. Converting them to bitmap is not an option. The print looks awful. Commented Apr 23, 2024 at 15:28
  • What "old windows API" exactly did you use? Why is it working anymore? Commented Apr 23, 2024 at 17:19
  • 1
    XPS and PDF are very different. You can create a non-XAML print document but it's not that easy. I've created some sample code here github.com/smourier/XpsPrintSamples The CustomPrintDocument demonstrates the custom non-XAML way and by default should output better quality prints. Commented Apr 29, 2024 at 18:51
  • 1
    Thanks you @Simon Mourier. This is so useful!!! Commented Apr 14 at 11:30

1 Answer 1

0

There is a great sample posted by Simon Mourier in the comment section that contains the answer https://github.com/smourier/XpsPrintSamples

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.