ASP.NET核心中Azure上的幻影pdf
我正在使用ASP.NET核心中Azure上的幻影pdf,azure,asp.net-core,pdf-generation,jsreport,Azure,Asp.net Core,Pdf Generation,Jsreport,我正在使用jsreport和phantom pdf recipe在ASP.NET核心中以pdf格式呈现视图。该项目正在Azure中作为应用程序服务运行。这在我的本地机器上运行良好,但当我发布到Azure时,我收到以下错误消息 异常:调用节点模块失败,错误为:ReferenceError:e未定义 在module.exports(D:\home\site\wwwroot\serviceCallDetailsPdf.js:18:26) 这是我的js文件,它位于我的项目根目录中(与wwwroot、视图
jsreport
和phantom pdf recipe
在ASP.NET核心中以pdf格式呈现视图。该项目正在Azure
中作为应用程序服务运行。这在我的本地机器上运行良好,但当我发布到Azure时,我收到以下错误消息
异常:调用节点模块失败,错误为:ReferenceError:e未定义
在module.exports(D:\home\site\wwwroot\serviceCallDetailsPdf.js:18:26)
这是我的js
文件,它位于我的项目根目录中(与wwwroot、视图、控制器等目录级别相同)
注意:最后一次回电话通常不在那里。如果我删除它,那么在60000毫秒之后,Node.js模块的更改就会超时,当然,它需要60秒才能显示出来
我必须更新我的project.json
文件,以便在publishOptions
中包含*.js
和node\u模块
,否则我会收到一个错误,说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"
}
}
最后,这里是我的操作
:
[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");
}
[HttpGet]
公共异步任务服务CallDetailStopDF(int id)
{
var call=_repository.PullCallDetails(id,User.Identity.RegionId(),User.Identity.TimeZoneOffsetId());
//将视图渲染为字符串
var html=await _viewRenderService.RenderToStringAsync(“Render/serviceCallDetailsDf”,call);
html=html.Replace(“,@”@font-face{font-family:'OpenSans';src:url({#asset OpenSans-Regular.ttf@encoding=dataURI});format('ttf');}*{font-family:'OpenSans';}h2{font-weight:300;线宽:1.1;}”);
var htmlFooter=“*{font-family:'opensans';text-align:center;}”+“第{pageNum}页,共{numPages}”;
//调用节点作业以创建pdf
var result=await _nodeServices.InvokeAsync(“./serviceCallDetailsPdf”,html,htmlFooter);
//内容处置“内联”将pdf返回到浏览器,而不是下载
var contentDisposition=新ContentDispositionHeaderValue(“内联”);
//将文件名添加到内容处置,以便在下载时使用正确的文件名
contentDisposition.SetHttpFileName(“dispatch”+id.ToString()+”.pdf”);
Response.Headers[HeaderNames.ContentDisposition]=ContentDisposition.ToString();
返回文件(结果,“应用程序/pdf”);
}
是否可以调试正在调用的javascript
文件?我花了几天和无数个小时试图弄明白为什么这行不通。任何帮助都将不胜感激
更新
我相信我从以下链接中找到了答案:
这基本上意味着您不能在Azure应用程序服务中使用幻影pdf配方。还有谁能证实吗?如果是这种情况,是否有人知道html到pdf呈现程序将在Azure应用程序服务中工作?phantomjs和其他pdf呈现程序将在默认Windows服务器上运行的Azure应用程序服务中不工作。不过,您现在可以使用运行在linux上的Azure应用程序服务,jsreport在linux上运行得很好
在创建新的应用程序服务和使用基于节点的容器时,您只需要切换到Linux上的Web应用程序。然后,您可以使用docker hub将带有jsreport的图像下载到Web应用程序中。最简单的方法是使用正式的jsreport图像,但也很容易使用自己的图像
链接
我知道我没有回答如何在与asp.net core相同的应用程序中实际运行它。我现在不知道怎么做,但我建议您在不同的应用程序中运行asp.net应用程序和jsreport。您可以通过REST轻松调用jsreport呈现。这也可以改进您的架构设计。您已经通过链接到的另一个问题找到了答案(基本上这是该问题的重复)。不能在Web应用程序中使用ActiveX/GDI等。
[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");
}