EPR类企业管理系统

在我们现有系统基础上或全新开发,提供定制服务
为您的企业高效快速实施ERP,WMS,MES,CRM管理系统
全面管控物料仓库、销售业务、采购业务、仓库业务
生产过程、质量检验、组织架构、业务报表


定制
QQ:460-3528

开发
QQ群:3360-90194

源码
微信:136-3650-3721

如何:在不显示预览的情况下打印报告

此示例演示如何实现PrintContacts Action,该操作将在不显示预览的情况下打印“ Contacts Report”报告。请注意,此操作不适用于具有最终用户指定参数的报表(即,使用ReportParametersObjectBase参数或本机XtraReport参数的报表)。

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

注意

移动应用程序不支持报告打印机制,因此本主题中描述的方法无法在Mobile平台中实现。

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

提示

DevExpress代码示例数据库(http://www.devexpress.com/example=E5146)中提供了完整的示例项目。

在本主题中,假定您有一个使用Reports V2 Module的XAF应用程序,并且已经创建了一个或多个报告(请参阅Reports V2 Module Overview)。

在与平台无关的抽象控制器中创建PrintContacts操作

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

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);
}

如您所见,PrintContactsControllerContact对象为目标,因此当用户在导航中选择Contact时,它将被激活。控制器引入了PrintContacts SimpleAction。执行Action时,将调用抽象的PrintReport方法(请参见SimpleAction.Execute)。从数据库中获取ReportDataV2.DisplayName设置为“ Contacts Report”的ReportDataV2对象,并将其传递给PrintReport方法(此处假定已经创建了这样的报告)。接下来的两节将说明如何提供WinForms和ASP.NET的PrintReport方法。

为WinForms实施报告打印

在WinForms模块项目中,以以下方式继承PrintContactsController并实现PrintReport方法。

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();
        }
    }
}

在这里,ReportsStorage.LoadReport方法用于从传递的IReportDataV2持久对象加载XtraReport对象。该ReportsStorage实例是使用静态访问ReportDataProvider.ReportsStorage财产。然后,使用ReportDataSourceHelper.SetupBeforePrint方法准备要打印的报告。该ReportDataSourceHelper实例是使用访问ReportsModuleV2.ReportsDataSourceHelper财产。使用XtraReport的PrintDialog调用最终用户可以在打印文档之前指定打印机和其他打印选项的打印对话框。 扩展方法。

重点

确保已引用DevExpress.XtraPrinting.v 19.2 .dll。该PrintDialog类扩展方法是在该组件实现。

结果显示在下图中。

InstantPrintReport_Win

为ASP.NET实施报告打印

在ASP.NET模块项目中,以下列方式继承PrintContactsController并实现PrintReport方法。

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);
    }
}

在这里,ReportsStorage.GetReportContainerHandle方法用于从传递的IReportDataV2持久对象获取报告句柄。该ReportsStorage实例是使用静态访问ReportDataProvider.ReportsStorage财产。使用WebWindow.RegisterStartupScript方法注册打印脚本。

注意

在Edge浏览器中,不可能在html页面中嵌入的iframe中触发打印,因此您可以在新窗口中打开生成的报告PDF文件,并使用标准的PDF查看器功能来打印此文件。

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

打开创建的InstantPrintReport.aspx.csInstantPrintReport.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();
            }
        }
    }
}

在这里,ReportsStorage.GetReportContainerByHandle方法和IReportContainer.Report属性用于从使用HTTP查询字符串传递的报表句柄加载XtraReport对象。然后,使用ReportDataSourceHelper.SetupBeforePrint方法准备报告以进行进一步打印。该ReportDataSourceHelper实例是使用访问ReportsModuleV2.ReportsDataSourceHelper财产。然后,使用Adobe PDF Web浏览器插件打印报告,如如何打印报告而不在Web应用程序代码示例中显示报告中所示。

PrintContacts行动应在回发执行,因为回传需要发送一个文件给客户端。因此,在ASP.NET模块项目中打开“模型编辑器”,并设置ActionDesign | IModelActionWeb.IsPostBackRequired属性。动作| 将PrintContacts节点设置为true。

InstantPrintReport_ME

结果显示在下图中。

InstantPrintReport_Web

相关文章

转载保留此链接,注明出处