How to: Print a Report Without Displaying a Preview 如何:在不显示预览的情况下打印报表

This example demonstrates how to implement the PrintContacts Action, which prints the "Contacts Report" report without displaying its preview. Note that this Action is not designed for reports with end-user-specified parameters (i.e., reports that use ReportParametersObjectBase parameters or native XtraReport parameters).

此示例演示如何实现打印联系人操作,该操作打印"联系人报告"报表而不显示其预览。请注意,此操作不是为具有最终用户指定参数的报表(即使用报表参数ObjectBase参数或本机 XtraReport 参数的报表)设计的。

 

You can also use the code from this example to access an XtraReport object and then export or email the report content as illustrated in the tutorials listed in the Exporting Reports document.

您还可以使用此示例中的代码访问 XtraReport 对象,然后导出报表内容或通过电子邮件发送报表内容,如导出报表文档中列出的教程中所示。

 

Note 注意
Mobile applications do not support the report printing mechanism, so the approach described in this topic cannot be implemented in the Mobile platform.
移动应用程序不支持报表打印机制,因此本主题中描述的方法无法在移动平台中实现。

 

It is recommended that you review the following XtraReport help topics and examples before proceeding.

  • Printing a Report
  • Printing and Exporting
  • Printing and Exporting in Code
  • How to print a report without displaying it in a web application

建议您在继续之前查看以下 XtraReport 帮助主题和示例。

  • 打印报表
  • 打印和导出
  • 代码中的打印和导出
  • 如何在 Web 应用程序中打印报表而不显示报表

 

Tip 提示
A complete sample project is available in the DevExpress Code Examples database at http://www.devexpress.com/example=E5146
完整的示例项目可在 DevExpress 代码示例数据库中找到,http://www.devexpress.com/example=E5146

.

In this topic, it is assumed that you have an XAF application that uses the Reports V2 Module, and you have created one or more reports (see Reports V2 Module Overview).

在本主题中,假定您有一个使用报表 V2 模块的 XAF 应用程序,并且您创建了一个或多个报表(请参阅报表 V2 模块概述)。

Create the PrintContacts Action in the Abstract Platform-Agnostic Controller

在抽象平台不可知的控制器中创建打印联系人操作

In the platform-agnostic module, implement the following abstract Controller class.

在与平台无关的模块中,实现以下抽象控制器类。

using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.ReportsV2;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
// ...
public abstract class PrintContactsController : ObjectViewController<ListView, Contact> {
    public PrintContactsController() {
        SimpleAction printAction = new SimpleAction(this, "PrintContacts", PredefinedCategory.Reports);
        printAction.ImageName = "Action_Printing_Print";
        printAction.Execute += delegate(object sender, SimpleActionExecuteEventArgs e) {
            IObjectSpace objectSpace = ReportDataProvider.ReportObjectSpaceProvider.CreateObjectSpace(typeof(ReportDataV2));
            IReportDataV2 reportData = objectSpace.FindObject<ReportDataV2>(
                new BinaryOperator("DisplayName","Contacts Report"));
            if (reportData == null) {
                throw new UserFriendlyException("Cannot find the 'Contacts Report' report.");
            }
            else {
                PrintReport(reportData);
            }
        };
    }
    protected abstract void PrintReport(IReportDataV2 reportData);
}

 

As you can see, the PrintContactsController targets Contact objects, so it will be activated when a user selects Contact in the navigation. The Controller introduces the PrintContacts SimpleAction. The abstract PrintReport method is called when the Action is executed (see SimpleAction.Execute). The ReportDataV2 object that has the ReportDataV2.DisplayName set to "Contacts Report" is obtained from the database and passed to the PrintReport method (here, it is assumed that such a report is already created). The next two sections will explain how to provide implementations of the PrintReport method for WinForms and ASP.NET.

