2

私は長い間印刷の問題と戦ってきました。誰かが助けてくれることを願っています。

背景 ワード テンプレートから Aspose.Words ドキュメントを作成し、それをメール マージしてから、印刷ダイアログを使用して WPF アプリケーションから直接印刷したいと考えています。印刷するときは、プリンターで使用できるさまざまなプリンター設定 (使用する用紙、ズーム、向き、色など) をすべて選択できる必要があります。私が見つけたすべての例は、プリンター名または印刷するコピーの数を指定することだけであるため、この最後のことが私のGoogle検索の成功を妨げているようです.

テスト 1 - Aspose が推奨する印刷方法 フォーラムから

    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);
    }

これで完璧なようです!しかし、私は得る21 つの問題。

  • 最初にデフォルトのフォントで印刷され、2 番目に私の特別なフォントで 2 番目に最初のフォントの上に印刷されるように見えるため、テキストはページ上で 2 倍になります。スクリーンキャプチャを参照してください: これについては申し訳ありませんが、それはdocxファイル内の非表示の画像であり、何らかの形で変換すると前面に表示されました(Wordでは非表示になっていましたが)。

テキストはページ上で 2 重になっています

  • それは非常に遅いです...印刷するのに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 Automation で印刷する

    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);
        }

    }

では、自動化を使用する必要がありますか? 正常に印刷されますが、ワードアプリとドキュメントを閉じると問題が発生します。たとえば、「マージンが印刷可能領域外です」というダイアログが表示されることがありますが、コードはプロセスを終了できず、プロセスを終了します。Thread.Sleep が表示されますか? そこにない場合、印刷が完了する前に Word が終了します。

ほら、私はすべての試みで不十分です。これについて最善の方法は何ですか?

御時間ありがとうございます!

4

1 に答える 1

2

OK、適切な 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 を参照してください

于 2012-03-16T07:17:36.927 に答える