如何使用 Hangfire 在 BackgroundJob 中使用 Rotativa 获取 ControllerContext 来构建 PDF
How to get ControllerContext to build PDF using Rotativa in BackgroundJob with Hangfire
我必须在我的后台应用程序中发送邮件,为此我使用 Hangfire,但我必须在每封邮件中附加一个文件及其收件人,文件的信息附加在我用 rotativa 转换的 table 中。
我担心的是,当我想将文档转换为 byte[]
时,我总是得到 HttpContext
是 null
,显然是因为没有 HTTP 请求触发操作一切都在后台。
这是我的实际代码:
var Avis_views = new ViewAsPdf("~/Views/AvisAutomatique/ExportPdfDebit.cshtml", printa)
{
PageMargins = new Rotativa.Options.Margins(0, 0, 0, 0),
MinimumFontSize = 14,
/*ageHeight=60,*/
PageOrientation = Rotativa.Options.Orientation.Portrait,
PageSize = Rotativa.Options.Size.A4,
};
var fileName = "DEBITADVISE_" + Numcpt + "_" + _GetTransDateTime() + ".pdf";
//var path = Path.Combine(@"C:\DocumentPdf\", fileName);
byte[] abc = Avis_views.BuildFile(quotesController.ControllerContext);
//System.IO.File.WriteAllBytes(path, abc);
MemoryStream ms = new MemoryStream(abc);
sendemail(email, fileName, abc, emailc);
有人可以帮我从控制器初始化 httpcontext 吗?
Rotativa lib 中似乎有一个问题,它必须采用控制器上下文,github。com/webgio/Rotativa/pull/88
并且您将无法像您列出的那样将上下文传递给 hangfire 后台进程。
解决方法(如果文件不是太大)可能是您的 hangfire 进程在您的网站上调用 URL 执行电子邮件发送代码,而不是在 hangfire 中执行 Rotativa 和电子邮件发送后台进程。
我是 Rotativa 的作者和 rotativa.io 云服务的所有者。
在 SaaS 版本的 rotativa 中,您可以使用 Nuget 库,它可以让您从剃刀视图构建 PDF,而无需参考 Asp.net:
https://rotativa.io/site/blog/instructions/2020/07/31/create-pdf-in-net-core-without-aspnet.html
您可以按照 Giogio Bozio 的建议检查云服务,或者,如果您打算使用当前的 Rotativa DLL,您可以尝试我在评论中建议的解决方案。
您的代码应如下所示(您提供的代码中嵌入了示例解决方案):
var Avis_views = new ViewAsPdf("~/Views/AvisAutomatique/ExportPdfDebit.cshtml", printa)
{
PageMargins = new Rotativa.Options.Margins(0, 0, 0, 0),
MinimumFontSize = 14,
/*ageHeight=60,*/
PageOrientation = Rotativa.Options.Orientation.Portrait,
PageSize = Rotativa.Options.Size.A4,
};
var fileName = "DEBITADVISE_" + Numcpt + "_" + _GetTransDateTime() + ".pdf";
//var path = Path.Combine(@"C:\DocumentPdf\", fileName);
// Create an instance of your controller class (in example, I guess you are using mentioned quotesController)
QuotesController controllerInstance = new QuotesController();
// Generate RouteData based in your controller (even if you are not using on in this situation, you can reference an existent one)
RouteData route = new RouteData();
// Simply change "MyAction" and "QuotesController" for the name of real action name and controller, respectively
route.Values.Add("action", "MyAction");
route.Values.Add("controller", "QuotesController");
// Generate controller context, to use in the next step
ControllerContext newContext = new ControllerContext(new HttpContextWrapper(System.Web.HttpContext.Current), route, controllerInstance);
byte[] abc = Avis_views.BuildFile(newContext); // Here you send the generated controller context
//System.IO.File.WriteAllBytes(path, abc);
MemoryStream ms = new MemoryStream(abc);
sendemail(email, fileName, abc, emailc);
请检查它是否适合您,并且不要忘记包含所需的参考资料:
using System.Web;
using System.Web.Routing;
using System.Web.Mvc;
在尝试使用 rotativa 一周后,我用 Itextsharp 资助了另一个解决方案,下面是我的做法:
1-首先安装包 ItextSharp 和 ItextSharp XMLWorker
2- 我在 html 页面中设计了我的模板,其中 css 将它们放在
文件夹中(@"C:\Templates\Credit.html"; @" C:\Templates\pdfview.css";)
3-用这个方法阅读 html 和 css
public string RenderViewToString(string viewPath)
{
var file = new FileInfo(viewPath);
using (StreamReader streamReader = file.OpenText())
{
string viewLine = "";
var result = string.Empty;
while ((viewLine = streamReader.ReadLine()) != null)
{
result = result + viewLine;
}
return result;
}
}
并使用此方法转换为 pdf:
public byte[] GetPDF(string param1,string param2,etc...)
{
byte[] bPDF = null;
try
{
pHTML = pHTML.Replace("{{parameter form the html file}}", param1);
pHTML = pHTML.Replace("{{parameter form the html file}}", param2);
MemoryStream ms = new MemoryStream();
TextReader txtReader = new StringReader(pHTML.ToString());
var image = @"C:\Templates\avis.jpg";
iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(image);
jpg.SpacingBefore = 10f;
jpg.ScaleToFit(50, 50);
jpg.Alignment =iTextSharp.text.Image.ALIGN_RIGHT;
doc.Open();
doc.Add(jpg);
using (var cssMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(csstemp)))
{
using (var htmlMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(pHTML)))
{
XMLWorkerHelper.GetInstance().ParseXHtml(oPdfWriter, doc, htmlMemoryStream, cssMemoryStream);
}
}
//htmlWorker.StartDocument();
//// 5: parse the html into the document
//htmlWorker.Parse(txtReader);
//// 6: close the document and the worker
//htmlWorker.EndDocument();
//htmlWorker.Close();
doc.Close();
bPDF = ms.ToArray();
return bPDF;
}
catch (Exception ex)
{
var mess = ex.StackTrace;
var mess2 = ex.Message;
}
return bPDF;
}
感谢您希望对某人有所帮助
我必须在我的后台应用程序中发送邮件,为此我使用 Hangfire,但我必须在每封邮件中附加一个文件及其收件人,文件的信息附加在我用 rotativa 转换的 table 中。
我担心的是,当我想将文档转换为 byte[]
时,我总是得到 HttpContext
是 null
,显然是因为没有 HTTP 请求触发操作一切都在后台。
这是我的实际代码:
var Avis_views = new ViewAsPdf("~/Views/AvisAutomatique/ExportPdfDebit.cshtml", printa)
{
PageMargins = new Rotativa.Options.Margins(0, 0, 0, 0),
MinimumFontSize = 14,
/*ageHeight=60,*/
PageOrientation = Rotativa.Options.Orientation.Portrait,
PageSize = Rotativa.Options.Size.A4,
};
var fileName = "DEBITADVISE_" + Numcpt + "_" + _GetTransDateTime() + ".pdf";
//var path = Path.Combine(@"C:\DocumentPdf\", fileName);
byte[] abc = Avis_views.BuildFile(quotesController.ControllerContext);
//System.IO.File.WriteAllBytes(path, abc);
MemoryStream ms = new MemoryStream(abc);
sendemail(email, fileName, abc, emailc);
有人可以帮我从控制器初始化 httpcontext 吗?
Rotativa lib 中似乎有一个问题,它必须采用控制器上下文,github。com/webgio/Rotativa/pull/88
并且您将无法像您列出的那样将上下文传递给 hangfire 后台进程。
解决方法(如果文件不是太大)可能是您的 hangfire 进程在您的网站上调用 URL 执行电子邮件发送代码,而不是在 hangfire 中执行 Rotativa 和电子邮件发送后台进程。
我是 Rotativa 的作者和 rotativa.io 云服务的所有者。
在 SaaS 版本的 rotativa 中,您可以使用 Nuget 库,它可以让您从剃刀视图构建 PDF,而无需参考 Asp.net:
https://rotativa.io/site/blog/instructions/2020/07/31/create-pdf-in-net-core-without-aspnet.html
您可以按照 Giogio Bozio 的建议检查云服务,或者,如果您打算使用当前的 Rotativa DLL,您可以尝试我在评论中建议的解决方案。
您的代码应如下所示(您提供的代码中嵌入了示例解决方案):
var Avis_views = new ViewAsPdf("~/Views/AvisAutomatique/ExportPdfDebit.cshtml", printa)
{
PageMargins = new Rotativa.Options.Margins(0, 0, 0, 0),
MinimumFontSize = 14,
/*ageHeight=60,*/
PageOrientation = Rotativa.Options.Orientation.Portrait,
PageSize = Rotativa.Options.Size.A4,
};
var fileName = "DEBITADVISE_" + Numcpt + "_" + _GetTransDateTime() + ".pdf";
//var path = Path.Combine(@"C:\DocumentPdf\", fileName);
// Create an instance of your controller class (in example, I guess you are using mentioned quotesController)
QuotesController controllerInstance = new QuotesController();
// Generate RouteData based in your controller (even if you are not using on in this situation, you can reference an existent one)
RouteData route = new RouteData();
// Simply change "MyAction" and "QuotesController" for the name of real action name and controller, respectively
route.Values.Add("action", "MyAction");
route.Values.Add("controller", "QuotesController");
// Generate controller context, to use in the next step
ControllerContext newContext = new ControllerContext(new HttpContextWrapper(System.Web.HttpContext.Current), route, controllerInstance);
byte[] abc = Avis_views.BuildFile(newContext); // Here you send the generated controller context
//System.IO.File.WriteAllBytes(path, abc);
MemoryStream ms = new MemoryStream(abc);
sendemail(email, fileName, abc, emailc);
请检查它是否适合您,并且不要忘记包含所需的参考资料:
using System.Web;
using System.Web.Routing;
using System.Web.Mvc;
在尝试使用 rotativa 一周后,我用 Itextsharp 资助了另一个解决方案,下面是我的做法:
1-首先安装包 ItextSharp 和 ItextSharp XMLWorker
2- 我在 html 页面中设计了我的模板,其中 css 将它们放在
文件夹中(@"C:\Templates\Credit.html"; @" C:\Templates\pdfview.css";)
3-用这个方法阅读 html 和 css
public string RenderViewToString(string viewPath)
{
var file = new FileInfo(viewPath);
using (StreamReader streamReader = file.OpenText())
{
string viewLine = "";
var result = string.Empty;
while ((viewLine = streamReader.ReadLine()) != null)
{
result = result + viewLine;
}
return result;
}
}
并使用此方法转换为 pdf:
public byte[] GetPDF(string param1,string param2,etc...)
{
byte[] bPDF = null;
try
{
pHTML = pHTML.Replace("{{parameter form the html file}}", param1);
pHTML = pHTML.Replace("{{parameter form the html file}}", param2);
MemoryStream ms = new MemoryStream();
TextReader txtReader = new StringReader(pHTML.ToString());
var image = @"C:\Templates\avis.jpg";
iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(image);
jpg.SpacingBefore = 10f;
jpg.ScaleToFit(50, 50);
jpg.Alignment =iTextSharp.text.Image.ALIGN_RIGHT;
doc.Open();
doc.Add(jpg);
using (var cssMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(csstemp)))
{
using (var htmlMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(pHTML)))
{
XMLWorkerHelper.GetInstance().ParseXHtml(oPdfWriter, doc, htmlMemoryStream, cssMemoryStream);
}
}
//htmlWorker.StartDocument();
//// 5: parse the html into the document
//htmlWorker.Parse(txtReader);
//// 6: close the document and the worker
//htmlWorker.EndDocument();
//htmlWorker.Close();
doc.Close();
bPDF = ms.ToArray();
return bPDF;
}
catch (Exception ex)
{
var mess = ex.StackTrace;
var mess2 = ex.Message;
}
return bPDF;
}
感谢您希望对某人有所帮助