在悬空工作中生成/发送PDF电子邮件附件



在我们的ASP.NET MVC Web应用程序中,我们发送电子邮件作为Hangfire处理的计划任务的一部分该方法运行良好,我们能够发送HTML/文本电子邮件。现在,我们还需要生成并附加PDF文件。需要通过使用剃须刀模板动态生成附件的PDF。首先,我尝试使用rotativa来生成PDF。但是,我遇到的问题是,方法buildpdf需要一个ContranceerContext,该控制权在背景过程中不可用。我试图将ControllerContext伪造为

using (var memWriter = new StringWriter(sb))
            {
                var fakeResponse = new HttpResponse(memWriter);
                var fakeRequest = new HttpRequest(null, "http://wwww.oururl.com", null);
                var fakeHttpContext = new HttpContext(fakeRequest, fakeResponse);
                var emailController = new BackgroundEmailController();
                var fakeControllerContext = new ControllerContext(new HttpContextWrapper(fakeHttpContext), new RouteData(), emailController);
                var attachment = emailController.BillAttachment(email);
                var pdf = attachment.BuildPdf(fakeControllerContext);
                if (pdf != null && pdf.Count() > 0)
                {
                    using (MemoryStream ms = new MemoryStream(pdf))
                    {
                        var contentType = new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Application.Pdf);
                        email.Attach(new System.Net.Mail.Attachment(ms, contentType));
                    }
                }
            }              

然而,这引起了rotativa中的无用误差。 然后,我首先尝试将Razorengine编译为HTML(然后以某些平均值将HTML转换为PDF)为

var engineService = RazorEngineService.Create();
            engineService.AddTemplate(cache_name, File.ReadAllText(billAttachmentTemplatePath));
            engineService.Compile(cache_name, modelType: typeof(BillEmail));
            var html = engineService.Run(cache_name, null, email);
            using (var ms = CommonHelper.GenerateStreamFromString(html))
            {
                var contentType = new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Text.Html);
                email.Attach(new System.Net.Mail.Attachment(ms, contentType));
            }

,它在razorengine Dynamic Dll中抛出了另一个无用:

 System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_bb2b366aaef64f2bbc2997353f88cc9e.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)

我想知道是否有人在hangfire过程中从模板中生成PDF文件?

如果您向商业解决方案开放,则可以尝试 telerik报告并以PDF的方式导出。您可以定义报告,然后调用它以在服务器端生成PDF,最后通过电子邮件将BYTE []发送给电子邮件附件。您现在可以使用hangfire作业开始此过程。

这是假设您已经定义了报告结构的伪代码,请在此处查找有关如何以编程方式创建报告的更多详细信息。

public void GenerateAndEmailReport()
{     
    var reportSource = new InstanceReportSource();
    Telerik.Reporting.Report report = new MyReport();
    //populate data into report
    reportSource.ReportDocument = report;
    var reportProcessor = new ReportProcessor();
    reportSource.ReportDocument = report;
    var info = new Hashtable();
    var result= reportProcessor.RenderReport("PDF", reportSource, info);
    byte[]reportBytes = result.DocumentBytes;
    SendEmail(reportBytes, "myreport.pdf"); // a method that takes the bytes and attach it to email. 
}

Telerik的其他参考。

  • 将报告发送为电子邮件
  • 在控制台应用程序中生成PDF
  • 通过编程保存报告

最新更新