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

Onl*_*ere 61 c# printing pdf .net-4.0 winforms

这是基本前提:

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

string filePath = "filepathisalreadysethere";
SendToPrinter(filePath); //Something like this?
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

我怎么做到这一点?

Edw*_*aal 61

您可以告诉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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • WaitForInputIdle()无效.看起来p在Start()之后处于空闲模式.只有睡眠3秒才允许Adobe完成假脱机.这可能是大型文档的问题. (2认同)
  • @user1027167 如果您需要打印多个文档,这尤其成问题@EdwinGroenendaal 如果要打印多个文档,您将如何进行?在命令 shell 中,可以将它们全部写在打印机名称之后:`print /D:printerName file1.pdf file2.pdf file3.pdf` (2认同)

Ken*_*ett 56

为此添加一个新的答案,因为在.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;
    }
}
Run Code Online (Sandbox Code Playgroud)


B.K*_*.K. 27

我知道标签说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);
}
Run Code Online (Sandbox Code Playgroud)

System.Printing如果还没有包含引用,请记住包含引用.现在,这种方法不适合ASP.NETWindows Service.它不应该Windows Forms像它一样使用System.Drawing.Printing.使用上面的代码我的PDF打印没有任何问题.

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

  • 这也适用于普通的控制台项目. (3认同)

use*_*167 9

这是一个略微修改的解决方案.该过程将在闲置至少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();
}
Run Code Online (Sandbox Code Playgroud)


小智 8

以下代码片段是Kendall Bennett使用PdfiumViewer库打印pdf文件代码的改编版.主要区别在于使用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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

在我的例子中,我使用名为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());
Run Code Online (Sandbox Code Playgroud)

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

  • PdfiumViewer
  • PdfiumViewer.Native.x86.v8-XFA


Rol*_*oCC 7

简单的方法:

var pi=new ProcessStartInfo("C:\file.docx");
pi.UseShellExecute = true;
pi.Verb = "print";
var process =  System.Diagnostics.Process.Start(pi);
Run Code Online (Sandbox Code Playgroud)

  • 为了定位特定的打印机,添加:`pi.Arguments = "PATH_TO_PRINTER"` 并使用 `pi.Verb = "PrintTo"` 而不是 `pi.Verb = "print"` (2认同)

Nei*_*eil 5

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