当前位置: 首页 > 知识库问答 >
问题:

使用订书钉在C#中打印PDF

简成仁
2023-03-14

我尝试使用PrintTicket对象(Microsoft)设置订书钉属性,但它不起作用。我已验证是否安装了正确的打印驱动程序。当我手动打印时,我能够钉上打印输出,所以我确信打印机支持它。

我编辑了这篇文章以包含完整的代码。我在这里使用的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();
                    }
                }
            }
        }

共有1个答案

刘修能
2023-03-14

我终于找到了管用的东西!我从以下站点获得了代码:https://www.codeproject.com/articles/488737/storage-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。我希望这能帮到别人。

 类似资料:
  • 简单、省钱、安全! 手机打印/免装驱动/全员共享/远程打印/用量统计/省钱经济 产品清单 包材产品清单配图 包材产品清单 包材产品清单 产品结构 产品结构 配置流程 配置前准备 扫描二维码 连接蓝牙 云盒连网 绑定团队 使用流程 1.钉钉内云打印(钉钉客户端4.3.7及以上版本) 1.1 聊天对话内的文件、图片等,可发起云打印 手机端钉钉 电脑端钉钉 1.2 钉盘内的文件、图片等,可发起云打印 手

  • 我正在尝试从excel打印一个word文档。 除了我需要为此打印作业启用订书机外,此操作有效。 我的打印机是Xerox Workcenter 5755,可以在左上角放一到两个订书钉。 Excel显然可以管理这一点,我不需要进入打印机驱动程序属性来启用装订,我可以直接从文件打印页面启用。 当我转到这个页面时,在“设置”下面有一个下拉列表,上面写着“无订书机”,带有订书机符号。 如果我点击它,我会选择

  • 我们有一个管理打印文档的项目。起初,我想知道为什么不能在一个地方设置打印选项。例如,可以使用MS Word自动化完成首页和其他页面的打印机托盘选择: 在上面的代码中,打印机托盘被指定为整数,因为一些打印机没有托盘的标准值(我们在HP中遇到了这个问题-这里描述了托盘代码)。因此,我们首先使用代码检索打印机的托盘: 这段代码工作正常。 但这里无法指定双面打印和装订选项。可以使用OpenPrinter和

  • 1.打印订单的间距怎么修改? 打印订单的模板是系统自带的。需要改的话参考二开手册。

  • WooCommerce的订单页面内容繁多,如果直接打印后台页面,想必是惨不忍睹,还好有一款免费插件可以解决这个问题——WooCommerce Print Invoices & Delivery Notes,这个插件的好处是通过修改模版,你可以打印订单中的任何内容,漂亮的打印出来。 关于该插件的使用不再赘述,本文介绍如何修改打印模版,加入自己需要的数据。比如,加入产品缩略图和产品分类,效果如下图所示

  • 简单、省钱、安全的企业级云打印。 配置前准备 C1 + 惠普打印机 配置说明 1.配置钉钉C1智能无线路由器 钉钉智能无线路由器通电、连网 配置:连接WiFi、打开钉钉 绑定团队,设置网络名称 2.打印机配置流程 1)通电开机,网线连接 通电和连网 2)打开手机钉钉,大约30s收到通知,一键绑定团队 收到工作通知,点击一键绑定团队 绑定过程中,自动打印二维码信息页 3)二维码粘贴在打印机上 剪下并