如何在 .NET 中以编程方式在信头纸、卡片纸、预印纸上打印

How to programmatically print on Letterhead, Cardstock, Pre-printed paper in .NET

我正在尝试使用 System.Drawing.Printing 库从 WCF 服务进行打印。问题是我正在尝试选择一种纸张类型(或介质类型),如信头纸、卡片纸或预印纸,而这些纸张在该库中似乎不可用。

System.Drawing.Printing 有一个 PageSettings class,但我只能设置 PaperSize,没有用于信头纸、卡片纸、预印纸等的 PaperSize。 https://msdn.microsoft.com/en-us/library/System.Drawing.Printing.PageSettings(v=vs.110).aspx

另外 PrinterSettings.PaperSources 中的 PaperSource class 不包含任何关于每个纸盒中纸张类型的信息。

有没有人建议如何确保我发送的打印作业具有正确的设置,以便打印机知道从哪个纸盘打印?

一定有办法做到这一点。例如,从 Word 或 Excel 打印时我可以 select 信头,但仅当我转到打印机属性时。为什么我不能在 .NET 中以编程方式执行此操作?这是托管代码限制吗?我需要访问打印机驱动程序吗?

甚至 System.Printing 也没有这些选项可用。 MSDN 还指出:

Caution: Classes within the System.Printing namespace are not supported for use within a Windows service or ASP.NET application or service. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions.

我唯一可用的其他选项是让用户在具有某些用户界面的数据库中手动设置每台打印机的每个托盘中的纸张类型。然后我将设置要打印的托盘。如果可能的话,我想避免这种情况。

2015 年 12 月 14 日更新

打印机制造商愿意提供付费解决方案,但目前该项目不可行。

粗略的代码解决方案是:

private PrintJobStatusEnum SendToPrinter(PrintDocumentModel printJob, out List<string> errors)
        {
            errors = new List<string>();

            // The print job includes the printer and page settings
            var printerSettings = new PrinterSettings
            {
                PrinterName = "MyPrinterName",
                Duplex = printJob.IsDuplex ? Duplex.Vertical : Duplex.Simplex
            };

            // Set the paper size
            var paperKind = PaperKind.Letter;

            // Find the paper size in the available sizes on the printer
            var paperSizes = printerSettings.PaperSizes.Cast<PaperSize>().AsQueryable();
            var paperSize = paperSizes.FirstOrDefault(p => p.Kind == paperKind);

            // Set the paper source (tray)
            var paperSources = printerSettings.PaperSources.Cast<PaperSource>().AsQueryable();

            // The SourceName is different for many printers. 
            // Double-check yours through PrinterSettings.PaperSources
            var paperSource = paperSources.FirstOrDefault(s => s.SourceName == "Cassette 1");
            if (paperSource == null)
            {
                paperSource = paperSources.FirstOrDefault(s => s.Kind == PaperSourceKind.AutomaticFeed);
            }

            // Set up the page
            var pageSettings = new PageSettings
            {
                Landscape = printJob.PaperOrientationLookUpId == MyConstants.PaperOrientationLandscape,
                Margins = new Margins(0, 0, 0, 0), // Not sure if margins are needed
                PaperSize = paperSize ?? new PaperSize("Letter", 850, 1100),
                Color = printJob.IsColor,
                PaperSource = paperSource,
                PrinterSettings = printerSettings
            };


            // Send document, printer settings and page settings to print handler
            List<string> printErrors;

            var result = _pdfPrintHandler.Print(printerSettings, pageSettings, printJob, out printErrors);
            errors.AddRange(printErrors);

            return result;
        }

这在 .NET 中过去是如何工作的,现在可能仍然是这样,因为所有这些功能都是特定于打印机驱动程序的。它们不会作为可调用 API 公开。用户可在 运行 时配置什么纸张尺寸和类型等。驱动程序会更改将墨水粘在纸上的精确方法,这是 none 您的事。

不过,驱动程序会告诉您打印的纸张尺寸,您可以相应地修改输出。您也可以选择自己以编程方式翻转渲染以制作纵向和横向。

您可以保存和加载打印机配置 "Page Setups"。因此,您可以让用户使用不同的托盘选择配置不同的 "Page Setups",并在打印时在它们之间切换。

https://social.msdn.microsoft.com/Forums/vstudio/en-US/0e1194ee-d71b-45b4-b4c2-5b626a100d30/windows-print-spooler-api-and-paper-tray-selection?forum=netfxbcl