【问题标题】:Print PDF in c# with staples在 c# 中使用订书钉打印 PDF
【发布时间】:2018-01-25 19:28:15
【问题描述】:

我正在尝试使用 c# 以编程方式打印 pdf。我尝试了不同的库(PostSharp、PDFium 等)以及 adobe SDK。但是,我找不到任何有关打印和装订打印输出的信息。

我尝试使用 PrintTicket 对象 (Microsoft) 来设置 Stapling 属性,但它不起作用。我已确认我安装了正确的打印驱动程序。我可以在手动打印时装订打印输出,所以我确定打印机支持它。

我编辑了帖子以包含完整的代码。我在这里使用的 PDF 库是 PdfiumViewer。我没有检查这段代码中的返回值,但如果我运行它,我得到的返回值会给我“ConflictStatus.ConflictResolved”。

        using (var server = new PrintServer("print server name"))
        {
            var printerName = "printer with stapling capabilities name";
            var queues = server.GetPrintQueues();
            using (var queue = queues.FirstOrDefault(x => x.FullName == printerName))
            {
                var printTicket = queue.DefaultPrintTicket;
                printTicket.Collation = Collation.Collated;
                printTicket.Stapling = Stapling.StapleTopLeft;
                queue.UserPrintTicket = printTicket;
                queue.CurrentJobSettings.CurrentPrintTicket = printTicket;
                var ret = queue.MergeAndValidatePrintTicket(queue.UserPrintTicket, printTicket);
                using (var pdfDoc = PdfDocument.Load("path to pdf"))
                {
                    using (var printDoc = pdfDoc.CreatePrintDocument())
                    {
                        printDoc.PrinterSettings.PrinterName = printerName;
                        printDoc.PrinterSettings.ToPage = 2;
                        printDoc.Print();
                    }
                }
            }
        }

【问题讨论】:

  • Print Pdf in C#的可能重复
  • 尝试致电queue.MergeAndValidatePrintTicket(queue.UserPrintTicket, printTicket) 合并门票。一定要检查返回值。
  • 感谢大家的回复。使用 MergeAndValidate 运气不好。它似乎使装订属性无效。我注意到的另一件事是,当我调用 queue.GetPrintCapabilities(printTicket) 时,StaplingCapability 属性显示计数为零,尽管打印机支持装订(就像我之前提到的,当我通过手动打印文档时,我可以装订文档Adobe 阅读器)。还有其他想法吗?
  • @h.o.m.a.n,感谢您的提示,但这不是骗人的,因为我无法在网上找到任何有关在 adobe 中装订的信息。我什至查看了 Adob​​e SDK,不幸的是,他们的 IAC 框架似乎不支持它。您发布的链接没有提及装订。
  • @JDoh':将queue.UserPrintTicket 分配给您的票证,然后将其与该票证合并,没有任何作用。

标签: c# pdf printing


【解决方案1】:

我终于找到了有用的东西!我从以下获得代码:https://www.codeproject.com/Articles/488737/Storing-and-recalling-printer-settings-in-Csharp-n

public static class PrinterUtilities
{
    [DllImport("kernel32.dll", ExactSpelling = true)]
    private static extern IntPtr GlobalFree(IntPtr handle);

    [DllImport("kernel32.dll", ExactSpelling = true)]
    private static extern IntPtr GlobalLock(IntPtr handle);

    [DllImport("kernel32.dll", ExactSpelling = true)]
    private static extern IntPtr GlobalUnlock(IntPtr handle);


    /// <summary>
    /// Grabs the data in arraylist and chucks it back into memory "Crank the suckers out"
    /// </summary>
    /// <param name="printerSettings"></param>
    /// <param name="filename"></param>
    public static void SetDevModeFromFile(PrinterSettings printerSettings, string filename)
    {
        IntPtr hDevMode = IntPtr.Zero;// a handle to our current DEVMODE
        IntPtr pDevMode = IntPtr.Zero;// a pointer to our current DEVMODE
        try
        {
            // Obtain the current DEVMODE position in memory
            hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings);

            // Obtain a lock on the handle and get an actual pointer so Windows won't move
            // it around while we're futzing with it
            pDevMode = GlobalLock(hDevMode);

            // Overwrite our current DEVMODE in memory with the one we saved.
            // They should be the same size since we haven't like upgraded the OS
            // or anything.


            var fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            var temparray = new byte[fs.Length];
            fs.Read(temparray, 0, temparray.Length);
            fs.Close();
            fs.Dispose();
            for (int i = 0; i < temparray.Length; ++i)
            {
                Marshal.WriteByte(pDevMode, i, temparray[i]);
            }
            // We're done futzing
            GlobalUnlock(hDevMode);

            // Tell our printer settings to use the one we just overwrote
            printerSettings.SetHdevmode(hDevMode);
            printerSettings.DefaultPageSettings.SetHdevmode(hDevMode);

            // It's copied to our printer settings, so we can free the OS-level one
            GlobalFree(hDevMode);
        }
        catch (Exception)
        {
            if (hDevMode != IntPtr.Zero)
            {
                GlobalUnlock(hDevMode);
                // And to boot, we don't need that DEVMODE anymore, either
                GlobalFree(hDevMode);
                hDevMode = IntPtr.Zero;
            }
        }

    }
}

然后在我的主类中调用它

    private static void PrintTest()
    {
        using (var pdfDoc = PdfDocument.Load("pdf doc path"))
        {
            using (var printDoc = pdfDoc.CreatePrintDocument())
            {
                var currentSettings = printDoc.PrinterSettings;
                SetDevModeFromFile(currentSettings, "bin file that has printer settings path");
                currentSettings.ToPage = 3;
                printDoc.Print();
            }
        }
    }

要使用上面的代码,我必须从链接下载原始解决方案。然后我运行原始解决方案,以便从打印机对话框更新装订/装订设置,然后将设置保存到“bin”文件。问题似乎是并非所有设置都由 .net 公开(可能是因为这些是更多特定于打印机硬件的设置)。要打开 pdf 文件,我使用了PDFiumViewer。我希望这对其他人有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    • 2012-07-19
    • 2016-11-25
    • 2011-07-30
    相关资源
    最近更新 更多