سؤال

لذلك أقوم بإعداد طريقة عرض جزئية في الذاكرة من أجل توجيه بيانات XSL-FO في العرض إلى عارض PDF.

يمكن لعارض PDF أن يأخذ سلسلة أو XMLDOCUMENT أو دفق كمدخل.

هذا ما أود القيام به: (تم تحريره للوضوح)

الحل مأخوذ من: http://thriftybliss.spaces.live.com/blog/cns !58da805f37f31f20!

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

إليك ما ينجح ، لكن ما أفضل عدم فعله:

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

لسوء الحظ ، لا يبدو أن HTMLTextWriter ترغب في الكتابة إلى StreamWriter ، أو ربما أفسدت شيئًا آخر.

إذا قمت باستبدال StreamWriter بـ StringWriter ، فهذا يعمل بشكل جيد ، لكن لا يمكنني استخدام StringWriter لأنه عندما أتصل. toString () أحصل على جميع أنواع الأحرف الهروب التي تعبث XSL-FO ويلقي العارض استثناء "أحرف غير قانونية".

لقد تجولت هذا من خلال إنشاء XMLDOCUMBE وتحميل السلسلة في ذلك ، ولكن يبدو وكأنه طريقة دورية للغاية لفعل الأشياء. أود حقًا فقط التقاط الإخراج من HTMLTextWriter وأطعمه مباشرة في العارض. هل هناك أي طريقة للقيام بذلك؟

شكرًا!

هل كانت مفيدة؟

المحلول

عندما تقول "htmltextWriter لا يبدو أنه يريد الكتابة إلى StreamWriter" هل يعني ذلك ذلك driver.Render لا يمكنك الحصول على أي بايت من instream؟ احتمالان يمكنني التفكير في ...

الأول هو أن HTMLTextWriter لا يتدفق على الدفق بعد الانتهاء من الكتابة ، وفي هذه الحالة قد تحتاج إلى ملف sw.Flush() هناك قبل تسليم المعقد إلى driver.Render.

ثانياً أنه بعد الكتابة إلى MemoryStream ، سيكون مؤشر الموقع في نهاية الدفق ، وأي محاولات للقراءة منها ستحقق بايت صفر (لأنها في النهاية).

في هذه الحالة ، الإعداد inStream.Position إلى 0 ، أو الاتصال inStream.Seek(0, SeekOrigin.Begin) قبل الاتصال driver.Render يجب إصلاحه.

لقد واجهت الموقف الثاني عدة مرات من قبل ، لذلك هذا هو أفضل تخمين لي.

نصائح أخرى

لم أختبر هذا على الإطلاق... لكنها نسخة معدلة من أ طريقة RenderviewToString التي صنعتها وأستخدمها في مكان آخر:

    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;
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top