【问题标题】:.net c# sending a file to the printer from a console application.net c# 从控制台应用程序向打印机发送文件
【发布时间】:2021-06-04 14:14:54
【问题描述】:

我正在 .Net Framework 4.8 中编写一个控制台应用程序,它将作为 Windows 服务运行。在此控制台应用程序中应该可以将文件发送到打印机(安装在与运行 Windows 服务的同一台电脑上)。但是,我发现这非常具有挑战性,并且还没有找到合适的解决方案。我无法控制电脑上安装的其他内容(例如 Adob​​e Acrobat Reader)。我已经尝试过的以下事情是:

  • 使用 .net 中的 PrintDocument 类(这似乎是为了创建需要在运行时打印的内容,而不是为现有文件创建内容)
  • 使用 System.Printing(这不能用于 Windows 服务,如其文档 here 中所述)
  • 使用带有动词“print”和“printto”的进程,如Stack overflow post 中所述
  • 我最终使用了this Nuget 包。例如,它适用于 .txt 和 .pdf 但不适用于 .docx 文件。我希望能够打印不同类型的文件。

我做错了什么?我认为这是直截了当的,但显然不是。这让我觉得我从错误的角度来看它。 是否有任何可用的示例或 Nuget 包来帮助我实现这一目标? 如果您需要任何其他信息,请询问我。

【问题讨论】:

  • 如何打印一个 .DOCX 文件而无需解释和呈现文件。您无法从服务 (theether.net/download/Microsoft/kb/288367.html) 运行 Word,因此您需要找到一些能够呈现文件的打印包。如果您从桌面“将文件发送到打印机”,则您正在激活该文件类型的默认应用程序并发送“打印”动词。如果您使用 DOCX 文件执行此操作,您将看到 Word 启动。但是,作为服务运行有很多注意事项(请参阅该知识库文章)。
  • 那么尝试将所有文​​件类型转换为 pdf 格式然后打印这些 pdf 格式是最安全的选择吗?
  • 实际上,如果您可以将内容转换为 XPS 格式 (en.wikipedia.org/wiki/Open_XML_Paper_Specification),您可能会稍微好一些。我相信 Windows 打印机驱动程序是基于 XPS 的

标签: c# .net file printing console-application


【解决方案1】:

听起来您需要一个库来支持通过 Windows 服务或控制台应用程序进行光栅化和渲染您感兴趣的各种文件格式。您可以查看Leadtools.Document.sdk nuget 包(请注意我是该供应商的员工)。

我继续组织了一个项目来测试它,它对我有用。我可以打印 sdk 支持的 150 多种文件格式中的任何一种。有关支持的文件格式的完整列表,请参阅here

这里是示例代码:

using (var document = DocumentFactory.LoadFromFile(@"filename.docx", new LoadDocumentOptions()))
    PrintDocument(document);

static void PrintDocument(LEADDocument document)
{
   using (var printDocument = new PrintDocument())
   {
      printDocument.PrinterSettings.MinimumPage = 1;
      printDocument.PrinterSettings.MaximumPage = document.Pages.Count;
      printDocument.PrinterSettings.FromPage = 1;
      printDocument.PrinterSettings.ToPage = document.Pages.Count;
      printDocument.PrinterSettings.PrinterName = "Adobe PDF";
      printDocument.DefaultPageSettings = new PageSettings();

      var pageNumber = printDocument.PrinterSettings.FromPage;

      printDocument.PrintPage += (object sender, PrintPageEventArgs e) => PrintPageHandler(e, document, printDocument, ref pageNumber);
      printDocument.Print();
   }
}

private static void PrintPageHandler(PrintPageEventArgs e, LEADDocument document, PrintDocument printDocument, ref int pageNumber)
{
   PrintPage(document, pageNumber, e);
   pageNumber++;

   e.HasMorePages = (pageNumber <= printDocument.PrinterSettings.ToPage);
   if (!e.HasMorePages)
      pageNumber = 1;
}

static void PrintPage(LEADDocument document, int pageNumber, PrintPageEventArgs e)
{
   var page = document.Pages[pageNumber - 1];

   // Get page size in pixels
   var pixelSize = page.SizeToPixels(page.Size);
   // Convert to DPI
   var size = LeadSizeD.Create(pixelSize.Width * 96.0 / page.Resolution, pixelSize.Height * 96.0 / page.Resolution).ToLeadSize();
   // Fit in the margin bounds
   var destRect = LeadRect.Create(e.MarginBounds.X, e.MarginBounds.Y, e.MarginBounds.Width, e.MarginBounds.Height);
   destRect = RasterImage.CalculatePaintModeRectangle(size.Width, size.Height, destRect, RasterPaintSizeMode.Fit, RasterPaintAlignMode.Center, RasterPaintAlignMode.Center);

   // Get the page image
   using (var rasterImage = page.GetImage())
   using (var bitmap = RasterImageConverter.ConvertToImage(rasterImage, ConvertToImageOptions.None))
      e.Graphics.DrawImage(bitmap, destRect.X, destRect.Y, destRect.Width, destRect.Height);
}

【讨论】:

【解决方案2】:

在比较了不同的打印库(和 pdf 操作)之后,我们选择了 Gembox.Pdf 来满足要求。这允许我们从 Windows 服务打印 pdf、png、jpg 等。

【讨论】:

  • 您现在对 Gembox.PDF 满意吗?
  • 是的,它符合我们的需求。我们唯一无法做的是将 pdf 转换为 azure 函数中的图像,因此我们需要使用变通方法。如果将来可以使用,我想获得更新:)
猜你喜欢
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 2012-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多