XPSDocumentWriter - 将特定页面打印到特定的纸盘

时间:2014-02-18 16:55:56

标签: wpf printing xps

我目前正在开发打印应用程序。此应用程序要求某些页面需要来自打印机上的特定纸盘。以下是我到目前为止的内容:

    foreach (var dto in dispensersToPrint)
    {
        var documents = FilterDocumentSections(DispenserDocumentsToPrint.RetrieveByDispenserId(dto.DispenserId));
        var groupedDocs = documents.GroupBy(t => t.DocumentTypeId);
        var queueName = Properties.Settings.Default.PrinterName;
        var queue = RawPrinterHelper.GetPrintQueue(queueName);
        var seq = new FixedDocumentSequence();
        var xpsWriter = PrintQueue.CreateXpsDocumentWriter(queue);

        foreach (var docGroup in groupedDocs)
        {
            var printTicket = queue.DefaultPrintTicket.Clone();
            var printTray = MapPrintTray((DocumentSectionType)docGroup.Key);
            if (!printTray.IsNullOrEmpty())
            {
                printTicket = RawPrinterHelper.ModifyPrintTicket(printTicket, "psk:JobInputBin", printTray);
            }
            var fixedDoc = new FixedDocument();
            fixedDoc.PrintTicket = printTicket;

            foreach (var doc in docGroup)
            {
                var pageContent = new PageContent();
                var fixedPage = new FixedPage();

                var localFileName = string.Empty;
                var unzippedFileName = string.Empty;
                //copy files locally
                localFileName = CopyFileToLocalMachine(doc.FileName);
                //unzip file
                unzippedFileName = EmfPrintingHelper.UnzipEmfFile(localFileName);
                var itemToPrint = new PrintableEmfImage
                                           {
                                               DataContext = new EmfImageViewModel { FileName = unzippedFileName }
                                           };
                fixedPage.Children.Add(itemToPrint);
                pageContent.Child = fixedPage;
                fixedDoc.Pages.Add(pageContent);
            }
            var docRef = new DocumentReference();
            docRef.SetDocument(fixedDoc);
            seq.References.Add(docRef);
        }
        xpsWriter.Write(seq);
    }

处于真正的高水平:

  • 对于每个分配器(工单)我需要打印;我首先按DocumentType分组(即打印类型A到托盘1)
  • 然后我创建一个新的FixedDocumentSequence
  • 对于每个DocumentType;然后我创建一个固定的文档。然后我修改打印票据以查看相应的托盘。
  • 然后我为每种文档类型构建每个单独的页面;并将它们添加到FixedDocument
  • 完成FixedDocument的构建后;我将它附加到DocumentSequence。
  • 然后我将FixedDocumentSequence发送到xpsWriter。

但出于某种原因;这些设置没有兑现。我将所有文件从同一个托盘中打印出来。

以下是我目前的一些观察结果:

  • 修改打印票证确实有效;我已经通过将修改后的printTicket发送到xpsWriter来验证了这一点。但这会将设置应用于整个作业;这对我来说是不行的。
  • 查询打印功能时;我注意到我只有JobInputBin。我不认为这意味着这台打印机不支持该功能;因为多托盘打印工作来自类似的WindowsForms应用程序(使用PageSettings.PaperSource)

关于我接下来可以尝试的任何想法?以前有没有人成功做过这样的事情?

1 个答案:

答案 0 :(得分:3)

我首先要说的是,我无法使用带托盘的打印机,因此我很遗憾无法测试此解决方案。也就是说,我会将您的注意力转移到MSDN论坛帖子here,其中原始海报是为了追求相同的每页托盘行为。

根据您发布的代码,您可能已经看到了这篇文章中的一些内容,根据您发布的代码至少有一些ModifyPrintTicket()的实现来判断。

在帖子中,有几个不同的用户,每个用户都引用了针对特定问题版本的解决方案。但是,在这种情况下似乎最相关的是关于ModifyPrintTicket()中没有正确说明名称空间的解决方案(由发布者 Jo0815)。我说'最相关',因为海报说的是印刷托盘被忽视。他们(wittersworld)提供了一个替代实现来纠正这个问题。在MSDN上的帖子中,指向完整来源的链接已中断,但可以找到here

要点是,在ModifyPrintTicket()上,他们添加了namespaceUri参数,然后改变了这一点:

if (node != null)
{
    node.Attributes["name"].Value = newValue;
}

到此:

if (node != null)
{
    if (newValue.StartsWith("ns0000"))
    {
        // add namespace to xml doc
        XmlAttribute namespaceAttribute = xmlDoc.CreateAttribute("xmlns:ns0000");                   
        namespaceAttribute.Value = namespaceUri;                   
        xmlDoc.DocumentElement.Attributes.Append(namespaceAttribute);
    }
    node.Attributes["name"].Value = newValue;
}

允许用户指定使用的特定于打印机的命名空间。

我希望这有用。