【问题标题】:Best way to print for Windows Clients (Not Web Apps)?Windows 客户端(不是 Web 应用程序)的最佳打印方式?
【发布时间】:2010-09-27 03:34:26
【问题描述】:

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

问题是关于单页以及包含大量页面的报告。

如果能获得一份最常见的打印库列表,其中包含每个库的主要功能和陷阱,那就太好了。

请为标准 Windows 客户端(或服务器)提供[更新],不适用于 Web 应用程序。

【问题讨论】:

  • 您已经查看了多少 System.Drawing.Printing 命名空间?
  • 我查看了几种打印方式,但在深入研究一种方式之前,我想了解更多信息 - 选择错误的方式来了解更多信息是在浪费时间。

标签: c# .net printing


【解决方案1】:

对于报告,我使用 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 PAGE”事件(旨在一次打印 1 页)。然后,此事件使用 PrintPageEventArgs 的 Graphics 属性将相关字符串直接绘制到打印后台处理程序。

Here's one tutorial,然后在 Google 上快速搜索“.NET 打印教程”会返回超过 200K 的结果。

【讨论】:

  • 您能否进一步扩展固有的打印对象?
【解决方案2】:

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

  • 它似乎处于活动状态 发展。
  • 它有大部分 我们需要的功能。
  • 源代码 可用。虽然用了一些 我的模式和约定 以前没见过,一旦我上了 他们,很容易使 变化。我添加了对使用的支持 System.Drawing.Image 直接 而不是保存文件。
  • 它是 也没有很好的记录 内部或外部。

【讨论】:

    【解决方案3】:

    » 显示在 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
        }
    

    【讨论】:

      【解决方案4】:

      大量的东西,你说。嗯,看来您应该使用设计器的解决方案,因此您应该研究 Crystal Reports 和 RDLC。 还有 Reporting Services 解决方案,但在这种情况下,您需要一台带有 SQL Server 的服务器。

      Crystal Reports 似乎给了你更多的选择,但需要比 RDLC 多一点学习。

      我不建议您使用 HTML + CSS 来创建它们,因为这些限制和您必须投入的额外工作。

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

          即使它不是完美的工具(远非如此),Crystal Reports 也往往是一个不错的选择。 它使您可以选择直接从数据库中获取数据,或者,如果您已经有了要打印的对象列表,您可以将它们传递给文档并将对象属性绑定到报告的标签。

          但是请给我们更多关于您想要做什么的信息,以便您收到更好的建议。

          【讨论】:

          • 哦,好吧,我要打印大量的东西了:单页、长报告、粘性标签,说出它的名字,我必须(很快)打印出来。所以我想大致了解一下打印解决方案的正反。
          【解决方案7】:

          可以通过 Adob​​e Acrobat 打印

          我使用 System.Diagnostics.ProcessStartInfo 等标准库来使用 Adob​​e Acrobat 打印 pdf。最终用户不必与 Acrobat GUI 交互,但令人讨厌的是,以下代码仍将其拉到屏幕上几秒钟。

              // 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/MigraDoc 进行操作

          我没有将文档操作读入 OP,但我看到其他答案评论了这一事实。 2008-2012 年的一些 StackOverflow 问答(包括来自这个问题的@Robert Gowland)说 PDFSharp / MigraDoc 的文档很差。

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-09-17
            • 1970-01-01
            • 2010-10-02
            • 1970-01-01
            • 1970-01-01
            • 2021-09-24
            相关资源
            最近更新 更多