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

发布于 2024-11-08 22:18:48 字数 673 浏览 0 评论 0原文

基本前提如下:

我的用户单击一些小玩意,然后一个 PDF 文件就会出现在他的桌面上。有什么方法可以让我将此文件发送到打印机队列并将其打印到本地连接的打印机吗?

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

他会多次执行这个过程。他必须为教室里的每个学生打印一张小成绩单。因此,我为每个学生生成一个 PDF,我希望自动化打印过程,而不是让用户生成 pdf、打印、生成 pdf、打印、生成 pdf、打印。

关于如何解决这个问题有什么建议吗?我在带有 Windows Forms .NET 4 的 Windows XP 上运行。

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

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

我将如何完成这个?

Here's the basic premise:

My user clicks some gizmos and a PDF file is spit out to his desktop. Is there some way for me to send this file to the printer queue and have it print to the locally connected printer?

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

He will do this process many times. For each student in a classroom he has to print a small report card. So I generate a PDF for each student, and I'd like to automate the printing process instead of having the user generated pdf, print, generate pdf, print, generate pdf, print.

Any suggestions on how to approach this? I'm running on Windows XP with Windows Forms .NET 4.

I've found this StackOverflow question where the accepted answer suggests:

Once you have created your files, you
can print them via a command line (you
can using the Command class found in
the System.Diagnostics namespace for
that)

How would I accomplish this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

迷离° 2024-11-15 22:18:48

对此添加一个新的答案,因为在 .net 中打印 PDF 的问题已经存在很长时间了,并且大多数答案早于 Google Pdfium 库,该库现在有一个 .net 包装器。对我来说,我自己正在研究这个问题,但一直一片空白,尝试做一些黑客解决方案,例如生成 Acrobat 或其他 PDF 阅读器,或者遇到昂贵且许可条款不太兼容的商业库。但 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;
    }
}

Adding a new answer to this as the question of printing PDF's in .net has been around for a long time and most of the answers pre-date the Google Pdfium library, which now has a .net wrapper. For me I was researching this problem myself and kept coming up blank, trying to do hacky solutions like spawning Acrobat or other PDF readers, or running into commercial libraries that are expensive and have not very compatible licensing terms. But the Google Pdfium library and the PdfiumViewer .net wrapper are Open Source so are a great solution for a lot of developers, myself included. PdfiumViewer is licensed under the Apache 2.0 license.

You can get the NuGet package here:

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

and you can find the source code here:

https://github.com/pvginkel/PdfiumViewer

Here is some simple code that will silently print any number of copies of a PDF file from it's filename. You can load PDF's from a stream also (which is how we normally do it), and you can easily figure that out looking at the code or examples. There is also a WinForm PDF file view so you can also render the PDF files into a view or do print preview on them. For us I simply needed a way to silently print the PDF file to a specific printer on demand.

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;
    }
}
つ低調成傷 2024-11-15 22:18:48

您可以告诉 Acrobat Reader 使用“打印”动词(正如某人已经提到的那样)打印文件。此后,您还需要以编程方式关闭 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/(商业)。

注意:示例代码在当前注册用于打印 PDF 的应用程序中打开 PDF,该应用程序是大多数人计算机上的 Adob​​e Acrobat Reader。但是,他们可能使用不同的 PDF 查看器,例如 Foxit (http://www.foxitsoftware. com/pdf/reader/)。不过,示例代码应该仍然可以工作。

You can tell Acrobat Reader to print the file using (as someone's already mentioned here) the 'print' verb. You will need to close Acrobat Reader programmatically after that, too:

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();
}

This opens Acrobat Reader and tells it to send the PDF to the default printer, and then shuts down Acrobat after three seconds.

If you are willing to ship other products with your application then you could use GhostScript (free), or a command-line PDF printer such as http://www.commandlinepdf.com/ (commercial).

Note: the sample code opens the PDF in the application current registered to print PDFs, which is the Adobe Acrobat Reader on most people's machines. However, it is possible that they use a different PDF viewer such as Foxit (http://www.foxitsoftware.com/pdf/reader/). The sample code should still work, though.

寄离 2024-11-15 22:18:48

我知道标签上写着 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 文件格式的直接打印,那么您就无法使用此方法。

I know the tag says Windows Forms... but, if anyone is interested in a WPF application method, System.Printing works like a charm.

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);
}

