首页 文章

如何将文件文档发送到打印机并打印?

提问于
浏览
58

这是基本前提:

我的用户点击了一些小玩意,一个PDF文件被吐出到他的桌面 . 我有办法将此文件发送到打印机队列并将其打印到本地连接的打印机吗?

string filePath = "filepathisalreadysethere";
SendToPrinter(filePath); //Something like this?

他会多次这样做 . 对于教室里的每个学生,他必须打印一张小型成绩单 . 所以我为每个学生生成一个PDF,我想自动化打印过程,而不是让用户生成pdf,打印,生成pdf,打印,生成pdf,打印 .

有关如何处理此问题的任何建议?我在Windows XP上使用Windows Forms .NET 4运行 .

我发现这个StackOverflow问题,其中接受的答案表明:

创建文件后,可以通过命令行打印它们(可以使用System.Diagnostics命名空间中的Command类)

我怎么做到这一点?

11 回答

  • 2

    您可以告诉Acrobat Reader使用(就像这里已经提到的那样)'print'动词来打印文件 . 此后,您还需要以编程方式关闭Acrobat Reader:

    private void SendToPrinter()
    {
       ProcessStartInfo info = new ProcessStartInfo();
       info.Verb = "print";
       info.FileName = @"c:\output.pdf";
       info.CreateNoWindow = true;
       info.WindowStyle = ProcessWindowStyle.Hidden;
    
       Process p = new Process();
       p.StartInfo = info;
       p.Start();
    
       p.WaitForInputIdle();
       System.Threading.Thread.Sleep(3000);
       if (false == p.CloseMainWindow())
          p.Kill();
    }
    

    这将打开Acrobat Reader并告诉它将PDF发送到默认打印机,然后在三秒钟后关闭Acrobat .

    如果您愿意使用您的应用程序发布其他产品,那么您可以使用GhostScript(免费)或命令行PDF打印机,如http://www.commandlinepdf.com/(商业) .

    Note: 示例代码在注册的应用程序当前打开PDF以打印PDF,这是大多数人的机器上的Adobe Acrobat Reader . 但是,它们可能使用不同的PDF查看器,例如Foxit(http://www.foxitsoftware.com/pdf/reader/) . 但是,示例代码仍然可以正常工作 .

  • 9

    为此添加一个新的答案,因为在.net中打印PDF的问题已经存在了很长时间,并且大部分答案都早于Google Pdfium库,它现在有一个.net包装器 . 对我来说,我自己正在研究这个问题并且一直空白,试图做出像产生Acrobat或其他PDF阅读器这样的hacky解决方案,或者遇到价格昂贵但没有非常兼容的许可条款的商业库 . 但是Google Pdfium库和PdfiumViewer .net包装器是开源的,所以对于很多开发人员来说都是一个很好的解决方案,包括我自己 . PdfiumViewer根据Apache 2.0许可证授权 .

    你可以在这里获得NuGet包:

    https://www.nuget.org/packages/PdfiumViewer/

    你可以在这里找到源代码:

    https://github.com/pvginkel/PdfiumViewer

    这是一些简单的代码,可以从它的文件名中静默打印任意数量的PDF文件 . 您也可以从流中加载PDF(这是我们通常的做法),您可以轻松地查看代码或示例 . 还有一个WinForm PDF文件视图,因此您还可以将PDF文件渲染到视图中或对其进行打印预览 . 对我们来说,我只需要一种方法,可以根据需要以静默方式将PDF文件打印到特定的打印机 .

    public bool PrintPDF(
        string printer,
        string paperName,
        string filename,
        int copies)
    {
        try {
            // Create the printer settings for our printer
            var printerSettings = new PrinterSettings {
                PrinterName = printer,
                Copies = (short)copies,
            };
    
            // Create our page settings for the paper size selected
            var pageSettings = new PageSettings(printerSettings) {
                Margins = new Margins(0, 0, 0, 0),
            };
            foreach (PaperSize paperSize in printerSettings.PaperSizes) {
                if (paperSize.PaperName == paperName) {
                    pageSettings.PaperSize = paperSize;
                    break;
                }
            }
    
            // Now print the PDF document
            using (var document = PdfDocument.Load(filename)) {
                using (var printDocument = document.CreatePrintDocument()) {
                    printDocument.PrinterSettings = printerSettings;
                    printDocument.DefaultPageSettings = pageSettings;
                    printDocument.PrintController = new StandardPrintController();
                    printDocument.Print();
                }
            }
            return true;
        } catch {
            return false;
        }
    }
    
  • 3

    我知道标签说 Windows Forms ...但是,如果有人对 WPF 应用方法感兴趣, System.Printing 就像一个魅力 .

    var file = File.ReadAllBytes(pdfFilePath);
    var printQueue = LocalPrintServer.GetDefaultPrintQueue();
    
    using (var job = printQueue.AddJob())
    using (var stream = job.JobStream)
    {
        stream.Write(file, 0, file.Length);
    }
    

    请记住包含 System.Printing 引用,如果它尚未包含在内 . 现在,此方法与 ASP.NETWindows Service 不兼容 . 它不应该与 Windows Forms 一起使用,因为它有 System.Drawing.Printing . 使用上面的代码我的PDF打印没有任何问题 .

    但是,我应该提一下,如果您的打印机不支持PDF文件格式的直接打印,那么您对此方法不满意 .

  • 25

    这是一个略微修改的解决方案 . 该过程将在闲置至少1秒后被杀死 . 也许你应该添加X秒的时间并从一个单独的线程调用该函数 .

    private void SendToPrinter()
    {
      ProcessStartInfo info = new ProcessStartInfo();
      info.Verb = "print";
      info.FileName = @"c:\output.pdf";
      info.CreateNoWindow = true;
      info.WindowStyle = ProcessWindowStyle.Hidden;
    
      Process p = new Process();
      p.StartInfo = info;
      p.Start();
    
      long ticks = -1;
      while (ticks != p.TotalProcessorTime.Ticks)
      {
        ticks = p.TotalProcessorTime.Ticks;
        Thread.Sleep(1000);
      }
    
      if (false == p.CloseMainWindow())
        p.Kill();
    }
    
  • 2

    以下代码片段是使用PdfiumViewer库打印pdf文件的Kendall Bennett's代码的改编 . 主要区别在于使用Stream而不是文件 .

    public bool PrintPDF(
        string printer,
        string paperName,
        int copies, Stream stream)
            {
                try
                {
                    // Create the printer settings for our printer
                    var printerSettings = new PrinterSettings
                    {
                        PrinterName = printer,
                        Copies = (short)copies,
                    };
    
                // Create our page settings for the paper size selected
                var pageSettings = new PageSettings(printerSettings)
                {
                    Margins = new Margins(0, 0, 0, 0),
                };
                foreach (PaperSize paperSize in printerSettings.PaperSizes)
                {
                    if (paperSize.PaperName == paperName)
                    {
                        pageSettings.PaperSize = paperSize;
                        break;
                    }
                }
    
                // Now print the PDF document
                using (var document = PdfiumViewer.PdfDocument.Load(stream))
                {
                    using (var printDocument = document.CreatePrintDocument())
                    {
                        printDocument.PrinterSettings = printerSettings;
                        printDocument.DefaultPageSettings = pageSettings;
                        printDocument.PrintController = new StandardPrintController();
                        printDocument.Print();
                    }
                }
                return true;
            }
            catch (System.Exception e)
            {
                return false;
            }
        }
    

    在我的情况下,我使用名为PdfSharp的库生成PDF文件,然后将文档保存到Stream,如下所示:

    PdfDocument pdf = PdfGenerator.GeneratePdf(printRequest.html, PageSize.A4);
            pdf.AddPage();
    
            MemoryStream stream = new MemoryStream();
            pdf.Save(stream);
            MemoryStream stream2 = new MemoryStream(stream.ToArray());
    

    我想指出的一件事可能对其他开发人员有帮助,我必须安装32位版本的pdfuim本机dll才能使打印工作,即使我运行的是Windows 10 64位 . 我在Visual Studio中使用NuGet包管理器安装了以下两个NuGet包:

    • PdfiumViewer

    • PdfiumViewer.Native.x86.v8-xfa

  • 42

    System.Diagnostics.Process.Start可用于打印文档 . 将UseShellExecute设置为True并将动词设置为"print" .

  • 2

    您可以像在这篇文章中一样尝试使用GhostScript:

    How to print PDF on default network printer using GhostScript (gswin32c.exe) shell command

  • 4

    简单的方法:

    var pi=new ProcessStartInfo("C:\file.docx");
    pi.UseShellExecute = true;
    pi.Verb = "print";
    var process =  System.Diagnostics.Process.Start(pi);
    
  • 2

    这是一个迟到的答案,但您也可以使用System.IO命名空间的File.Copy方法将文件发送到打印机:

    System.IO.File.Copy(filename, printerName);
    

    这很好用

  • 0

    我知道埃德温在上面回答了这个问题,但他只打印了一份文件 . 我使用此代码打印给定目录中的所有文件 .

    public void PrintAllFiles()
    {
        System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo();
        info.Verb = "print";
        System.Diagnostics.Process p = new System.Diagnostics.Process();
        //Load Files in Selected Folder
        string[] allFiles = System.IO.Directory.GetFiles(Directory);
        foreach (string file in allFiles)
        {
            info.FileName = @file;
            info.CreateNoWindow = true;
            info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
             p.StartInfo = info;
            p.Start();
        }
        //p.Kill(); Can Create A Kill Statement Here... but I found I don't need one
        MessageBox.Show("Print Complete");
    }
    

    它几乎是循环的通过给定目录变量Directory中的每个文件 - >对我来说它是@ "C:\Users\Owner\Documents\SalesVaultTesting"并将这些文件打印到 default printer .

  • 57

    您可以使用DevExpress PdfDocumentProcessor.Print(PdfPrinterSettings)方法 .

    public void Print(string pdfFilePath)
    {
          if (!File.Exists(pdfFilePath))
              throw new FileNotFoundException("No such file exists!", pdfFilePath);
    
          // Create a Pdf Document Processor instance and load a PDF into it.
          PdfDocumentProcessor documentProcessor = new PdfDocumentProcessor();
          documentProcessor.LoadDocument(pdfFilePath);
    
          if (documentProcessor != null)
          {
              PrinterSettings settings = new PrinterSettings();
    
              //var paperSizes = settings.PaperSizes.Cast<PaperSize>().ToList();
              //PaperSize sizeCustom = paperSizes.FirstOrDefault<PaperSize>(size => size.Kind == PaperKind.Custom); // finding paper size
    
              settings.DefaultPageSettings.PaperSize = new PaperSize("Label", 400, 600);
    
              // Print pdf
              documentProcessor.Print(settings);
          }
    }
    

相关问题