5

您好,感谢您的关注!

背景

我正在使用Rotativa pdf 工具将视图 (html) 读入 PDF。它工作得很好,但它本身并不提供将 PDF 保存到文件系统的方法。相反,它只是将文件作为操作的结果返回给用户的浏览器。

这是该代码的样子:

public ActionResult PrintQuote(FormCollection fc)
        {
            int revisionId = Int32.Parse(Request.QueryString["RevisionId"]);

            var pdf = new ActionAsPdf(
                 "Quote",
                 new { revisionId = revisionId })
                       {
                           FileName = "Quote--" + revisionId.ToString() + ".pdf",
                           PageSize = Rotativa.Options.Size.Letter
                       };

            return pdf;

        } 

此代码正在调用另一个操作结果(“报价”),将其视图转换为 PDF,然后将 PDF 作为文件下载返回给用户。

问题

如何截取文件流并将 PDF 保存到我的文件系统。将PDF发送给用户是完美的,但我的客户也希望同时将PDF保存到文件系统中。

有任何想法吗?

谢谢!

马特

4

6 回答 6

3

我有同样的问题,这是我的解决方案:

您基本上需要向您自己的 URL 发出 HTTP 请求,并将输出保存为二进制文件。简单、没有重载、辅助类和臃肿的代码。

你需要这个方法:

    // Returns the results of fetching the requested HTML page.
    public static void SaveHttpResponseAsFile(string RequestUrl, string FilePath)
    {
        try
        {
            HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(RequestUrl);
            httpRequest.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";
            httpRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)httpRequest.GetResponse();
            }
            catch (System.Net.WebException ex)
            {
                if (ex.Status == WebExceptionStatus.ProtocolError)
                    response = (HttpWebResponse)ex.Response;
            }

            using (Stream responseStream = response.GetResponseStream())
            {
                Stream FinalStream = responseStream;
                if (response.ContentEncoding.ToLower().Contains("gzip"))
                    FinalStream = new GZipStream(FinalStream, CompressionMode.Decompress);
                else if (response.ContentEncoding.ToLower().Contains("deflate"))
                    FinalStream = new DeflateStream(FinalStream, CompressionMode.Decompress);

                using (var fileStream = System.IO.File.Create(FilePath))
                {
                    FinalStream.CopyTo(fileStream);
                }

                response.Close();
                FinalStream.Close();
            }
        }
        catch
        { }
    }

然后在您的控制器内部,您可以这样称呼它:

SaveHttpResponseAsFile("http://localhost:52515/Management/ViewPDFInvoice/" + ID.ToString(), "C:\\temp\\test.pdf");

瞧!该文件在您的文件系统中,您可以双击并打开 PDF,或通过电子邮件将其发送给您的用户,或者您需要的任何内容。

于 2013-03-03T01:39:17.300 回答
1
 return new Rotativa.ActionAsPdf("ConvertIntoPdf") 
 { 
     FileName = "Test.pdf", PageSize = Rotativa.Options.Size.Letter
 };
于 2016-01-18T07:29:11.277 回答
0

看看这里的 MVC 流水线图: http ://www.simple-talk.com/content/file.ashx?file=6068

在呈现 ActionResult 之后调用方法OnResultExecuted() 。

您可以覆盖此方法或使用ActionFilter来应用和使用属性的 OnResultExecuted 拦截器。

编辑:此论坛主题的末尾,您将找到一个回复​​,其中给出了一个 ActionFilter 的示例,该示例读取(并更改)一个动作的响应流。然后,您可以将流复制到文件中,并将其返回给您的客户端。

于 2012-08-07T22:22:38.380 回答
0

我成功地使用了 Aaron 的“SaveHttpResponseAsFile”方法,但我不得不改变它,因为当前登录的用户的凭据没有被应用(所以它被转发到 MVC4 的登录 url)。

public static void SaveHttpResponseAsFile(System.Web.HttpRequestBase requestBase, string requestUrl, string saveFilePath)
{
    try
    {
        *snip*
        httpRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
        httpRequest.Headers.Add(HttpRequestHeader.Cookie, requestBase.Headers["Cookie"]);
        *snip*</pre></code>

然后在调用 Controller 方法中,只需将“请求”添加到 SaveHttpResponseAsFile 调用中。

于 2013-10-30T14:23:15.587 回答
0

您也可以使用 Rotativa 来完成,这实际上非常简单。

Using Rotativa;

...

byte[] pdfByteArray = Rotativa.WkhtmltopdfDriver.ConvertHtml( "Rotativa", "-q", stringHtmlResult );

File.WriteAllBytes( outputPath, pdfByteArray );

我在 winforms 应用程序中使用它,从我们也在 Web 应用程序中使用的 Razor Views 生成和保存 PDF。

于 2014-04-15T15:33:29.683 回答
0

我能够让Eric Brown-Cal的解决方案正常工作,但我需要进行一些小调整以防止出现关于找不到目录的错误。

(另外,查看 Rotativa 代码,似乎 -q 开关已默认传递,因此可能没有必要,但我没有更改它。)

var bytes = Rotativa.WkhtmltopdfDriver.ConvertHtml(Server.MapPath(@"/Rotativa"), "-q", html);
于 2015-11-02T15:02:08.490 回答