Programmatischer Export aus Vorschau

In einer Vorschaudatei ist ja alles vorhanden, um nach PDF zu exportieren.

Ich bin deshalb davon ausgegangen, dass ich beim Druck auf das Preview Control (inkrementelle Vorschau), programmatisch einen PDF-Export auslösen kann ohne dass komplett neu gerendert werden müsste - hinter den Kulissen wird da ja eine temporäre LL-Datei erzeugt. Irgendwie finde finde ich da aber keinen Weg?

Anwendungsfall: Ich möchte eine Schaltfläche anbieten, mit der der Anwender den angezeigten Report ins Dokumentenmanagementsystem übernehmen kann, ohne dass die ggf. > 100 Seiten nochmal komplett neu aufgebaut werden müssen.

BTW: Wenn man aus der Vorschau eine E-Mail erstellt, wird der PDF-Anhang ruckzuck erzeugt, ohne die Druckschleife nochmal zu durchlaufen. Beim PDF-Export über die “Exportieren”-Schaltfläche wird dagegen alles neu gedruckt… Warum?

Also wenn das im Code passieren soll mit dem PDF-Export und dir Vorschau-Datei ist vorhanden und bekannt, dann sollte das mit der Convert-Funktion der Vorschaudatei eigentlich möglich sein, ohne das ein voller Re-Print durchgeführt werden muss. Das wäre dann eher ein “SaveAs” - wie beim Mail-Versand auch.

Kommt denn .NET zum Einsatz? Wenn ja, dann würde sich anbieten die PreviewFile-Klasse zu verwenden und dort dann das ConvertTo aufrufen.

Es wird nicht in eine LL-Datei gedruckt, sondern auf die inkrementelle Vorschau. Das ist aus psychologischen Gründen auch alternativlos - Druck in LL-Datei würde sich zu langsam anfühlen.

Und ja, Umgebung ist .NET.

Also wenn das PreviewControl auf der Form verwendet wird, müsste dort aber schon der SaveAs-Button vorhanden sein:
image

Wenn das modale Vorschaufenster aufgeht sollten man im Ribbon unter “Weitere Formate” dann auch das SaveAs für das PDF auslösen können:

Natürlich beides interaktive Aktionen die der Anwender selbst ausführen muss. Aber meines Wissen wird da eben kein Re-Print ausgelöst und es braucht dann auch nicht das ConvertTo etc.

Man könnte dann auch auf das Ereignis ViewerButtonClicked reagieren und dort seinen eigenen PDF-Export durchführen. Wenn das PreviewControl aber nicht verwendet wird sondern eben das modale Vorschaufenster, muss man irgendwie an den aktuellen Dateinamen kommen, der in der Vorschau angezeigt wird, damit man das ConvertTo aufrufen kann - was aber nur funktioniert, wenn die Vorschaudatei eben nicht geladen ist, was aber im Anwendungsfall zu sein scheint. Haben ein wenig damit gespielt und geforscht - könnte dann so aussehen:

...
private void LL_ViewerButtonClicked(object sender, ViewerButtonClickedEventArgs e)
{
    int nSize = (int)MyNativeMethods.SendMessage(e.ViewerWindow.Handle, MyNativeMethods.LS_VIEWERCONTROL_GET_FILENAME, IntPtr.Zero, IntPtr.Zero);
    StringBuilder buffer = new StringBuilder(nSize * 2 + 1);
    MyNativeMethods.SendMessage(e.ViewerWindow.Handle, MyNativeMethods.LS_VIEWERCONTROL_GET_FILENAME, (IntPtr)nSize, buffer);
    string llFileName = buffer.ToString();
    if (File.Exists(llFileName))
    {
        // copy current preview file into temp preview file
        string newTempFie = llFileName + "_copy.ll";
        File.Copy(llFileName, newTempFie, true);

        // convert to PDF
        using (PreviewFile prev = new PreviewFile(newTempFie, true))
        {
            prev.ConvertTo(@"c:\temp\export.pdf");
        }

        // skip further action in preview window
        e.IsProcessed = true;

        // delete temp peview file
        File.Delete(newTempFie);
    }
}

public static class MyNativeMethods
{
    public const int WM_USER = 0x0400;
    public const int LS_VIEWERCONTROL_GET_FILENAME = WM_USER + 55;

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    internal static extern IntPtr SendMessage
        (IntPtr hWnd, uint Msg, IntPtr wParam, StringBuilder lParam);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    internal static extern IntPtr SendMessage
        (IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
}
...

Das “Wegkopieren” der temporären LL-Datei funktioniert tatsächlich. Den Dateinamen kann man recht einfach über die Eigenschaft “FileName” des Vorschaucontrols abgreifen.

Mag sich combit mal dazu äußern, ob das wirklich der richtige Weg ist, meine Anforderung zu lösen?

Und BTW: Es wird immer der gleiche Temporärdateiname gebildet, so dass nur eine Instanz pro Benutzer die inkrementelle Vorschau nutzen kann? Nachvollziehbar über die Beispielanwendung: 2 x starten, in beiden Instanzen die gleiche Liste auf die Vorschau drucken:
grafik

Das scheint mir - wenn denn die Bedingungen wie beschrieben fix sind, d. h. kein PreviewControl gewünscht, inkrementelle Vorschau wichtig und keine Benutzerinteraktion möglich - eine praktikable Lösung.

Der Pfad und Name der Vorschaudatei kann pro Ausdruck separat bestimmt werden. Hier ist das dokumentiert: