我使用Rotativa工具来显示PDF。它工作在本地主机上正常,但在Azure平台不起作用 [英] I am using Rotativa tool to display pdf. It works fine on localhost, But does not work on Azure platform

查看:1605
本文介绍了我使用Rotativa工具来显示PDF。它工作在本地主机上正常,但在Azure平台不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Rotativa工具来显示PDF。它的工作原理罚款本地主机,但在天青的平台。

I am using Rotativa tool to display PDF. It works fine on localhost, But does not work on Azure platform.

下面是我的code ...

Below is my code...

public ActionResult GeneratePDF(int id = 0)
    {
        ReportTransactionData reporttransactiondata = db.ReportTransactionDatas.Find(id);
        var viewFileToPrint = @"~/Views/ReportTranData/PDFReport.cshtml";
        //var oRotativaPDF = new Rotativa.ViewAsPdf();
        var oRotativaPDF = new Rotativa.PartialViewAsPdf();
        try
        {
            if (reporttransactiondata == null)
            {
                return HttpNotFound();
            }
            else
            {
                // Populate reporttransactiondata with Verfier Name...TO BE IMPLEMENTED LATER...
                //reporttransactiondata.VerifierName = GetVerifierNameByID(reporttransactiondata.VerifierID);
            }

            // Code to call a function/action...
            //return new Rotativa.ActionAsPdf("PrintRptInPDF", reporttransactiondata) 

            //oRotativaPDF = new Rotativa.ViewAsPdf(viewFileToPrint, reporttransactiondata)
            //        {
            //            FileName = "Technician Job Report.pdf",
            //            PageSize = Size.A4,
            //            PageOrientation = Orientation.Portrait,
            //            PageMargins = new Margins(0, 0, 0, 0),
            //            PageWidth = 230,      //250      //300  // 350
            //            PageHeight = 360,      // 380   // 400 //420  // 450
            //            CustomSwitches = "--disable-smart-shrinking"
            //        };

            oRotativaPDF = new Rotativa.PartialViewAsPdf(viewFileToPrint, reporttransactiondata)
            {
                FileName = "Technician Job Report.pdf",
                PageSize = Size.A4,
                PageOrientation = Orientation.Portrait,
                PageMargins = new Margins(0, 0, 0, 0),
                PageWidth = 230,      //250      //300  // 350
                PageHeight = 360,      // 380   // 400 //420  // 450
                CustomSwitches = "--disable-smart-shrinking"
            };
        }
        catch (Exception ex)
        {
            // TODO: Code here...
        }

        return oRotativaPDF;
    }

请忽略评论code。这只是正常,但是当我部署我的web应用程序,PDF文件不是在客户端下载和一段时间后,我的IE浏览器显示500内部服务器错误。

Please ignore the commented code. This works just fine but when I deploy my web application, the PDF file is not downloaded at client side and after some time my IE browser display 500 internal server error.

我探讨这个问题进一步,来到知道,这个错误可能是因为wkhtmltopdf.exe没有对自己在Azure平台上执行。所以我就用一些搜索上有关该问题的决议净...

I explored the issue further and came to know that this error may be because wkhtmltopdf.exe does not execute on its own on Azure platform. So I came with the following solution with the help of some search on the net about the issue resolution...