Just remember to include System.Printing reference, if it's not already included.
Now, this method does not play well with ASP.NET or Windows Service. It should not be used with Windows Forms, as it has System.Drawing.Printing. I don't have a single issue with my PDF printing using the above code.

I should mention, however, that if your printer does not support Direct Print for PDF file format, you're out of luck with this method.

残月升风 2024-11-15 22:18:48

以下代码片段改编自 Kendall Bennett 使用 PdfiumViewer 库。主要区别在于使用 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());

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

  • PdfiumViewer
  • PdfiumViewer.Native.x86.v8-xfa

The following code snippet is an adaptation of Kendall Bennett's code for printing pdf files using the PdfiumViewer library. The main difference is that a Stream is used rather than a file.

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;
    }
}

In my case I am generating the PDF file using a library called PdfSharp and then saving the document to a Stream like so:

PdfDocument pdf = PdfGenerator.GeneratePdf(printRequest.html, PageSize.A4);
pdf.AddPage();

MemoryStream stream = new MemoryStream();
pdf.Save(stream);
MemoryStream stream2 = new MemoryStream(stream.ToArray());

One thing that I want to point out that might be helpful to other developers is that I had to install the 32 bit version of the Pdfium native DLL in order for the printing to work even though I am running Windows 10 64 bit. I installed the following two NuGet packages using the NuGet package manager in Visual Studio:

  • PdfiumViewer
  • PdfiumViewer.Native.x86.v8-xfa
┼── 2024-11-15 22:18:48

最简单的方法:

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

The easy way:

var pi=new ProcessStartInfo("C:\file.docx");
pi.UseShellExecute = true;
pi.Verb = "print";
var process =  System.Diagnostics.Process.Start(pi);
你不是我要的菜∠ 2024-11-15 22:18:48

这是一个稍微修改过的解决方案。当进程空闲至少 1 秒时将被杀死。也许您应该添加 X 秒的 timeof 并从单独的线程调用该函数。

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();
}

This is a slightly modified solution. The Process will be killed when it was idle for at least 1 second. Maybe you should add a timeof of X seconds and call the function from a separate thread.

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();
}
ゃ人海孤独症 2024-11-15 22:18:48

System.Diagnostics.Process.Start 可以是用于打印文档。将 UseShellExecute 设置为 True 并将 Verb 设置为“print”。

System.Diagnostics.Process.Start can be used to print a document. Set UseShellExecute to True and set the Verb to "print".

甩你一脸翔 2024-11-15 22:18:48

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

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 \”并将这些文件打印到您的默认打印机

I know Edwin answered it above but his only prints one document. I use this code to print all files from a given directory.

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");
}

It essentually cycles through each file in the given directory variable Directory - > for me it was @"C:\Users\Owner\Documents\SalesVaultTesting\" and prints off those files to your default printer.

吐个泡泡 2024-11-15 22:18:48

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

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

这工作正常

this is a late answer, but you could also use the File.Copy method of the System.IO namespace top send a file to the printer:

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

This works fine

葬シ愛 2024-11-15 22:18:48

您可以使用 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);
      }
}

You can use the DevExpress PdfDocumentProcessor.Print(PdfPrinterSettings) Method.

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);
      }
}
鹿童谣 2024-11-15 22:18:48

Windows 10 及更高版本包括 < code>Windows.Data.Pdf API,允许打印和显示 PDF 文件通过 Direct2D。不需要额外的许可证或软件,并且可以从桌面和 UWP 应用程序调用 API。

Rmg.PdfPrinting,一个公开的小包装器.Net 的该功能可在 Nuget 上使用,它允许打印方式:

var pdfPrinter = new Rmg.PdfPrinting.PdfPrinter();
await pdfPrinter.Print("Printer Name", "Example.pdf");

