Intro
In this time, I try setting print settings and print WebView2.
- 【.NET 5】【WPF】【ClosedXML】Draw and print spreadsheets 1
- 【.NET 5】【WPF】Try MVVM
- 【.NET 5】【WPF】Try WebView2
Printer settings
I can set printing settings like paper size, etc. by "PrintTicket".
using System.Printing;
using System.Windows.Media;
using System.Windows.Xps;
namespace PrintSample.Prints
{
public class Printer: IPrinter
{
public void Print(Visual target)
{
LocalPrintServer printServer = new LocalPrintServer();
PrintQueue queue = printServer.GetPrintQueue("Microsoft Print to PDF");
PrintTicket ticket = queue.DefaultPrintTicket;
ticket.PageMediaSize = new PageMediaSize(200d, 300d);
// I can get defined paper sizes like "A3" by PageMediaSizeName
// ticket.PageMediaSize = new PageMediaSize(PageMediaSizeName.ISOA3);
ticket.CopyCount = 2;
ticket.PageResolution = new PageResolution(72, 72);
// Setting this value to Landscape reverses the "MediaSize" designation
ticket.PageOrientation = PageOrientation.Landscape;
// no margins
ticket.PageBorderless = PageBorderless.Borderless;
XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(queue);
writer.Write(target, ticket);
}
}
}
Print WebView2
Because I had been able to set a WebView2 instance as argument of XpsDocumentWriter.Write, I have thought I could print HTML of WebView2.
using System;
using System.Printing;
using System.Windows;
using System.Windows.Xps;
using Microsoft.Web.WebView2.Core;
namespace PdfPrintSample.Main
{
public partial class MainWindow : Window
{
public MainWindow(MainViewModel viewModel)
{
DataContext = viewModel;
InitializeComponent();
InitializeAsync();
webView.NavigationCompleted += NavigationCompleted;
}
private async void InitializeAsync()
{
await webView.EnsureCoreWebView2Async(null);
}
private async void NavigationCompleted(object? sender,
CoreWebView2NavigationCompletedEventArgs args)
{
LocalPrintServer printServer = new LocalPrintServer();
PrintQueue queue = printServer.GetPrintQueue("Microsoft Print to PDF");
XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(queue);
writer.Write(webView);
}
}
}
WPF
Printed
The HTML wasn't printed :(
Use DevTool of WebView2
One of the way to print HTML of WebView2 is taking screenshot by DevTool of WebView2.
using System;
using System.IO;
using System.Printing;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Windows.Xps;
using Microsoft.Web.WebView2.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
namespace PdfPrintSample.Main
{
public partial class MainWindow : Window
{
...
private async void NavigationCompleted(object? sender,
CoreWebView2NavigationCompletedEventArgs args)
{
string pic = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync("Page.captureScreenshot", "{}");
JObject o3 = JObject.Parse(pic);
JToken data = o3["data"]!;
byte[] bytes = Convert.FromBase64String(data.ToString());
Image image = new Image();
double picHeight = 0d;
double picWidth = 0d;
using(MemoryStream stream = new MemoryStream(bytes))
{
BitmapFrame bitmap = System.Windows.Media.Imaging.BitmapDecoder.Create(stream, BitmapCreateOptions.None,
BitmapCacheOption.OnLoad).Frames[0];
picHeight = bitmap.Height;
picWidth = bitmap.Width;
image.Source = bitmap;
}
LocalPrintServer printServer = new LocalPrintServer();
PrintQueue queue = printServer.GetPrintQueue("Microsoft Print to PDF");
PrintTicket ticket = queue.DefaultPrintTicket;
// must set PageMediaSize
ticket.PageMediaSize = new PageMediaSize(picWidth, picHeight);
XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(queue);
writer.Write(image, ticket);
}
}
}
- WebView2 DrawToBitmap returns only background · Issue #529 · MicrosoftEdge/WebView2Feedback · GitHub
- CoreWebView2.CallDevToolsProtocolMethodAsync(String, String) Method (Microsoft.Web.WebView2.Core) | Microsoft Docs
- C# Base64 String to JPEG Image - Stack Overflow
Set PageMediaSize
An important thing is I must set PageMediaSize because XpsDocumentWriter may not be able to get the image size.
So if I don't do this, the result like below.