Hi Support.
It was great meeting you guys at the Dev Connections conference and I'm very excited about all the new stuff you're doing.
Here's my Question:
We have a XAF Web Application with some lengthy XAF reports.
I want to execute a report on a separate thread on the server and then email the resulting PDF to the user when it's done.
I've got all this working except that when a report has a report parameter object specified it is not shown and the resulting report is unfiltered.
This is how I'm capturing the report:
Public Sub EmailReport(ByVal myReport As ReportData)
Dim xrpt As XafReport = myReport.LoadXtraReport(ObjectSpace)
Dim MS As New System.IO.MemoryStream()
xrpt.ExportToPdf(MS)
MS.Seek(0, IO.SeekOrigin.Begin)
Dim msg As New Net.Mail.MailMessage()
msg.To.Add(ToAddress)
msg.Subject = myReport.ReportName
msg.Body = "Created at: " + Date.Now.ToLongDateString
msg.Attachments.Add(New Net.Mail.Attachment(MS, myReport.ReportName + ".pdf"))
MailHelper.SendPreformatedMail(msg)
…
End Sub
The above is executed from a SimpleAction.
What I would like to do is when the user clicks the Action to send the email, it should show the same parameter window that you get when viewing the report and then pass those parameters to the report and render it as above.
Is that possible?
Thanks
Richard
We have closed this ticket because another page addresses its subject:
Documentation - Provide a help article on how to programmatically export a report to PDF, stream, print or attach it to email via a custom Action without showing the report previewSend a Report as an Email
Answers approved by DevExpress Support
ReportsV2 solution:
If you filter a report using a custom parameter object as described in the Data Filtering in Reports V2 article, you can implement your logic as follows:
C#using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.ReportsV2;
using DevExpress.ExpressApp.Utils.Reflection;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.XtraReports.UI;
using MySolution.Module.BusinessObjects;
using System.IO;
namespace MySolution.Module.Web.Controllers {
public class WebSendReportViaEMailController : ObjectViewController<ListView, ReportDataV2> {
public WebSendReportViaEMailController() {
var action = new SimpleAction(this, "SendMail", PredefinedCategory.View);
action.SelectionDependencyType = SelectionDependencyType.RequireSingleObject;
action.Execute += Action_Execute;
}
private void Action_Execute(object sender, SimpleActionExecuteEventArgs e) {
ReportDataV2 reportData = (ReportDataV2)View.CurrentObject;
WebSendReportViaEMailDialogController reportViewerDialogController = Application.CreateController<WebSendReportViaEMailDialogController>();
reportViewerDialogController.Setup(reportData);
if (reportViewerDialogController.ParamsView != null) {
ShowViewParameters showViewParameters = new ShowViewParameters();
showViewParameters.Controllers.Add(reportViewerDialogController);
showViewParameters.CreatedView = reportViewerDialogController.ParamsView;
showViewParameters.Context = TemplateContext.PopupWindow;
showViewParameters.TargetWindow = TargetWindow.NewWindow;
Application.ShowViewStrategy.ShowView(showViewParameters, new ShowViewSource(Frame, null));
} else {
reportViewerDialogController.SendEmail();
}
}
}
public class WebSendReportViaEMailDialogController : DevExpress.ExpressApp.SystemModule.DialogController {
private XtraReport report;
ReportParametersObjectBase parametersObject;
protected override void Accept(SimpleActionExecuteEventArgs args) {
parametersObject = (ReportParametersObjectBase)args.CurrentObject;
SendEmail();
Window.Dispose();
}
protected override void Cancel(SimpleActionExecuteEventArgs args) {
base.Cancel(args);
Window.Dispose();
}
protected override void Dispose(bool disposing) {
base.Dispose(disposing);
if (ParamsView != null) {
ParamsView.Dispose();
ParamsView = null;
}
if (report != null) {
report.Dispose();
report = null;
}
}
public void Setup(ReportDataV2 reportData) {
report = ReportDataProvider.ReportsStorage.LoadReport(reportData);
if (reportData.ParametersObjectType == null) {
return;
}
IObjectSpace os = Application.CreateObjectSpace(reportData.ParametersObjectType);
ParamsView = Application.CreateDetailView(os, TypeHelper.CreateInstance(reportData.ParametersObjectType, ApplicationReportObjectSpaceProvider.Instance));
ParamsView.ViewEditMode = DevExpress.ExpressApp.Editors.ViewEditMode.Edit;
}
public DetailView ParamsView { get; private set; }
public void SendEmail() {
ReportsModuleV2 module = ReportsModuleV2.FindReportsModule(ApplicationReportObjectSpaceProvider.ContextApplication.Modules);
module.ReportsDataSourceHelper.SetupBeforePrint(report, parametersObject, parametersObject.GetCriteria(), true, parametersObject.GetSorting(), true);
// Send report via email code
}
}
}
In addition, I suggest you check the How to: Print a Report Without Displaying a Preview article to learn more about how to print a report in code in XAF.
Old Reports Module solution:
Yes, it's possible. Please refer to a sample code snippet, and then integrate it into your application:
Visual BasicPublic Class WebSendReportViaEMailDialogController
Inherits DevExpress.ExpressApp.SystemModule.DialogController
Private report As DevExpress.ExpressApp.Reports.XafReport
Private paramsView_Renamed As DetailView
Protected Overrides Sub Accept(ByVal args As DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs)
SendEmail()
Window.Dispose()
End Sub
Protected Overrides Sub Cancel(ByVal args As DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs)
MyBase.Cancel(args)
Window.Dispose()
End Sub
Protected Overrides Overloads Sub Dispose(ByVal disposing As Boolean)
MyBase.Dispose(disposing)
If paramsView_Renamed IsNot Nothing Then
paramsView_Renamed.Dispose()
paramsView_Renamed = Nothing
End If
If report IsNot Nothing Then
report.Dispose()
report = Nothing
End If
End Sub
Public Sub Setup(ByVal reportData As DevExpress.ExpressApp.Reports.IReportData)
report = reportData.LoadXtraReport(Application.CreateObjectSpace())
paramsView_Renamed = report.CreateParametersDetailView(Application)
paramsView_Renamed.ViewEditMode = DevExpress.ExpressApp.Editors.ViewEditMode.Edit
If paramsView_Renamed IsNot Nothing AndAlso paramsView_Renamed.Items.Count = 0 Then
paramsView_Renamed.Dispose()
paramsView_Renamed = Nothing
End If
End Sub
Public ReadOnly Property ParamsView() As DetailView
Get
Return paramsView_Renamed
End Get
End Property
Public Sub SendEmail()
' Send report via email code
End Sub
End Class
Public Class WebSendReportViaEMailController
Inherits ViewController(Of ListView)
Private sendMailAction As DevExpress.ExpressApp.Actions.SimpleAction
Public Sub New()
TargetObjectType = GetType(DevExpress.ExpressApp.Reports.IReportData)
sendMailAction = New DevExpress.ExpressApp.Actions.SimpleAction(Me, "SendMail", PredefinedCategory.View)
AddHandler sendMailAction.Execute, AddressOf sendMailAction_Execute
End Sub
Private Sub sendMailAction_Execute(ByVal sender As Object, ByVal e As DevExpress.ExpressApp.Actions.SimpleActionExecuteEventArgs)
Dim reportData As DevExpress.ExpressApp.Reports.IReportData = TryCast(View.CurrentObject, DevExpress.ExpressApp.Reports.IReportData)
If reportData IsNot Nothing Then
Dim reportViewerDialogController As WebSendReportViaEMailDialogController = Application.CreateController(Of WebSendReportViaEMailDialogController)()
reportViewerDialogController.Setup(reportData)
If reportViewerDialogController.ParamsView IsNot Nothing Then
Dim showViewParameters As New ShowViewParameters()
showViewParameters.Controllers.Add(reportViewerDialogController)
showViewParameters.CreatedView = reportViewerDialogController.ParamsView
showViewParameters.Context = TemplateContext.PopupWindow
showViewParameters.TargetWindow = TargetWindow.NewWindow
Application.ShowViewStrategy.ShowView(showViewParameters, New ShowViewSource(Frame, Nothing))
Else
reportViewerDialogController.SendEmail()
End If
End If
End Sub
End Class
>> Can you provide the SendEmail function in C#?
Please see an example in the initial question. Here is its C# version:
C#public void EmailReport(ReportData myReport) {
XafReport xrpt A = myReport.LoadXtraReport(ObjectSpace);
MemoryStream MS = new System.IO.MemoryStream();
xrpt.ExportToPdf(MS);
MS.Seek(0, IO.SeekOrigin.Begin);
MailMessage msg = new Net.Mail.MailMessage();
msg.To.Add(ToAddress);
msg.Subject = myReport.ReportName;
msg.Body = "Created at: " + DateTime.Now.ToLongDateString();
msg.Attachments.Add(new Net.Mail.Attachment(MS, myReport.ReportName + ".pdf"));
MailHelper.SendPreformatedMail(msg);
}
>> Also, is there a sample application that contains below requirements?
I have created a separate ticket to discuss this task: How to show a window with an email template. We will answer it shortly.
Hi Bobby,
As far as I understand, you wish to implement the same functionality for the Reports V2 module. If you filter a report using a custom parameter object as described in the Data Filtering in Reports V2 article, you can implement your logic as follows:
C#using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.ReportsV2;
using DevExpress.ExpressApp.Utils.Reflection;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.XtraReports.UI;
using MySolution.Module.BusinessObjects;
using System.IO;
namespace MySolution.Module.Web.Controllers {
public class WebSendReportViaEMailController : ObjectViewController<ListView, ReportDataV2> {
public WebSendReportViaEMailController() {
var action = new SimpleAction(this, "SendMail", PredefinedCategory.View);
action.SelectionDependencyType = SelectionDependencyType.RequireSingleObject;
action.Execute += Action_Execute;
}
private void Action_Execute(object sender, SimpleActionExecuteEventArgs e) {
ReportDataV2 reportData = (ReportDataV2)View.CurrentObject;
WebSendReportViaEMailDialogController reportViewerDialogController = Application.CreateController<WebSendReportViaEMailDialogController>();
reportViewerDialogController.Setup(reportData);
if (reportViewerDialogController.ParamsView != null) {
ShowViewParameters showViewParameters = new ShowViewParameters();
showViewParameters.Controllers.Add(reportViewerDialogController);
showViewParameters.CreatedView = reportViewerDialogController.ParamsView;
showViewParameters.Context = TemplateContext.PopupWindow;
showViewParameters.TargetWindow = TargetWindow.NewWindow;
Application.ShowViewStrategy.ShowView(showViewParameters, new ShowViewSource(Frame, null));
} else {
reportViewerDialogController.SendEmail();
}
}
}
public class WebSendReportViaEMailDialogController : DevExpress.ExpressApp.SystemModule.DialogController {
private XtraReport report;
ReportParametersObjectBase parametersObject;
protected override void Accept(SimpleActionExecuteEventArgs args) {
parametersObject = (ReportParametersObjectBase)args.CurrentObject;
SendEmail();
Window.Dispose();
}
protected override void Cancel(SimpleActionExecuteEventArgs args) {
base.Cancel(args);
Window.Dispose();
}
protected override void Dispose(bool disposing) {
base.Dispose(disposing);
if (ParamsView != null) {
ParamsView.Dispose();
ParamsView = null;
}
if (report != null) {
report.Dispose();
report = null;
}
}
public void Setup(ReportDataV2 reportData) {
report = ReportDataProvider.ReportsStorage.LoadReport(reportData);
if (reportData.ParametersObjectType == null) {
return;
}
IObjectSpace os = Application.CreateObjectSpace(reportData.ParametersObjectType);
ParamsView = Application.CreateDetailView(os, TypeHelper.CreateInstance(reportData.ParametersObjectType, ApplicationReportObjectSpaceProvider.Instance));
ParamsView.ViewEditMode = DevExpress.ExpressApp.Editors.ViewEditMode.Edit;
}
public DetailView ParamsView { get; private set; }
public void SendEmail() {
ReportsModuleV2 module = ReportsModuleV2.FindReportsModule(ApplicationReportObjectSpaceProvider.ContextApplication.Modules);
module.ReportsDataSourceHelper.SetupBeforePrint(report, parametersObject, parametersObject.GetCriteria(), true, parametersObject.GetSorting(), true);
// Send report via email code
}
}
}
In addition, I suggest you check the How to: Print a Report Without Displaying a Preview article to learn more about how to print a report in code in XAF.