如果您希望避免使用包装器,请对 CreateDocumentPackageTargetForPrintJobPdfCreateRenderer需要一些其他本机 API:

var pdfFile = await StorageFile.GetFileFromPathAsync("example.pdf");
var pdfDoc = await PdfDocument.LoadFromFileAsync(pdfFile);

// Initializing DXGI, D3D, D2D, and WIC are omitted for brevity
// See https://github.com/mgaffigan/D2DPdfPrintSample/blob/master/PrintPdfManaged/Program.cs#L55

// Initialize the job
ID2D1PrintControl printControl;
{
    // Create a factory for document print job.
    var documentTargetFactory = (IPrintDocumentPackageTargetFactory)new PrintDocumentPackageTargetFactory();
    IPrintDocumentPackageTarget docTarget;
    documentTargetFactory.CreateDocumentPackageTargetForPrintJob(
        printerName, jobName, null, ArrayToIStream(ticket), out docTarget);

    // Create a new print control linked to the package target.
    d2dDevice.CreatePrintControl(pWic, docTarget, null, out printControl);
}

// Open the PDF Document
PInvoke.PdfCreateRenderer(dxgiDevice, out var pPdfRendererNative).ThrowOnFailure();
var renderParams = new PDF_RENDER_PARAMS();

// Write pages
for (uint pageIndex = 0; pageIndex < pdfDoc.PageCount; pageIndex++)
{
    var pdfPage = pdfDoc.GetPage(pageIndex);

    d2dContextForPrint.CreateCommandList(out var commandList);
    d2dContextForPrint.SetTarget(commandList);

    d2dContextForPrint.BeginDraw();
    pPdfRendererNative.RenderPageToDeviceContext(pdfPage, d2dContextForPrint, &renderParams);
    d2dContextForPrint.EndDraw();

    commandList.Close();
    printControl.AddPage(commandList, pdfPage.Size.AsD2dSizeF(), null);
}

printControl.Close();

可以从 Github

Windows 10 and above include Windows.Data.Pdf APIs which permit printing and display of PDF files via Direct2D. No additional licenses or software are required, and the API's may be called from desktop and UWP applications.

Rmg.PdfPrinting, a small wrapper which exposes that functionality to .Net, is available on Nuget which permits printing via:

var pdfPrinter = new Rmg.PdfPrinting.PdfPrinter();
await pdfPrinter.Print("Printer Name", "Example.pdf");

If you prefer to avoid the wrapper, P/Invokes to CreateDocumentPackageTargetForPrintJob, PdfCreateRenderer, and a few other native API's are required:

var pdfFile = await StorageFile.GetFileFromPathAsync("example.pdf");
var pdfDoc = await PdfDocument.LoadFromFileAsync(pdfFile);

// Initializing DXGI, D3D, D2D, and WIC are omitted for brevity
// See https://github.com/mgaffigan/D2DPdfPrintSample/blob/master/PrintPdfManaged/Program.cs#L55

// Initialize the job
ID2D1PrintControl printControl;
{
    // Create a factory for document print job.
    var documentTargetFactory = (IPrintDocumentPackageTargetFactory)new PrintDocumentPackageTargetFactory();
    IPrintDocumentPackageTarget docTarget;
    documentTargetFactory.CreateDocumentPackageTargetForPrintJob(
        printerName, jobName, null, ArrayToIStream(ticket), out docTarget);

    // Create a new print control linked to the package target.
    d2dDevice.CreatePrintControl(pWic, docTarget, null, out printControl);
}

// Open the PDF Document
PInvoke.PdfCreateRenderer(dxgiDevice, out var pPdfRendererNative).ThrowOnFailure();
var renderParams = new PDF_RENDER_PARAMS();

// Write pages
for (uint pageIndex = 0; pageIndex < pdfDoc.PageCount; pageIndex++)
{
    var pdfPage = pdfDoc.GetPage(pageIndex);

    d2dContextForPrint.CreateCommandList(out var commandList);
    d2dContextForPrint.SetTarget(commandList);

    d2dContextForPrint.BeginDraw();
    pPdfRendererNative.RenderPageToDeviceContext(pdfPage, d2dContextForPrint, &renderParams);
    d2dContextForPrint.EndDraw();

    commandList.Close();
    printControl.AddPage(commandList, pdfPage.Size.AsD2dSizeF(), null);
}