如您所见,打印联系人控制器面向联系人对象,因此当用户在导航中选择"联系人"时,将激活该对象。控制器介绍打印联系人简单操作。执行操作时调用抽象 PrintReport 方法(请参阅简单操作.从数据库中获取了将报表数据V2.DisplayName 设置为"联系人报告"的 ReportDataV2 对象,并传递给 PrintReport 方法(此处假定已创建此类报表)。接下来的两节将解释如何为 WinForms 和ASP.NET提供 PrintReport 方法的实现。

Implement Report Printing for WinForms

为 WinForms 实施报表打印

In the WinForms module project, inherit the PrintContactsController and implement the PrintReport method in the following manner.

在 WinForms 模块项目中,继承打印联系人控制器,并采用以下方式实现打印报告方法。

using DevExpress.ExpressApp.ReportsV2;
using DevExpress.XtraReports.UI;
// ...
public class WinPrintContactsController : PrintContactsController{
    protected override void PrintReport(IReportDataV2 reportData) {
        XtraReport report = ReportDataProvider.ReportsStorage.LoadReport(reportData);
        ReportsModuleV2 reportsModule = ReportsModuleV2.FindReportsModule(Application.Modules);
        if (reportsModule != null && reportsModule.ReportsDataSourceHelper != null) {
            reportsModule.ReportsDataSourceHelper.SetupBeforePrint(report);
            report.PrintDialog();
        }
    }
}

 

Here, the ReportsStorage.LoadReport method is used to load the XtraReport object from the passed IReportDataV2 persistent object. The ReportsStorage instance is accessed using the static ReportDataProvider.ReportsStorage property. Then, the report is prepared for printing using the ReportDataSourceHelper.SetupBeforePrint method. The ReportDataSourceHelper instance is accessed using the ReportsModuleV2.ReportsDataSourceHelper property. The print dialog where an end-user can specify a printer and other print options before printing the document is invoked using the XtraReport's PrintDialog extension method.

此处,报表存储.LoadReport 方法用于从传递的 IReportDataV2 持久对象加载 XtraReport 对象。使用静态报表数据提供程序.报表存储属性访问报表存储实例。然后,准备使用报表数据源帮助程序打印报表。使用报表模块V2.报表数据源帮助程序属性访问报表数据源帮助器实例。最终用户可以在打印文档之前使用 XtraReport 的 PrintDialog 扩展方法调用打印机和其他打印选项的打印对话框。

 

Important 重要
Ensure that the DevExpress.XtraPrinting.v19.2.dll is referenced. The PrintDialog extension method is implemented in this assembly.
确保引用 DevExpress.XtraPrinting.v19.2.dll。在此程序集中实现 PrintDialog 扩展方法。

 

The result is demonstrated in the image below.

结果如下图所示。

InstantPrintReport_Win

Implement Report Printing for ASP.NET

为ASP.NET实施报表打印

In the ASP.NET module project, inherit the PrintContactsController and implement the PrintReport method in the following manner.

在ASP.NET模块项目中,继承打印联系人控制器,并采用以下方式实现打印报告方法。

using System.Web;
using DevExpress.ExpressApp.ReportsV2;
using DevExpress.ExpressApp.Web;
// ...
public class WebPrintContactsController : PrintContactsController {
    protected override void PrintReport(IReportDataV2 reportData) {
        string reportContainerHandle = ReportDataProvider.ReportsStorage.GetReportContainerHandle(reportData);
        ((WebWindow)WebApplication.Instance.MainWindow).RegisterStartupScript(
            "InstantPrintReport", GetPrintingScript(reportContainerHandle), overwrite: true);
    }
    private string GetPrintingScript(string reportContainerHandle) {
        var url = HttpContext.Current.Response.ApplyAppPathModifier(
            string.Format("~/InstantPrintReport.aspx?reportContainerHandle={0}", reportContainerHandle));
        return string.Format(@"
            if(!ASPx.Browser.Edge) {{
                var iframe = document.getElementById('reportout');
                if (iframe != null) {{
                    document.body.removeChild(iframe);
                }}
                iframe = document.createElement('iframe');
                iframe.setAttribute('id', 'reportout');
                iframe.style.width = 0;
                iframe.style.height = 0;
                iframe.style.border = 0;
                document.body.appendChild(iframe);
                document.getElementById('reportout').contentWindow.location = '{0}';
                }} else {{
                    window.open('{0}', '_blank');
            }}
        ", url);
    }
}

 

Here, the ReportsStorage.GetReportContainerHandle method is used to get the report handle from the passed IReportDataV2 persistent object. The ReportsStorage instance is accessed using the static ReportDataProvider.ReportsStorage property. The printing script is registered using the WebWindow.RegisterStartupScript method.

此处,报表存储.GetReportContainerHandle 方法用于从传递的 IReportDataV2 持久对象获取报表句柄。使用静态报表数据提供程序.报表存储属性访问报表存储实例。使用 WebWindow 注册启动脚本方法注册打印脚本。

 

Note 注意
In the Edge browser, it is impossible to trigger a print in an iframe embedded in a html page, so you can open the generated report PDF-file in a new window and print this file using the standard PDF-viewer functions.
在 Edge 浏览器中,不可能在嵌入在 html 页面中的 iframe 中触发打印,因此您可以在新窗口中打开生成的报表 PDF 文件,并使用标准 PDF 查看器功能打印此文件。

 

The script above creates the iframe element and passes the report's handle to the InstantPrintReport.aspx page intended for report printing. So, create the InstantPrintReport.aspx page in the ASP.NET application project (Add | New Item... | Web Form).

上面的脚本创建 iframe 元素,并将报表的句柄传递给用于报表打印的 InstantPrintReport.aspx 页。因此,在ASP.NET应用程序项目中创建 InstantPrintReport.aspx 页(添加 |新项目... |网页表单)。

 

Open the created InstantPrintReport.aspx.cs (InstantPrintReport.aspx.vb) file and modify the Page_Load method as follows.

打开创建的InstantPrintReport.aspx.cs(InstantPrintReport.aspx.vb)文件,然后修改Page_Load方法,如下所示。

using System;
using System.IO;
using DevExpress.XtraPrinting;
using DevExpress.XtraReports.UI;
using DevExpress.ExpressApp.ReportsV2;
// ...
public partial class InstantPrintReport : System.Web.UI.Page {
    protected void Page_Load(object sender, EventArgs e) {
        string reportDataHandle = Request.QueryString["reportContainerHandle"];
        ReportsModuleV2 module = ReportsModuleV2.FindReportsModule(
            ApplicationReportObjectSpaceProvider.ContextApplication.Modules);
        if(!String.IsNullOrEmpty(reportDataHandle) && module != null) {
            XtraReport report = null;
            try {
                report = ReportDataProvider.ReportsStorage.GetReportContainerByHandle(reportDataHandle).Report;
                module.ReportsDataSourceHelper.SetupBeforePrint(report, null, null, false, null, false);
                using(MemoryStream ms = new MemoryStream()) {
                    report.CreateDocument();
                    PdfExportOptions options = new PdfExportOptions();
                    options.ShowPrintDialogOnOpen = true;
                    report.ExportToPdf(ms, options);
                    ms.Seek(0, SeekOrigin.Begin);
                    byte[] reportContent = ms.ToArray();
                    Response.ContentType = "application/pdf";
                    Response.AddHeader("Content-Disposition", "attachement; filename=MyFileName.pdf");
                    Response.Clear();
                    Response.OutputStream.Write(reportContent, 0, reportContent.Length);
                    Response.End();
                }
            }
            finally {
                if (report != null) report.Dispose();
            }
        }
    }
}

 

Here, the ReportsStorage.GetReportContainerByHandle method and IReportContainer.Report property are is used to load the XtraReport object from the report handle passed using the HTTP query string. Then, the report is prepared for further printing using the ReportDataSourceHelper.SetupBeforePrint method. The ReportDataSourceHelper instance is accessed using the ReportsModuleV2.ReportsDataSourceHelper property. The report is then printed using the Adobe PDF web browser plug-in, as illustrated in the How to print a report without displaying it in a web application code example.

此处,报表存储.GetReportContainerByHandle 方法和 IReportContainer.Report 属性用于从使用 HTTP 查询字符串传递的报表句柄加载 XtraReport 对象。然后,准备使用报表数据源帮助器进一步打印报表。使用报表模块V2.报表数据源帮助程序属性访问报表数据源帮助器实例。然后,使用 Adobe PDF Web 浏览器插件打印报表,如如何在 Web 应用程序代码示例中显示报表而不显示报表中所示。

 

The PrintContacts Action should be executed on postback, because a postback is required to transmit a file to the client. So, open the Model Editor in the ASP.NET module project and set the IModelActionWeb.IsPostBackRequired property of the ActionDesign | Actions | PrintContacts node to true.

打印联系人操作应在回发时执行,因为需要回发才能将文件传输到客户端。因此,在ASP.NET模块项目中打开模型编辑器并设置"IModelActionWeb.IsPostBack"操作设计所需的属性 |操作 |将联系人节点打印为 true。

InstantPrintReport_ME

The result is demonstrated in the image below.

结果如下图所示。

InstantPrintReport_Web

 
posted @ 2020-01-10 14:38  code first life  阅读(627)  评论(0编辑  收藏  举报