2

Rotativa tool用来显示PDF。它在 上运行良好,但在平台localhost上不起作用。Azure

下面是我的代码...

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

请忽略注释的代码。这工作得很好,但是当我部署我的 Web 应用程序时,PDF 文件没有在客户端下载,一段时间后我的 IE 浏览器显示 500 内部服务器错误。

我进一步探讨了这个问题,发现这个错误可能是因为 wkhtmltopdf.exe 在 Azure 平台上无法自行执行。所以我在网上搜索了一些关于问题解决方案的帮助,提出了以下解决方案......

公共 ActionResult GeneratePDF(int id = 0) { ReportTransactionData reporttransactiondata = db.ReportTransactionDatas.Find(id); 字符串 viewName = @"~/Views/ReportTranData/PDFReport.cshtml"; string wkhtmltopdfPath = Server.MapPath(@"~/Rotativa/"); 字符串开关 = string.Empty; 尝试 { 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();
    }

但这在 localhost 上又可以正常工作,但在 Azure 服务器上却不行,并且完全没有例外地给出相同的 500 内部服务器错误。请看看是否有人可以在这里提供帮助。我正在使用这个 wkhtmltopdf exe,因为我可以根据我的(A4 页面大小的一半)纸张尺寸要求指定 pdf 的高度和宽度。如果有任何其他选项可能不会导致执行外部 exe 或 dll 的问题,请也建议该选项。

4

3 回答 3

7

Like (#Fabrizio Accatino) 写道:Rotativa 正在运行 wkhtmltopdf.exe。它位于项目根目录下的“Rotativa”文件夹中。所以问题可能是:

  1. 在部署期间 - Rotativa 文件夹未创建(确保您已在项目中添加文件夹和 .exe 并将文件的属性设置为“始终复制”)。
  2. 服务器上缺少库(确保服务器上存在 - msvcp120.dll 和 msvcr120.dll /under sysWOW64 folder/)
  3. 确保应用程序池用户具有运行可执行文件和存储临时 .pdf 文件所需的权限。
  4. 确保路径名不超过最大长度(我认为是 250 位)。

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

于 2015-05-04T14:58:31.613 回答
0

我认为只有 azure 上的高级帐户才允许在服务器上运行 wkhtmltopdf.exe,或者您也可以使用此https://rotativahq.com/创建旋转 pdf

希望这对任何人都有帮助!

于 2018-12-06T11:58:46.520 回答
0

我有同样的问题,我通过升级到 1.6.3 版本的旋转来解决。按照链接 nuget:[ https://www.nuget.org/packages/Rotativa/1.6.3] [1]


在包管理器控制台中,键入:

  1. 卸载包旋转按 ENTER。
  2. 安装包旋转版本 1.6.3 按 ENTER。
  3. 检查旋转文件夹,如果您现在只是文件 * * wkhtmltopdf。可执行程序 * *。

评论

在 1.6.3 版本中,旋转不再使用文件:

  1. 自由32。dll
  2. LIBGCC_S_DW2-1。dll
  3. 铭文10。dll
  4. 自述文件。文本
  5. ssleay32. dll

它仅使用以下文件:

  1. wkhtmltopdf。可执行程序

但是,当升级到这个新版本时,轮换只更新这个文件wkhtmltopdf.exe到新的,替换它。

现在只需再次旋转它,它就会再次工作。

[1]:轮换升级到1.6.3版本

于 2018-12-05T13:52:04.287 回答