printControl.Close();

A full sample without the wrapper in C# and C++ are available from Github.

落墨 2024-11-15 22:18:48

经过几天的尝试,我们最终使用了 https://www 中的“PDF Print for .NET” .winnovative-software.com/。它与 Evo PDF 的 PDF Print 相同,但可以作为独立产品购买(Evo PDF 是整个套件,价格更贵)。它的价格为 250 美元/550 美元,具体取决于您需要的许可证,这是我发现的唯一一个可以实现我们想要的功能的产品,看起来很微不足道,对吧:静默打印 PDF(不会弹出窗口)&让我们控制缩放。

编辑:Winnovative 对我发送的三封电子邮件没有支持反应,因此可能因此不推荐!

private static void PrintDirect(string filePath, string printerName)
{
  var printer = new PdfPrint
  {
    LicenseKey = "xyz",
    UseHardMargins = false,
    ShowStatusDialog = false
  };
  printer.PrinterSettings.PrinterName = printerName;
  printer.DefaultPageSettings.Margins = new Margins(20, 20, 20, 20);
  printer.Print(filePath);
}

我尝试过的(虽然我不记得所有内容):

  1. System.IO.Copy :在某些打印机上工作,打印速度超快,但 HP 打印机缩放不正确(底部缺少线条)。我们没有找到办法来控制这一点。
  2. Pdfium:我放弃了寻找并安装正确软件包的尝试。
  3. IronPdf:打印正确,但即使在快速机器上也需要大约 30-40 秒。
  4. IronPrint:打印速度快但超级模糊。
  5. LPN/LPT:如果我正确的话,在服务器和客户端上安装似乎太复杂了。

After days of trying this and that, we ended up using "PDF Print for .NET" from https://www.winnovative-software.com/. It's the same like Evo PDF's PDF Print but can be purchased as a standalone product (Evo PDF is a whole suite which is more expensive). It's $250 / $550, depending on the license you need and it's the only one I found that does what we want, which looks so trivial, right: Print a PDF silently (no window popping up) & let us have control of scaling.

EDIT: No support reaction from Winnovative to three emails I sent, so maybe not recommendable for that reason!

private static void PrintDirect(string filePath, string printerName)
{
  var printer = new PdfPrint
  {
    LicenseKey = "xyz",
    UseHardMargins = false,
    ShowStatusDialog = false
  };
  printer.PrinterSettings.PrinterName = printerName;
  printer.DefaultPageSettings.Margins = new Margins(20, 20, 20, 20);
  printer.Print(filePath);
}

What I tried (I don't remember everything though):

  1. System.IO.Copy : Works on some printers, prints super fast but is scaled incorrectly by HP printers (lines missing at the bottom). We found no way to control this.
  2. Pdfium: I gave up trying to find and install the correct packages.
  3. IronPdf: Prints correctly but need around 30-40 seconds even on a fast machine.
  4. IronPrint: Prints fast but super blury.
  5. LPN/LPT: Seemed too complex to install on server and clients if I got it right.
北斗星光 2024-11-15 22:18:48
    public static void PrintFileToDefaultPrinter(string FilePath)
    {
        try
        {
            var file = File.ReadAllBytes(FilePath);
            var printQueue = LocalPrintServer.GetDefaultPrintQueue();

            using (var job = printQueue.AddJob())
            using (var stream = job.JobStream)
            {
                stream.Write(file, 0, file.Length);
            }
        }
        catch (Exception)
        {

            throw;
        }
    }
    public static void PrintFileToDefaultPrinter(string FilePath)
    {
        try
        {
            var file = File.ReadAllBytes(FilePath);
            var printQueue = LocalPrintServer.GetDefaultPrintQueue();

            using (var job = printQueue.AddJob())
            using (var stream = job.JobStream)
            {
                stream.Write(file, 0, file.Length);
            }
        }
        catch (Exception)
        {

            throw;
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文