首先,快速描述最终目标:
我正在构建一个跨平台、基于 .NET Core 的打印应用程序。此应用程序将能够使用自定义页面设置打印各种文件类型,例如页眉、页脚和页边距。一个关键特性是它支持多页向上(例如,一张横向纸与两个并排呈现的纵向页面......称为“2up”)。
打印 HTML 很重要,不仅因为打印 HTML,而且我想将所有基于 HTML 的出色语法高亮用于源代码(例如 www.prismjs.com)。
该应用程序基本上完成了,但有一个主要问题:我无法让 HTML 渲染得足够好。到目前为止,我已经实现了源代码打印三种方式:
1) 使用我自己的行号和换行引擎作为纯文本。这对于我可以扔给它的所有东西都非常有效,但它不支持语法突出显示。2) 使用Html-Renderer
( https://github.com/ArthurHub/HTML-Renderer/issues ) 一个基于 OSS .NET 的 Html 渲染器。这个实现是最弱的,因为 Html-Renderer 的 CSS 支持真的很弱。它几乎prismjs
无法highlightjs' generate.
3) Using
通过LiteHtmlSharp
. 这是非常有前途的,我几乎可以让它与一些主要的黑客一起工作,但litehtml
也不支持关键的、现代的、HTML/CSS 特性。
既不也不Html-Renderer
支持litehtml
CSSpage-break-before
功能,当与它结合使用时,media print
我可以确保行不会在页面之间拆分。
我真正想要使用的是 Chromium 渲染引擎。litehtml
为这类问题提供了一个很棒的 API:它在需要渲染时调用我,我使用 GDI+ 绘制(文本、表格边框、图像等)。我的梦想是在 Chromium(CEF、Puppeteer、???)中找到提供类似 API 的东西。
或者,另一种选择,一个 API 可以让我传入 GDI+ 图形(或 HDC),然后渲染器将渲染到该表面。
用Html-Renderer
我测量计算 # 个这样的页面。
SizeF size = HtmlRender.MeasureGdiPlus(g, html, containingSheet.GetPageWidth());
int numPages = (int)(size.Height / containingSheet.GetPageHeight());
我的页面渲染代码(例如OnPaint
)如下所示:
SizeF size = new SizeF(containingSheet.GetPageWidth(), containingSheet.GetPageHeight());
HtmlRender.RenderGdiPlus(g, html, PointF(0, 0), size );
代码htmllite
如下OnPaint
所示:
// Set the clip such that any extraLines are clipped off bottom
g.SetClip(new Rectangle(0, 0, (int)Math.Round(PageSize.Width), (int)Math.Round(PageSize.Height - remainingPartialLineHeight)));
LiteHtmlSize size = new LiteHtmlSize(Math.Round(PageSize.Width), Math.Ceiling(PageSize.Height));
litehtml.Document.Draw((int)-0, (int)-yPos, new position {
x = 0,
y = 0,
width = (int)size.Width,
height = (int)size.Height
});
在这种情况下,调用会litehtml.Document.Draw
导致我的应用程序中出现一堆回调,我使用与调用相同Graphics
的方法来处理这些回调OnPaint
。
大多数关于 CEF 和 Chromium 的讨论都指向ScreenshotAsync
等……因为我需要渲染到 PRINTERS HDC(或 GDI+)并且位图会降低质量,所以不会这样做。
我已经倾注了 Chromium 源代码,但我找不到对 CEF/Chromium 说“将第 1 页(定义为高度/宽度)渲染到此 GDI+ 图形对象”然后“渲染第 2 页......”等的明显方式...打印支持(以及如何集成 pdfium!)。
Chromium 问题311308表明我已经被水洗了,直到重新开始这项工作。
注意:我在我的应用程序中拥有完全访问权限nodejs
。我已经构建了一个 dotnet/nodejs 桥,这就是我如何通过 prismjs 将源代码文件的原始文本文件转换为格式丰富、行编号、语法突出显示的 html。puppeteer
这意味着如果我能找出正确的 API,我就可以轻松使用/Headless Chrome。
有没有人有可能有帮助的建议?如果不是大心脏手术,我愿意为 Chromium 做出贡献。