gpt4 book ai didi

c# - 使用 WPF 在 C# 中静默打印 HTML 文件

转载 作者:太空狗 更新时间:2023-10-30 00:40:19 24 4
gpt4 key购买 nike

编辑:完全重写了问题并增加了赏金。

基于许多教程和 stackoverflow 问题,我现在可以:

  • 将多页打印成一个文档。
  • 打印实际内容。
  • 在页面上正确对齐内容。
  • 打印正确尺寸的文档。

该解决方案要求 HTML 文档底部有一些空白和样式标签 html{ overflow:hidden; } - 隐藏滚动条并允许滚动用于分页 - 但我可以接受这一点。

唯一剩下的问题是 WPF 不呈现 web 浏览器中屏幕外的部分。

这意味着,如果我倾斜我的电脑屏幕,我可以正确打印,但如果我不这样做,文档会切断下半部分。

我尝试渲染成位图,但是当我打印生成的图像作为我的视觉效果时,页面是空的。

如果您知道如何强制 WPF 完全呈现或如何正确呈现位图,请帮助我。

打印窗口 XAML:(打印 WPF 仅适用于 UI 线程,否则不呈现任何内容...)

<Window x:Class="CardLoader2000.PrintWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PrintWindow" Height="1139" Width="820">
<Grid x:Name="grid">
<!--The alignment and size of the webbrowser is reflected in the print. If larger than document
it will be cut. The width here corresponds to A4 paper width with a little margin-->
<WebBrowser x:Name="webBrowser" Height="1089" Width="770" VerticalAlignment="Top" Margin="0,10,0,0"/>
</Grid>
</Window>

打印窗口代码隐藏:

public partial class PrintWindow : Window
{
public PrintWindow(string path)
{
InitializeComponent();

FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);

webBrowser.NavigateToStream(fs);

ContentRendered += OnContentRendered;
}

private void OnContentRendered(object sender, EventArgs eventArgs)
{
PrintDialog pd = new PrintDialog
{
PrintTicket = new PrintTicket
{
Duplexing = Duplexing.TwoSidedLongEdge,
OutputColor = OutputColor.Monochrome,
PageOrientation = PageOrientation.Portrait,
PageMediaSize = new PageMediaSize(794, 1122),
InputBin = InputBin.AutoSelect
}
};

//Ok, final TODO: Page only renders what is on the PC screen...
WebPaginator paginator = new WebPaginator(webBrowser, 1089, 1122, 794);

pd.PrintDocument(paginator, "CustomerLetter");

Close();
}
}

自定义分页器:

public class WebPaginator : DocumentPaginator
{
private readonly WebBrowser webBrowser;
private readonly int pageScroll;
private Size pageSize;

public WebPaginator(WebBrowser webBrowser, int pageScroll, double pageHeight, double pageWidth)
{
this.webBrowser = webBrowser;
this.pageScroll = pageScroll;
pageSize = new Size(pageWidth, pageHeight);
}

public override DocumentPage GetPage(int pageNumber)
{
HTMLDocument htmlDoc = webBrowser.Document as HTMLDocument;
if (htmlDoc != null) htmlDoc.parentWindow.scrollTo(0, pageScroll * pageNumber);
Rect area = new Rect(pageSize);

return new DocumentPage(webBrowser, pageSize, area, area);
}

public override bool IsPageCountValid
{
get { return true; }
}

/// <summary>
/// Returns one less than actual length.
/// Last page should be whitespace, used for scrolling.
/// </summary>
public override int PageCount
{
get
{
var doc = (IHTMLDocument2)webBrowser.Document;
var height = ((IHTMLElement2)doc.body).scrollHeight;
int tempVal = height*10/pageScroll;
tempVal = tempVal%10 == 0
? Math.Max(height/pageScroll, 1)
: height/pageScroll + 1;
return tempVal > 1 ? tempVal-1 : tempVal;
}
}

public override Size PageSize
{
get
{
return pageSize;
}
set
{
pageSize = value;
}
}

/// <summary>
/// Can be null.
/// </summary>
public override IDocumentPaginatorSource Source
{
get
{
return null;
}
}
}

最佳答案

您可以使用标准 IE 的打印功能(通过 ExecWB method ),如下所示:

public partial class PrintWindow : Window
{
public PrintWindow()
{
InitializeComponent();
webBrowser.Navigate("http://www.google.com");
}

// I have added a button to demonstrate
private void Button_Click(object sender, RoutedEventArgs e)
{
// NOTE: this works only when the document as been loaded
IOleServiceProvider sp = webBrowser.Document as IOleServiceProvider;
if (sp != null)
{
Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E");
const int OLECMDID_PRINT = 6;
const int OLECMDEXECOPT_DONTPROMPTUSER = 2;

dynamic wb; // will be of IWebBrowser2 type, but dynamic is cool
sp.QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, out wb);
if (wb != null)
{
// note: this will send to the default printer, if any
wb.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, null, null);
}
}
}

[ComImport, Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IOleServiceProvider
{
[PreserveSig]
int QueryService([MarshalAs(UnmanagedType.LPStruct)] Guid guidService, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object ppvObject);
}
}

关于c# - 使用 WPF 在 C# 中静默打印 HTML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28889315/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com