公众的ActionResult GeneratePDF(INT ID = 0)
        {
            ReportTransactionData reporttransactiondata = db.ReportTransactionDatas.Find(ID);
            字符串的viewName = @〜/查看/ ReportTranData / PDFReport.cshtml
            字符串wkhtmltopdfPath =使用Server.Mappath(@〜/ Rotativa /);
            板开关=的String.Empty;
            尝试
            {
                如果(reporttransactiondata == NULL)
                {
                    返回HttpNotFound();
                }

public ActionResult GeneratePDF(int id = 0) { ReportTransactionData reporttransactiondata = db.ReportTransactionDatas.Find(id); string viewName = @"~/Views/ReportTranData/PDFReport.cshtml"; string wkhtmltopdfPath = Server.MapPath(@"~/Rotativa/"); string switches = string.Empty; try { if (reporttransactiondata == null) { return HttpNotFound(); }

            string fullPath = Server.MapPath(@"~/ApplicationFiles/TechnicianJobReport.pdf");
            FileInfo objFileInfo = new System.IO.FileInfo(fullPath);
            if (objFileInfo.Exists)
            {
                objFileInfo.Delete();
            }

            string sViewString = RenderRazorViewToString(viewName, reporttransactiondata);
            var byteArray = ConvertHTMLtoPDF(wkhtmltopdfPath, switches, sViewString);
            var fileStream = new FileStream(fullPath, FileMode.Create, FileAccess.Write);
            fileStream.Write(byteArray, 0, byteArray.Length);
            fileStream.Close();

            // Download file at client side...
            Response.Clear();
            Response.ClearContent();
            Response.ClearHeaders();
            Response.Charset = "UTF-8";
            Response.ContentEncoding = Encoding.UTF8;
            Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(objFileInfo.Name));
            Response.ContentType = "application/pdf";
            Response.WriteFile(objFileInfo.FullName);
            Response.End();

        }
        catch (Exception ex)
        {
            // Handle exception here and Log Error to file...
            Repositories.Repository objRepository = new Repositories.Repository();
            string sLogFilePath = Server.MapPath(@"~/ApplicationFiles/ErrorLogFile.txt");
            objRepository.LogErrorToFile(ex, sLogFilePath, this.ControllerContext.Controller.ToString());
        }

        return View(reporttransactiondata);
    }
    public string RenderRazorViewToString(string viewName, object model)
    {
        ViewData.Model = model;
        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext,viewName);
            var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);
            viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
            return sw.GetStringBuilder().ToString();
        }
    }

    /// <summary>
    /// Converts given URL or HTML string to PDF.
    /// </summary>
    /// <param name="wkhtmltopdfPath">Path to wkthmltopdf.</param>
    /// <param name="switches">Switches that will be passed to wkhtmltopdf binary.</param>
    /// <param name="html">String containing HTML code that should be converted to PDF.</param>
    /// <returns>PDF as byte array.</returns>
    private static byte[] ConvertHTMLtoPDF(string wkhtmltopdfPath, string switches, string html)
    {
        // switches:
        //     "-q"  - silent output, only errors - no progress messages
        //     " -"  - switch output to stdout
        //     "- -" - switch input to stdin and output to stdout
        switches = "-q " + switches + " -";

        // generate PDF from given HTML string, not from URL
        if (!string.IsNullOrEmpty(html))
            switches += " -";

        var proc = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = Path.Combine(wkhtmltopdfPath, "wkhtmltopdf.exe"),
                Arguments = switches,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                RedirectStandardInput = true,
                WorkingDirectory = wkhtmltopdfPath,
                CreateNoWindow = true
            }
        };
        proc.Start();

        // generate PDF from given HTML string, not from URL
        if (!string.IsNullOrEmpty(html))
        {
            using (var sIn = proc.StandardInput)
            {
                sIn.WriteLine(html);
            }
        }

        var ms = new MemoryStream();
        using (var sOut = proc.StandardOutput.BaseStream)
        {
            byte[] buffer = new byte[4096];
            int read;

            while ((read = sOut.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
        }

        string error = proc.StandardError.ReadToEnd();

        if (ms.Length == 0)
        {
            throw new Exception(error);
        }

        proc.WaitForExit();

        return ms.ToArray();
    }

但是,这一次正常工作本地主机,但不能在Azure服务器上,并给出了也不例外相同的500内部服务器错误的。请参阅如果有人能帮助在这里。我用这wkhtmltopdf exe,因为我可以指定根据我(一半A4页面大小)的纸张尺寸要求PDF的高度和宽度。如果有任何其他的选择,我可能不会在执行外部EXE或DLL的问题结束了,请建议选项了。

But this again works fine on localhost but not on Azure server and gives the same 500 internal server error with no exception at all. Please see if anyone can help here. I am using this wkhtmltopdf exe because I can specify the height and width of the pdf according to my (half of A4 page size) paper size requirement. If there is any other option where I may not end up in the issue of executing an external exe or dll, please suggest that option too.

推荐答案

赞(#Fabrizio Accatino)写道:Rotativa运行wkhtmltopdf.exe。它位于Rotativa文件夹中项目的根目录下。因此,问题可能是:

Like (#Fabrizio Accatino) wrote: Rotativa is running wkhtmltopdf.exe. It is located in "Rotativa" folder under the root of your project. So the issue could be:


  1. 在部署期间 - 未创建Rotativa文件夹(请确保您添加的文件夹,并在该项目中的.exe和始终复制设置文件的财产)

  2. 有服务器上缺少的库(保证有psented服务器上$ P $ - msvcp120.dll和msvcr120.dll / SYSWOW64文件夹下/)

  3. 确保应用程序池用户有需要的权限来运行可执行文件,并存储临时.pdf文件。

  4. 确保路径名不超过最大长度(250位,我认为)。

我希望这将引导您解决问题。

I hope this will guide you for solving the problem.

这篇关于我使用Rotativa工具来显示PDF。它工作在本地主机上正常,但在Azure平台不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