ASP.NET Core中的Azure上的幻影pdf

时间:2017-02-26 18:46:15

标签: azure asp.net-core pdf-generation jsreport

我正在使用jsreportphantom pdf recipeASP.NET Core中将视图呈现为pdf。该项目在Azure中作为App Service运行。这在我的本地计算机上工作正常,但是当我发布到Azure时,我收到以下错误消息。

Exception: Call to Node module failed with error: ReferenceError: e is not defined at module.exports (D:\home\site\wwwroot\serviceCallDetailsPdf.js:18:26)

这是我的js文件,它位于我的项目的根目录中(与wwwroot相同的目录级别,视图,控制器等)。

module.exports = function (callback, html, htmlFooter) {
    var jsreport = require('jsreport-core')();

    jsreport.init().then(function () {
        return jsreport.render({
            template: {
                content: html,
                engine: 'jsrender',
                recipe: 'phantom-pdf',
                phantom: {
                    orientation: "landscape",
                    allowLocalFilesAccess: true,
                    footer: htmlFooter
                }
            }
        }).then(function (resp) {
            callback(/* error */ null, resp.content.toString());
        });
    }).catch(function (e) {
        callback(/* error */ e, null);
    });

    callback(/* error */ e, null);
};

注意:最后一次回拨通常不会出现。如果我删除它,我得到的错误更改为Node.js模块在60000毫秒后超时,当然它需要60秒才能显示。

我必须更新我的project.json文件以在*.js中包含node_modulespublishOptions,否则我会收到错误消息,指出Node.js无法对文件进行处理我在打电话。我知道这不是正确的方法(应该使用Gulp只复制我需要的东西,但我只想让它先工作)。

我已将services.AddNodeServices();添加到ConfigureServices,并"Microsoft.AspNetCore.NodeServices": "1.1.0"添加到project.json

以下是我自动生成的package.json文件:

{
  "name": "projectname",
  "version": "1.0.0",
  "description": "",
  "main": "serviceCallDetailsPdf.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "jsreport-core":"1.1.1",
    "jsreport-jsrender": "1.0.1",
    "jsreport-phantom-pdf": "1.3.1"
  }
}

最后,这是我的Action

[HttpGet]
public async Task<IActionResult> ServiceCallDetailsToPdf(int id)
{
    var call = _repository.PullCallDetails(id, User.Identity.RegionId(), User.Identity.TimeZoneOffsetId());

    // Render view as string
    var html = await _viewRenderService.RenderToStringAsync("Render/ServiceCallDetailsPdf", call);
    html = html.Replace("<style></style>", @"<style>@font-face{font-family:'Open Sans';src:url({#asset OpenSans-Regular.ttf @encoding=dataURI});format('ttf');}*{font-family:'Open Sans';}h2{font-weight:300;line-height:1.1;}</style>");

    var htmlFooter = "<style>*{font-family:'Open Sans';text-align:center;}</style>" + "Page {#pageNum} of {#numPages}";

    // Invoke node job to create the pdf
    var result = await _nodeServices.InvokeAsync<byte[]>("./serviceCallDetailsPdf", html, htmlFooter);

    // Content disposition 'inline' will return the pdf to the browser and not download it
    var contentDisposition = new ContentDispositionHeaderValue("inline");
    // Add file name to content disposition so if it is downloaded, it uses the correct file name
    contentDisposition.SetHttpFileName("dispatch" + id.ToString() + ".pdf");
    Response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString();

    return File(result, "application/pdf");
}

是否可以调试正在调用的javascript文件?我花了几天时间和数小时试图弄清楚为什么这不会起作用。任何帮助将不胜感激。

更新

我相信我从这些链接中找到了答案:

https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox

PhantomJS as web job in Azure

这基本上意味着您无法在Azure应用服务中使用幻像pdf配方。其他人可以确认吗?如果是这种情况,是否有人知道将在Azure应用服务中使用的HTML到pdf渲染器?

1 个答案:

答案 0 :(得分:1)

phantomjs和其他pdf呈现在默认Windows Server上运行的Azure App服务中不起作用。但是,您现在可以使用在Linux上运行的Azure应用服务,其中jsreport非常适用。

在创建新的App Service并使用基于节点的容器时,您只需要在Linux上切换到Web App。然后,您可以使用docker hub将带有jsreport的图像下载到Web App中。最简单的是使用官方的jsreport图像,但它也很容易使用。

<强>链接
Tutorial how run jsreport on Azure Web App on linux
jsreport official docker image

我知道我没有回答如何在与asp.net核心相同的应用程序中实际运行它。我目前不知道该怎么做,但我建议你在不同的应用程序中运行asp.net应用程序和jsreport。您可以通过REST轻松调用jsreport呈现。这也可以改善您的架构设计。