C# 为Windows客户端打印的最佳方式(不是Web应用)?

C# 为Windows客户端打印的最佳方式(不是Web应用)?,c#,.net,printing,C#,.net,Printing,从c#/.net打印内容的最佳方式是什么 问题在于单页以及包含多页的报告 如果能得到一个最常见的打印lib列表,其中包含每个lib的主要特性和要点,那就太好了 [更新]对于标准windows客户端(或服务器),请不要用于web应用。对于报告,我使用RDLC控件 对于其他所有内容,我使用.NET中固有的打印对象 编辑 固有的打印对象都位于System.Drawing.printing命名空间中。在WinForms(或WPF)应用程序中使用PrintDialog或PrintPreviewDialog

从c#/.net打印内容的最佳方式是什么

问题在于单页以及包含多页的报告

如果能得到一个最常见的打印lib列表,其中包含每个lib的主要特性和要点,那就太好了


[更新]对于标准windows客户端(或服务器),请不要用于web应用。

对于报告,我使用RDLC控件

对于其他所有内容,我使用.NET中固有的打印对象

编辑 固有的打印对象都位于System.Drawing.printing命名空间中。在WinForms(或WPF)应用程序中使用PrintDialog或PrintPreviewDialog时,要将控制权移交给这些对象

最基本的概念是,您正在向打印机绘图。最简单的形式是:

Sub MyMethod()
     Dim x as New PrintDocument
     AddHandler x.PrintPage, AddressOf printDoc_PrintPage
     x.Print
End Sub
Sub printDoc_PrintPage( sender as Object,  e as PrintPageEventArgs)
      Dim textToPrint as String= ".NET Printing is easy"
      dim printFont as new Font("Courier New", 12)
      dim leftMargin as int= e.MarginBounds.Left
      dim topMargin as int = e.MarginBounds.Top
      e.Graphics.DrawString(textToPrint, printFont, Brushes.Black, leftMargin, topMargin)
End Sub
这里发生的事情是,当我的对象(x)被发送print命令时,它会引发“printpage”事件(设计为一次打印一页)。然后,此事件使用PrintPageEventArgs的Graphics属性将相关字符串直接绘制到打印后台处理程序


,然后在谷歌上快速搜索“.NET打印教程”会返回20多万条结果。

这在很大程度上取决于应用程序的要求

尽管Crystal Reports不是一个完美的工具(事实上还远远不是),但它往往是一个不错的选择。 它提供了直接从数据库获取数据的选项,或者,如果已经有要打印的对象列表,则可以将它们传递到文档,并将对象属性绑定到报表的标签


但是,请给我们更多关于您正在尝试做的事情的信息,这样您就可以收到更好的建议。

