Frage

Daher rendere ich eine Teilansicht im Speicher, um die XSL-FO-Daten in der Ansicht an einen PDF-Renderer weiterzuleiten.

Der PDF-Renderer kann einen String, ein XmlDocument oder einen Stream als Eingabe annehmen.

Folgendes möchte ich tun:(Aus Gründen der Klarheit bearbeitet)

Lösung entnommen aus: http://thriftybliss.spaces.live.com/blog/cns!58DA805F37F31F20!170.entry?wa=wsignin1.0&sa=362921628

var viewPage = new ViewPage();
var viewData = new ViewDataDictionary(model);
viewPage.ViewData = viewData;

var control = viewPage.LoadControl(viewName);
viewPage.Controls.Add(control);

using (var inStream = new MemoryStream())
{
    using (var sw = new StreamWriter(inStream))
    {
        using (var tw = new HtmlTextWriter(sw))
        {
            viewPage.RenderControl(tw);
        }
        using (var outStream = new MemoryStream())
        {
            driver.Render(inStream, outStream);
            return outStream.ToArray();
        }
    }
}

Folgendes funktioniert, was ich aber lieber nicht tun möchte:

var sb = new StringBuilder();

using (var sw = new StringWriter(sb))
{
    using (var tw = new HtmlTextWriter(sw))
    {
        vp.RenderControl(tw);
    }
}

var xml = new XmlDocument();
xml.LoadXml(sb.ToString());

using (var ms = new MemoryStream())
{
    driver.Render(xml, ms);
    return ms.ToArray();
}

Leider scheint der HtmlTextWriter nicht in den StreamWriter schreiben zu wollen, oder vielleicht habe ich einfach etwas anderes vermasselt.

Wenn ich StreamWriter durch StringWriter ersetze, funktioniert es einwandfrei, aber ich kann StringWriter nicht verwenden, da ich beim Aufruf von .ToString() alle Arten von Escape-Zeichen erhalte, die das XSL-FO durcheinander bringen, und der Renderer eine „Illegal Characters“-Ausnahme auslöst.

Ich habe dies umgangen, indem ich ein XmlDocument erstellt und die Zeichenfolge darin geladen habe, aber es scheint eine sehr umständliche Vorgehensweise zu sein.Ich möchte wirklich einfach die Ausgabe des HtmlTextWriter erfassen und sie direkt in den Renderer einspeisen.Gibt es eine Möglichkeit, dies zu tun?

Danke!

War es hilfreich?

Lösung

Wenn Sie sagen „HtmlTextWriter scheint nicht in den StreamWriter schreiben zu wollen“, heißt das? driver.Render Kann ich keine Bytes aus inStream abrufen?Zwei Möglichkeiten fallen mir ein...

Erstens löscht HtmlTextWriter den Stream nicht, nachdem er mit dem Schreiben fertig ist. In diesem Fall benötigen Sie möglicherweise einen sw.Flush() dort ein, bevor Sie den inStream übergeben driver.Render.

Zweitens befindet sich der Speicherortzeiger nach dem Schreiben in den MemoryStream am Ende des Streams und alle Versuche, daraus zu lesen, ergeben null Bytes (da er sich am Ende befindet).

In diesem Fall Einstellung inStream.Position auf 0, oder anrufen inStream.Seek(0, SeekOrigin.Begin) bevor Sie anrufen driver.Render sollte es beheben.

Ich bin schon ein paar Mal auf die zweite Situation gestoßen, also ist das meine beste Vermutung.

Andere Tipps

Ich habe das gar nicht getestet. .. aber es ist eine modifizierte Version eines RenderViewToString Methode , dass ich gemacht und die Verwendung anderer Stelle:

    public static Stream RenderViewToStream<T>(string viewPath, T model, ControllerContext controllerContext)
    {
        var ms = new MemoryStream();
        using (var writer = new StreamWriter(ms))
        {
            var view = new WebFormView(viewPath);
            var vdd = new ViewDataDictionary<T>(model);
            var viewCxt = new ViewContext(controllerContext, view, vdd, new TempDataDictionary(), writer);
            viewCxt.View.Render(viewCxt, writer);
        }
        return ms;
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top