因此,我正在内存中渲染部分视图,以便将视图中的XSL-FO数据定向到PDF渲染器。

PDF渲染器可以将字符串XmlDocument或Stream用作输入。

这是我想做的:(为清晰起见,已编辑)

解决方案取自: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();
        }
    }
}


这是有效的方法,但是我不愿意做的是:

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,或者也许我只是弄乱了其他东西。

如果我用StringWriter替换StreamWriter可以正常工作,但是我不能使用StringWriter,因为当我调用.ToString()时,我会得到各种使XSL-FO混乱的转义字符,并且渲染器会抛出“非法字符”异常。

我通过创建XmlDocument并将字符串加载到其中来解决了这个问题,但这似乎是一种非常round回的工作方式。我真的只是想从HtmlTextWriter捕获输出,并将其直接输入到Renderer中。有什么办法吗?

谢谢!

最佳答案

当您说“ HtmlTextWriter似乎不想写入StreamWriter”时,这是否意味着driver.Render无法从inStream中获取任何字节?我能想到的两种可能性

首先是HtmlTextWriter在完成写入后不会刷新流,在这种情况下,在将inStream交给sw.Flush()之前,您可能需要在其中插入driver.Render

其次,在写入MemoryStream之后,位置指针将位于流的末尾,并且任何从其中读取的尝试都将产生零字节(因为它位于末尾)。

在这种情况下,将inStream.Position设置为0,或在调用inStream.Seek(0, SeekOrigin.Begin)之前调用driver.Render应该可以解决该问题。

我之前几次遇到第二种情况,所以这是我最好的猜测。

10-04 14:59