如何从Web服务打印HTML文档?

86

我想从 C# Web 服务中打印 HTML。Web 浏览器控件过于复杂,在服务环境下无法很好地运行,而且在有严格安全限制的系统上也无法很好地运行。是否有任何一种免费的 .NET 库可以支持打印基本的 HTML 页面?以下是到目前为止我所拥有的代码,它无法正常运行。

public void PrintThing(string document)
{
    if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
    {
        Thread thread =
            new Thread((ThreadStart) delegate { PrintDocument(document); });
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
    }
    else
    {
        PrintDocument(document);
    }
}

protected void PrintDocument(string document)
{
    WebBrowser browser = new WebBrowser();
    browser.DocumentText = document;
    while (browser.ReadyState != WebBrowserReadyState.Complete)
    {
        Application.DoEvents();
    }
    browser.Print();
}

当从UI类型线程调用时,这可以正常工作,但从服务类型线程调用时没有任何反应。将Print()更改为 ShowPrintPreviewDialog() 会产生以下IE脚本错误:

Error: dialogArguments.___IE_PrintType为空或不是对象。

URL: res://ieframe.dll/preview.dlg

并且一个小的空打印预览对话框出现。


@mruanova 上次我尝试了所有的答案都不起作用。如果你有有效的方法,请告诉我们。 - Chris Marasti-Georg
我知道这在'08年被认为是一个好问题,但现在已经不相关了。 - Joshua
@Joshua 怎么了? - Chris Marasti-Georg
请参考以下链接:https://meta.stackoverflow.com/questions/251134/where-can-i-ask-about-finding-a-tool-library-or-favorite-off-site-resource - Joshua
7个回答

36

您可以使用以下命令从命令行打印:

rundll32.exe %WINDIR%\System32\mshtml.dll,PrintHTML "%1"

其中%1是要打印的HTML文件路径。

如果您不需要从内存打印(或者可以承担将其写入临时文件中的磁盘开销),可以使用以下方法:

using (Process printProcess = new Process())
{
    string systemPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
    printProcess.StartInfo.FileName = systemPath + @"\rundll32.exe";
    printProcess.StartInfo.Arguments = systemPath + @"\mshtml.dll,PrintHTML """ + fileToPrint + @"""";
    printProcess.Start();
}

注意:我认为这仅适用于Windows 2000及以上版本。


伟大的答案 - 我本来想将其标记为已接受,并运行我的测试。看来dll仍然会弹出打印对话框,而这是要作为无人看管的Windows服务运行,我们需要以某种方式绕过它。我已经基本用尽了Google,现在我已经快崩溃了。 - Chris Marasti-Georg
不幸的是出现了打印机对话框。我在 Windows 7 x64 上进行了测试。 - LukaszTaraszka

8

我知道Visual Studio本身(至少在2003版中)直接引用IE dll来渲染“设计视图”。

这可能值得研究。

否则,除了Web浏览器控件之外,我想不到任何其他的东西。


6

简单!将您的问题分成两部分:

  1. 将HTML渲染为PDF
  2. 打印PDF (SumatraPDF)
  • -print-to-default $file.pdf 在默认打印机上打印PDF文件
  • -print-to $printer_name $file.pdf 在指定的打印机上打印PDF

据我最近的检查,第二部分(通过Adobe命令行打印)在服务中无法工作 - 它需要用户交互。 - Chris Marasti-Georg
1
尝试使用Sumatra PDF,它要快得多。http://blog.kowalczyk.info/software/sumatrapdf/manual.html#manual-cmd-line - Colonel Panic
@ColonelPanic 哇,太棒了。我花了很长时间才找到一个可以从服务中使用的PDF阅读器,而且似乎SumatraPdf在商业软件中也可以使用。 - Nyerguds

4
如果您的预算有余 (~$3000),请查看PrinceXML。它可以将HTML渲染为PDF,适用于服务环境,并支持高级功能,例如不在表格单元格中间断开页面(许多浏览器目前不支持此功能)。

2
我非常喜欢使用的工具是HiQPdf。它的价格合理(从245美元起),可以将HTML渲染成PDF,并直接管理PDF文件的打印。 https://www.hiqpdf.com/

1

也许这可以帮到你。http://www.codeproject.com/KB/printing/printhml.aspx 另外,我不确定你是从哪个线程尝试访问浏览器控件,但它需要是STA。

注意 - 链接中提到的项目允许你导航到一个页面并执行打印而不显示打印对话框。


-2

我不知道具体的工具,但有些实用程序可以记录/回放点击。换句话说,您可以自动执行打印对话框中的“点击”操作。(我知道这是一种非正式的方法,但如果其他方法都失败了...)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接