【问题标题】:Print Word document from WPF with print settings (Aspose generated)使用打印设置从 WPF 打印 Word 文档(Aspose 生成)
【发布时间】:2012-04-01 00:06:19
【问题描述】:

我一直在与打印问题作斗争,希望有人能提供帮助。

背景 我正在从一个 word 模板创建一个 Aspose.Words 文档,并通过邮件将其合并,然后希望使用打印对话框直接从 WPF 应用程序打印它。 打印时,我需要能够为我的打印机选择所有可用的不同打印机设置(使用什么纸张、缩放、方向、颜色等)。最后一件事似乎是让我的 Google 搜索无法成功的原因,因为我找到的所有示例都只是关于提供打印机名称或要打印多少份。

测试 1 - Aspose 的首选打印方式 From their forum

    private void Print(Document document)
    {
        var printDialog = new System.Windows.Forms.PrintDialog
        {
            AllowSomePages = true,
            PrinterSettings = new PrinterSettings
            {
                MinimumPage = 1,
                MaximumPage = document.PageCount,
                FromPage = 1,
                ToPage = document.PageCount
            },
            UseEXDialog = true
        };

        var result = printDialog.ShowDialog();
        if (result.Equals(DialogResult.OK))
            document.Print(printDialog.PrinterSettings);
    }

现在这似乎是完美的!但我得到两个 一个问题。

  • 页面上的文本是双倍的,因为它似乎首先使用默认字体打印,第二个使用我的特殊字体打印,第二个,在第一个顶部。查看屏幕截图: 抱歉,这是 docx 文件中的隐藏图像,在以某种方式转换时出现在最前面(即使隐藏在 Word 中)。

  • 速度太慢了... document.Print 需要很长时间,尽管它只打印 2 页,而且没有图形。

测试 2 - 使用过程打印 (PDF)

    private void Print(Document document)
    {
        var savePath = String.Format("C:\\temp\\a.pdf");
        document.Save(savePath, SaveFormat.Pdf);

        var myProcess = new Process();
        myProcess.StartInfo.FileName = savePath;
        myProcess.StartInfo.Verb = "Print";
        //myProcess.StartInfo.CreateNoWindow = true;
        myProcess.Start();
        myProcess.WaitForExit();
    }

这将是一个很好的解决方案,但它没有给我对话框(我可以使用单词 PrintTo 并提供一些参数,例如打印机名称等。但不是出于我的特殊要求,对吧?)

测试 3 - 使用 Word 自动化打印

    private void Print(Document document)
    {
        object nullobj = Missing.Value;

        var savePath = String.Format("C:\\temp\\a.docx");
        document.Save(savePath, SaveFormat.Docx);

        var wordApp = new Microsoft.Office.Interop.Word.Application();
        wordApp.DisplayAlerts = Microsoft.Office.Interop.Word.WdAlertLevel.wdAlertsNone;
        wordApp.Visible = false;

        Microsoft.Office.Interop.Word.Document doc = null;
        Microsoft.Office.Interop.Word.Documents docs = null;
        Microsoft.Office.Interop.Word.Dialog dialog = null;
        try
        {
            docs = wordApp.Documents;
            doc = docs.Open(savePath);

            doc.Activate();
            dialog = wordApp.Dialogs[Microsoft.Office.Interop.Word.WdWordDialog.wdDialogFilePrint];
            var dialogResult = dialog.Show(ref nullobj);
            if (dialogResult == 1)
            {
                doc.PrintOut(false);
            }
        }catch(Exception)
        {
            throw;
        }finally
        {
            Thread.Sleep(3000);
            if (dialog != null) Marshal.FinalReleaseComObject(dialog);
            if (doc != null) Marshal.FinalReleaseComObject(doc);
            if (docs != null) Marshal.FinalReleaseComObject(docs);

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            GC.WaitForPendingFinalizers();

            doc = null;
            wordApp.Quit(false, ref nullobj, ref nullobj);
        }

    }

好的,我应该使用自动化吗?它打印得很好,但是在关闭 word-app 和文档时我遇到了麻烦。例如,我有时会看到“可打印区域外的边距”对话框,然后哇,代码无法退出进程并离开它。 你看到 Thread.Sleep 了吗?如果我没有它,Word 将在打印完成之前退出。

你看,我所有的尝试都失败了。解决此问题的最佳方法是什么?

感谢您的宝贵时间!

【问题讨论】:

    标签: c# wpf printing office-interop aspose


    【解决方案1】:

    好的,我找到了合适的 WPF 解决方案,将文档转换为 XPS 并将其加载到 DocumentViewer 中,我可以从中使用本机打印功能。

    View.xaml

    <DocumentViewer Document="{Binding XpsFixedDocumentSequence}"/>
    

    ViewModel.cs

    using System.Windows.Xps.Packaging;
    ...
    
    private void PrepareDocument(Document document)
    {
        var xpsDoc = GetDocumentAsXps(document);
        XpsFixedDocumentSequence = xpsDoc.GetFixedDocumentSequence();
    }
    
    private XpsDocument GetDocumentAsXps(Document document)
    {
        var savePath = "C:\\temp\\doc.xps";
        document.Save(savePath, SaveFormat.Xps);
        var xpsDoc = new XpsDocument(savePath, FileAccess.Read);
        return xpsDoc;
    }
    
    /* Property XpsFixedDocumentSequence */
    public const string XpsFixedDocumentSequencePropertyName = "XpsFixedDocumentSequence";
    private FixedDocumentSequence _xpsFixedDocumentSequence;
    public FixedDocumentSequence XpsFixedDocumentSequence
    {
        get { return _xpsFixedDocumentSequence; }
    
        set
        {
            if (_xpsFixedDocumentSequence == value) return;
            _xpsFixedDocumentSequence = value;
            RaisePropertyChanged(XpsFixedDocumentSequencePropertyName);
        }
    }
    

    自我注意:参考 ReachFramework dll

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-15
      • 2014-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多