ASP.NET Core中Azure上的Phantom pdf [英] Phantom pdf on Azure in ASP.NET Core

查看:97
本文介绍了ASP.NET Core中Azure上的Phantom pdf的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using jsreport and the phantom pdf recipe to render a View as a pdf in ASP.NET Core. The project is running in Azure as an App Service. This works fine on my local machine, but when I publish to Azure, I get the below error message.

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

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,Views,Controllers等相同的目录级别).

Here is my js file that is in the root of my project (same directory level as wwwroot, Views, Controllers, etc).

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秒.

Note: The very last call back usually would not be there. If I remove it, the error I get changes to the Node.js module timing out after 60000 milliseconds and of course it takes 60 seconds for it to display.

我必须更新我的project.json文件以在publishOptions中包含*.jsnode_modules,否则我会收到一条错误消息,说Node.js无法对我正在调用的文件进行优化.我知道这不是执行此操作的正确方法(应该使用Gulp仅复制我需要的内容,但我只想先使其工作).

I had to update my project.json file to include *.js and node_modules in publishOptions otherwise I would get an error saying Node.js could not fine the file I am calling. I know this is not the proper way to do this (should use Gulp to copy only what I need, but I just want to get it working first).

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

I've added services.AddNodeServices(); to ConfigureServices and also "Microsoft.AspNetCore.NodeServices": "1.1.0" to project.json.

这是我的package.json文件,它是自动生成的:

Here is my package.json file that was auto-generated:

{
  "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文件?我花了几天和大量的时间试图弄清楚为什么它不起作用.任何帮助将不胜感激.

Is it possible to debug the javascript file that is being called? I've spent a few days and numerous hours trying to figure out why this won't work. Any help would be greatly appreciated.

更新

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

I believe I found my answer from these links:

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

PhantomJS作为Azure中的Web作业

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

This basically means you cannot use the phantom pdf recipe in an Azure App Service. Can anyone else confirm? If this is the case, does anyone know of a html to pdf renderer that will work in an Azure App Service?

推荐答案

phantomjs和其他pdf渲染在默认Windows Server上运行的Azure App服务中不起作用.但是,您现在可以使用在jsreport可以正常工作的linux上运行的Azure App服务.

phantomjs and other pdf rendering won't work in Azure App service running on default Windows Server. However you can now use Azure App service running on linux where jsreport nicely works.

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

You just need to switch to Web App on Linux when creating new App Service and use node based container. Then you can use docker hub to download an image with jsreport right into the Web App. The simplest is to use official jsreport image but it is easy to use also your own.

链接
教程如何在Linux上的Azure Web App上运行jsreport
jsreport官方docker镜像

Links
Tutorial how run jsreport on Azure Web App on linux
jsreport official docker image

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

I'm aware I didn't answer how to actually run it in the same app as asp.net core. I don't know how to do that currently, but I suggest you to run asp.net application and jsreport in separate apps. You can easily invoke jsreport rendering through REST. This could also improve your architecture design.

这篇关于ASP.NET Core中Azure上的Phantom pdf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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