我们使用了一组第三方DLL,他们反过来使用MigraDoc的DLL。我不知道我们朝这个方向发展的所有原因(这个决定是由一位高级开发人员做出的),但我可以告诉你:

  • 它似乎处于活动状态 发展
  • 它拥有大部分的资源 我们需要的功能
  • 源代码 有空。虽然它使用了一些 我喜欢的模式和惯例 以前没见过,一旦我上了 对他们来说,制作 变化。我添加了对使用 该系统直接使用.Drawing.Image 而不是保存文件
  • 是的 也没有很好的记录 内部或外部

    • 你说,有很多东西。嗯,看来你应该使用一个设计师的解决方案,所以你应该研究Crystal Reports和RDLC。 还有Reporting Services解决方案,但在这种情况下,您需要一台带有SQL server的服务器

      Crystal Reports似乎为您提供了更多选择,但需要比RDLC多一点学习


      我不建议您在HTML+CSS中创建这些内容,因为这些内容存在局限性,并且需要额外的工作。

      如果您可以将输出构建为,则可以轻松地将其转换为XPS,以获得“电子”版本,并打印XPS。

      »显示Windows窗体应用程序中打印基础知识的示例代码:

          using System.Drawing.Printing;
      
          PrintDocument printDoc = new PrintDocument();
          printDoc.DefaultPageSettings.Landscape = true;
          printDoc.DefaultPageSettings.Margins.Left = 100; //100 = 1 inch = 2.54 cm
          printDoc.DocumentName = "My Document Name"; //this can affect name of output PDF file if printer is a PDF printer
          //printDoc.PrinterSettings.PrinterName = "CutePDF";
          printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);
      
          PrintDialog printDialog = new PrintDialog();
          printDialog.Document = printDoc; //Document property must be set before ShowDialog()
      
          DialogResult dialogResult = printDialog.ShowDialog();
          if (dialogResult == DialogResult.OK)
          {
              printDoc.Print(); //start the print
          }   
      
          void printDoc_PrintPage(object sender, PrintPageEventArgs e)
          {
              Graphics g = e.Graphics;
              string textToPrint = ".NET Printing is easy";
              Font font = new Font("Courier New", 12);
              // e.PageBounds is total page size (does not consider margins)
              // e.MarginBounds is the portion of page inside margins
              int x1 = e.MarginBounds.Left;
              int y1 = e.MarginBounds.Top;
              int w = e.MarginBounds.Width;
              int h = e.MarginBounds.Height;
      
              g.DrawRectangle(Pens.Red, x1, y1, w, h); //draw a rectangle around the margins of the page, also we can use: g.DrawRectangle(Pens.Red, e.MarginBounds)
              g.DrawString(textToPrint, font, Brushes.Black, x1, y1);
      
              e.HasMorePages = false; //set to true to continue printing next page
          }
      
      可以通过Adobe Acrobat打印 我使用标准库,如System.Diagnostics.ProcessStartInfo,使用Adobe Acrobat打印pdf。最终用户将不必与AcrobatGUI交互,但令人烦恼的是,下面的代码仍然会在屏幕上显示几秒钟

          // Sample fileName = System.Environment.GetFolderPath(
          // System.Environment.SpecialFolder.CommonApplicationData)
          //  + @"\MyCompany\MyProject\TestPrint.pdf"
          private void SendPrintJob(string fileName)
          {
              try
              {
                 // Start by finding Acrobat from the Registry.
                 // This supposedly gets whichever you have of free or paid
                  string processFilename = Microsoft.Win32.Registry.LocalMachine
                       .OpenSubKey("Software")
                       .OpenSubKey("Microsoft")
                       .OpenSubKey("Windows")
                       .OpenSubKey("CurrentVersion")
                       .OpenSubKey("App Paths")
                       .OpenSubKey("AcroRd32.exe")
                       .GetValue(String.Empty).ToString();
      
                  ProcessStartInfo info = new ProcessStartInfo();
                  info.Verb = "print";
                  info.FileName = processFilename;
                  info.Arguments = String.Format("/p /h {0}", fileName);
                  info.CreateNoWindow = true;
                  info.WindowStyle = ProcessWindowStyle.Hidden;
                  info.UseShellExecute = false;
      
                  Process p = new Process();
                  p.StartInfo = info;
                  p.Start();
      
                  p.WaitForInputIdle();
      
                  // Recommended to add a time-out feature. Mine is coded here.
              }
              catch (Exception e)
              {
                  Console.WriteLine("Error sending print job. " + e.Message);
              }
      
      可以通过PDFSharp/doc进行操作 我没有在OP中读到文档操纵,但我看到其他答案对这一事实进行了评论。2008-2012年的一些StackOverflow Q&A(包括本问题中的@Robert Gowland)表示PDFSharp/MigraDoc的文档质量较差

      在2018年,我发现这是一个简单的学习曲线,有很多样本在现场。我今天早上读了这个问题,想知道如何打印图表,现在有一个按钮可以截屏并打印我的应用程序


      您需要转到NuGet软件包管理器,以获取
      PDFsharp MigraDocs
      (或
      PDFsharp MigraDocs WPF
      ,或
      PDFsharp MigraDocs GDI
      )。MigraDocs是一个高级组件,它可以从元素中创建文档,而不必考虑它们是pdf还是图像,或者您拥有什么。PDFSharp是一个组件,它可以帮助重新排列文档,将多个文档放在一个页面上,并将内容从一页拆分为两页。

      您可以进一步扩展固有的打印对象吗?哦,好吧,我有大量打印内容:单页、长报告、粘性标签,等等,我必须打印(很快). 因此,我想了解一下打印解决方案的概况。您对System.Drawing.printing名称空间已经了解了多少?我已经了解了几种打印方法,但在深入研究其中一种方法之前,我想了解更多-选择错误的方法来了解更多信息是浪费时间的。