Hangfire + Crystal 报告电子邮件?
Hangfire + Crystal Reports email?
我正在努力做到这一点,以便我们可以每天生成某些报告并将它们通过电子邮件发送给列表中的一群人。
我已经针对重复性作业测试了 Hangfire,它运行良好。所以这不是问题。但我正在尝试从我现有的 Crystal 报告文件 (.rpt) 创建报告。基本上我想做的是当这个工作被执行时,代码会创建报告,将它作为 PDF 保存到指定路径的磁盘,然后我可以将它作为附件通过电子邮件发送给人们。因此无需能够在网页上查看报告。这个想法是从字面上只在后台代码中生成报告,将其保存为 PDF,并在保存后从后台代码通过电子邮件发送。
我遇到的问题与 crystal 报告的实际生成和保存有关。 顺便说一句,我在测试中生成了一个 excel 文件,但我会将其更改为 PDF 以用于实际报告。 这是我目前生成报告的内容:
string path = @"Save folder relative-path";
//"report" is declared at the class level and instantiated below.
report = new ReportDocument();
report.SetDatabaseLogon(ConfigurationManager.AppSettings["Username"], ConfigurationManager.AppSettings["Password"]);
report.Load(Server.MapPath("Relative path to the report"));
report.SetDataSource(GetDataSet()); //This gets the dataset filled with data for the report
try
{
ExportOptions options = new ExportOptions();
DiskFileDestinationOptions diskFileOptions = new DiskFileDestinationOptions();
ExcelFormatOptions excelOptions = new ExcelFormatOptions();
diskFileOptions.DiskFileName = path + "Test Report.xls";
options.ExportDestinationType = ExportDestinationType.DiskFile;
options.ExportFormatType = ExportFormatType.Excel;
options.ExportDestinationOptions = diskFileOptions;
options.ExportFormatOptions = excelOptions;
report.Export();
/*
This is where I would call a method to email the report to people
*/
}
catch (Exception ex)
{
Console.WriteLine("Error generating report: " + ex.Message);
}
此代码位于 Web 应用程序 global.asax 文件中的 Application_Start 处调用的方法中。当我 运行 应用程序时,作业失败并在我查看 Hangfire 仪表板中失败的作业时抛出此错误,即使我知道代码中的路径是正确的:
System.IO.FileNotFoundException Could not load file or assembly
'App_global.asax.twm32qri, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null' or one of its dependencies. The system cannot
find the file specified.
System.IO.FileNotFoundException: Could not load file or assembly
'App_global.asax.twm32qri, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null' or one of its dependencies. The system cannot
find the file specified. File name: 'App_global.asax.twm32qri,
Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' at
System.RuntimeTypeHandle.GetTypeByName(String name, Boolean
throwOnError, Boolean ignoreCase, Boolean reflectionOnly,
StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean
loadTypeFromPartialName, ObjectHandleOnStack type) at
System.RuntimeTypeHandle.GetTypeByName(String name, Boolean
throwOnError, Boolean ignoreCase, Boolean reflectionOnly,
StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean
loadTypeFromPartialName) at System.Type.GetType(String typeName,
Boolean throwOnError, Boolean ignoreCase) at
Hangfire.Storage.InvocationData.Deserialize()
WRN: Assembly binding logging is turned OFF. To enable assembly bind
failure logging, set the registry value
[HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1. Note: There
is some performance penalty associated with assembly bind failure
logging. To turn this feature off, remove the registry value
[HKLM\Software\Microsoft\Fusion!EnableLog].
编辑:
我也遇到了另一个错误。这个有事可做
加载报告文件。
Failed An exception occurred during performance of the job.
CrystalDecisions.CrystalReports.Engine.LoadSaveReportException
Invalid report file path.
CrystalDecisions.CrystalReports.Engine.LoadSaveReportException:
Invalid report file path. at
CrystalDecisions.CrystalReports.Engine.ExceptionThrower.ThrowEngineException(String
messageID, EngineExceptionErrorID id) at
CrystalDecisions.CrystalReports.Engine.ReportDocument.Load(String
filename, OpenReportMethod openMethod, Int16 parentJob) at
CrystalDecisions.CrystalReports.Engine.ReportDocument.EnsureLoadReport()
at
CrystalDecisions.CrystalReports.Engine.ReportDocument.SetDatabaseLogon(String
user, String password) at Intranet.Global.GenerateReport() in
path\Global.asax.cs:line 98
解决了问题。我显然需要使用 CrystalReportViewer 对象并将 ReportDocument 对象设置为其源。 CrystalReportViewer class 在 CrystalDecisions.Web 命名空间中。
using (ReportDocument report = new ReportDocument())
{
using (CrystalReportViewer viewer = new CrystalReportViewer())
{
string path = System.Web.Hosting.HostingEnvironment.MapPath(@"Destination path here");
report.Load(System.Web.Hosting.HostingEnvironment.MapPath(@"Path to .rpt file here"));
report.SetDatabaseLogon(ConfigurationManager.AppSettings["Username"], ConfigurationManager.AppSettings["Password"]);
string file = path + "TestReport.xls";
//These two lines below are important. The report won't generate without them.
viewer.ReportSource = report;
viewer.RefreshReport();
//Just deleting the file if it exists.
if (File.Exists(file))
File.Delete(file);
report.ExportToDisk(ExportFormatType.Excel, diskFileOptions.DiskFileName);
}
}
我正在努力做到这一点,以便我们可以每天生成某些报告并将它们通过电子邮件发送给列表中的一群人。
我已经针对重复性作业测试了 Hangfire,它运行良好。所以这不是问题。但我正在尝试从我现有的 Crystal 报告文件 (.rpt) 创建报告。基本上我想做的是当这个工作被执行时,代码会创建报告,将它作为 PDF 保存到指定路径的磁盘,然后我可以将它作为附件通过电子邮件发送给人们。因此无需能够在网页上查看报告。这个想法是从字面上只在后台代码中生成报告,将其保存为 PDF,并在保存后从后台代码通过电子邮件发送。
我遇到的问题与 crystal 报告的实际生成和保存有关。 顺便说一句,我在测试中生成了一个 excel 文件,但我会将其更改为 PDF 以用于实际报告。 这是我目前生成报告的内容:
string path = @"Save folder relative-path";
//"report" is declared at the class level and instantiated below.
report = new ReportDocument();
report.SetDatabaseLogon(ConfigurationManager.AppSettings["Username"], ConfigurationManager.AppSettings["Password"]);
report.Load(Server.MapPath("Relative path to the report"));
report.SetDataSource(GetDataSet()); //This gets the dataset filled with data for the report
try
{
ExportOptions options = new ExportOptions();
DiskFileDestinationOptions diskFileOptions = new DiskFileDestinationOptions();
ExcelFormatOptions excelOptions = new ExcelFormatOptions();
diskFileOptions.DiskFileName = path + "Test Report.xls";
options.ExportDestinationType = ExportDestinationType.DiskFile;
options.ExportFormatType = ExportFormatType.Excel;
options.ExportDestinationOptions = diskFileOptions;
options.ExportFormatOptions = excelOptions;
report.Export();
/*
This is where I would call a method to email the report to people
*/
}
catch (Exception ex)
{
Console.WriteLine("Error generating report: " + ex.Message);
}
此代码位于 Web 应用程序 global.asax 文件中的 Application_Start 处调用的方法中。当我 运行 应用程序时,作业失败并在我查看 Hangfire 仪表板中失败的作业时抛出此错误,即使我知道代码中的路径是正确的:
System.IO.FileNotFoundException Could not load file or assembly 'App_global.asax.twm32qri, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
System.IO.FileNotFoundException: Could not load file or assembly 'App_global.asax.twm32qri, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. File name: 'App_global.asax.twm32qri, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type) at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName) at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase) at Hangfire.Storage.InvocationData.Deserialize()
WRN: Assembly binding logging is turned OFF. To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1. Note: There is some performance penalty associated with assembly bind failure logging. To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
编辑:
我也遇到了另一个错误。这个有事可做 加载报告文件。
Failed An exception occurred during performance of the job. CrystalDecisions.CrystalReports.Engine.LoadSaveReportException
Invalid report file path.
CrystalDecisions.CrystalReports.Engine.LoadSaveReportException: Invalid report file path. at CrystalDecisions.CrystalReports.Engine.ExceptionThrower.ThrowEngineException(String messageID, EngineExceptionErrorID id) at CrystalDecisions.CrystalReports.Engine.ReportDocument.Load(String filename, OpenReportMethod openMethod, Int16 parentJob) at CrystalDecisions.CrystalReports.Engine.ReportDocument.EnsureLoadReport() at CrystalDecisions.CrystalReports.Engine.ReportDocument.SetDatabaseLogon(String user, String password) at Intranet.Global.GenerateReport() in path\Global.asax.cs:line 98
解决了问题。我显然需要使用 CrystalReportViewer 对象并将 ReportDocument 对象设置为其源。 CrystalReportViewer class 在 CrystalDecisions.Web 命名空间中。
using (ReportDocument report = new ReportDocument())
{
using (CrystalReportViewer viewer = new CrystalReportViewer())
{
string path = System.Web.Hosting.HostingEnvironment.MapPath(@"Destination path here");
report.Load(System.Web.Hosting.HostingEnvironment.MapPath(@"Path to .rpt file here"));
report.SetDatabaseLogon(ConfigurationManager.AppSettings["Username"], ConfigurationManager.AppSettings["Password"]);
string file = path + "TestReport.xls";
//These two lines below are important. The report won't generate without them.
viewer.ReportSource = report;
viewer.RefreshReport();
//Just deleting the file if it exists.
if (File.Exists(file))
File.Delete(file);
report.ExportToDisk(ExportFormatType.Excel, diskFileOptions.DiskFileName);
}
}