乐于分享
好东西不私藏

C# 实用工具类:FastReport 打印封装(完整可复用)

C# 实用工具类:FastReport 打印封装(完整可复用)

在 C# 桌面开发(尤其是 WinForm、DevExpress 项目)中,报表打印是高频需求,而 FastReport 作为轻量、灵活的报表工具,深受开发者青睐。但重复编写报表加载、数据源注册、打印机配置等代码,不仅繁琐还易出错。本文将解析一套完整的 FastReport 打印工具类(基于你提供的代码优化完善),封装了打印核心逻辑、打印机校验、模板校验等功能,可直接复制到项目中复用,大幅提升开发效率,新手也能快速上手!

## 一、前言:为什么要封装 FastReport 工具类?

FastReport 本身提供了完整的报表操作 API,但在实际项目中,我们会遇到这些痛点:

– 重复编写报表加载、数据源注册代码,冗余且维护成本高;

– 打印机选择、模板路径校验、异常处理分散在各个业务逻辑中,代码混乱;

– 不同报表(如住院费用清单、普通报表)的打印逻辑差异小,可统一封装复用;

– 缺乏统一的异常捕获和提示,用户体验不佳。

基于此,我们封装了 `Fast_Report` 工具类,将报表打印的核心逻辑(模板加载、数据源注册、打印机配置、异常处理)统一封装,对外提供简洁的调用接口,无需重复编码,直接传入参数即可实现打印功能。

## 二、环境准备

在使用该工具类前,需先完成 FastReport 的环境配置,确保项目能正常引用相关组件:

1. 项目框架:.NET Framework(适配 WinForm/DevExpress 项目,本文代码兼容 .NET Framework 4.0+);

2. 安装 FastReport 组件:通过 NuGet 安装 `FastReport` 核心包(搜索 FastReport,安装对应版本);

3. 引用依赖:确保项目中引用 `FastReport.dll`、`FastReport.Data.dll`,若使用 DevExpress 控件,需额外引用对应兼容包;

4. 模板准备:在项目根目录创建 `Report` 文件夹,存放 FastReport 模板文件(.frx 格式),模板中需提前设计好报表布局、数据绑定字段。

## 三、完整 FastReport 工具类代码(可直接复制复用)

以下是完整的 `Fast_Report` 工具类代码,包含 2 个打印方法(主方法+备用方法)、1 个打印机校验方法,注释详细,可根据自身项目需求微调(如提示信息、模板路径):

“`csharp

using System;

using System.Data;

using System.IO;

using System.Reflection;

using System.Drawing.Printing;

using FastReport;

using FastReport.Data;

using DevExpress.XtraEditors; // 若未使用DevExpress,可替换为System.Windows.Forms.MessageBox

namespace YourNamespace // 替换为你的项目命名空间

{

    /// <summary>

    /// FastReport 打印工具类

    /// 封装报表加载、数据源注册、打印机配置、异常处理等核心逻辑

    /// 可直接复用,支持多报表类型、指定打印机打印

    /// </summary>

    public class Fast_Report

    {

        /// <summary>

        /// 错误信息(用于返回打印异常详情)

        /// </summary>

        static string MessageError = string.Empty;

        /// <summary>

        /// 核心打印方法(推荐使用)

        /// </summary>

        /// <param name=”PrinterName”>指定打印机名称(可为空,为空则使用默认打印机)</param>

        /// <param name=”type”>报表类型(用于区分不同报表的数据源绑定逻辑)</param>

        /// <param name=”ReportNmae”>报表模板名称(无需加.frx后缀)</param>

        /// <param name=”dset”>数据源(DataSet,支持多表)</param>

        /// <returns>打印结果(空字符串表示成功,非空表示错误信息)</returns>

        public static string FastReport_Print(string PrinterName, int type, string ReportNmae, DataSet dset)

        {

            // 初始化错误信息

            MessageError = string.Empty;

            try

            {

                // 1. 实例化FastReport报表对象

                FastReport.Report report = new FastReport.Report();

                // 2. 获取报表模板路径(项目根目录/Report/模板名.frx)

                // 优先获取当前程序运行目录(兼容不同部署场景)

                string path = Environment.CurrentDirectory;

                // 拼接模板完整路径(Report文件夹需提前创建,存放.frx模板)

                string reportFile = Path.Combine(Path.Combine(path, “Report”), ReportNmae + “.frx”);

                // 3. 校验模板文件是否存在

                if (!File.Exists(reportFile))

                {

                    string errorMsg = “很抱歉,未找到对应的打印模板,请联系系统管理员!\r\n\r\n” + reportFile;

                    XtraMessageBox.Show(errorMsg); // 若未用DevExpress,替换为MessageBox.Show(errorMsg)

                    return errorMsg;

                }

                // 4. 加载报表模板

                report.Load(reportFile);

                // 5. 注册数据源(将DataSet注册到报表中,供模板绑定)

                report.RegisterData(dset);

                // 6. 根据报表类型,绑定数据源到报表的DataBand(可根据实际报表调整)

                // 此处适配两种报表类型,可根据自身项目扩展更多类型

                switch (type)

                {

                    case 1:// 示例:住院病人费用分类汇总清单

                        // 找到报表中的DataBand(需与模板中的DataBand名称一致,此处为”band”)

                        FastReport.DataBand band = report.FindObject(“band”) as FastReport.DataBand;

                        // 获取数据源(与DataSet中的表名对应)

                        FastReport.Data.DataSourceBase dataSource = report.GetDataSource(dset.Tables[0].TableName);

                        // 将数据源绑定到DataBand

                        band.DataSource = dataSource;

                        break;

                    case 2:// 示例:其他报表(可自定义报表类型)

                        FastReport.DataBand band1 = report.FindObject(“band”) as FastReport.DataBand;

                        FastReport.Data.DataSourceBase dataSource1 = report.GetDataSource(dset.Tables[0].TableName);

                        band1.DataSource = dataSource1;

                        break;

                }

                // 7. 打印配置:不显示打印对话框,直接打印(可根据需求调整)

                report.PrintSettings.ShowDialog = false;

                // 8. 校验并设置指定打印机(若打印机存在,使用指定打印机;否则使用默认打印机)

                if (Fast_Report.DYJBOOL(PrinterName))

                {

                    report.PrintSettings.Printer = PrinterName;

                }

                // 9. 准备报表(解析模板和数据源)

                report.Prepare();

                // 10. 显示打印预览(false表示不模态显示,可根据需求改为true)

                report.ShowPrepared(false);

                // 若需直接打印(不显示预览),注释上一行,启用下一行

                // report.Print();

            }

            catch (Exception aa)

            {

                // 捕获异常,记录错误信息并提示

                MessageError = aa.ToString();

                XtraMessageBox.Show(MessageError);

            }

            // 返回错误信息(空字符串表示打印成功)

            return MessageError;

        }

        #region 备用打印方法(未使用,可根据需求启用)

        /// <summary>

        /// 备用打印方法(单表数据源,简化版)

        /// </summary>

        /// <param name=”ReportNmae”>报表模板名称(无需加.frx后缀)</param>

        /// <param name=”dset”>数据源(DataTable,单表)</param>

        /// <param name=”name”>可选参数(可用于扩展,如打印机名称)</param>

        public static void FastReport_Print(string ReportNmae, DataTable dset, string name = null)

        {

            // 使用using自动释放报表资源,避免内存泄露

            using (FastReport.Report report = new FastReport.Report())

            {

                // 拼接模板路径(使用Application.StartupPath,适用于WinForm项目)

                string reportFile = Path.Combine(Path.Combine(Application.StartupPath, “Report”), ReportNmae + “.frx”);

                // 校验模板文件

                if (!File.Exists(reportFile))

                {

                    MessageBox.Show(“很抱歉,未找到对应的打印模板,请联系系统管理员!”);

                    return;

                }

                // 加载模板、注册单表数据源

                report.Load(reportFile);

                report.RegisterData(dset, dset.TableName);// 单表数据源注册,指定表名

                // 打印配置:不显示打印对话框

                report.PrintSettings.ShowDialog = false;

                // 准备并显示预览

                report.Prepare();

                report.ShowPrepared();

                // 直接打印(不显示预览)

                // report.Print();

            }

        }

        #endregion

        /// <summary>

        /// 打印机校验方法:判断指定打印机是否已安装

        /// </summary>

        /// <param name=”PrinterName”>打印机名称</param>

        /// <returns>true:打印机存在;false:打印机不存在</returns>

        public static bool DYJBOOL(string PrinterName)

        {

            try

            {

                bool isFind = false;

                // 实例化打印文档,用于获取系统已安装打印机

                System.Drawing.Printing.PrintDocument printDoc = new System.Drawing.Printing.PrintDocument();

                // 遍历系统中所有已安装的打印机

                foreach (string pName in PrinterSettings.InstalledPrinters)

                {

                    // 忽略大小写、空格,精准匹配打印机名称

                    if (PrinterName.Trim().ToUpper() == pName.Trim().ToUpper())

                    {

                        printDoc.PrinterSettings.PrinterName = PrinterName;

                        isFind = true;

                        break;

                    }

                }

                // 若未找到指定打印机,可启用提示(根据需求调整)

                // if (isFind == false)

                // {

                //     XtraMessageBox.Show(“未找到名为\'” + PrinterName.Trim().ToUpper() + “\’的打印机!”, “提醒”, MessageBoxButtons.OK, MessageBoxIcon.Warning);

                // }

                return isFind;

            }

            catch (Exception ex)

            {

                // 异常情况下,返回false(默认使用系统默认打印机)

                return false;

            }

        }

    }

}

“`

## 四、工具类核心解析(关键知识点)

该工具类封装了 FastReport 打印的全流程,核心逻辑和关键细节如下,帮助你理解并灵活调整:

### 1. 模板路径获取(兼容多场景)

工具类中使用 `Environment.CurrentDirectory` 获取程序运行目录,拼接 `Report` 文件夹路径,确保模板能被正确加载:

“`csharp

string path = Environment.CurrentDirectory;

string reportFile = Path.Combine(Path.Combine(path, “Report”), ReportNmae + “.frx”);

“`

补充:若项目部署后模板路径异常,可替换为 `Application.StartupPath`(适用于 WinForm 项目),即备用方法中的路径获取方式。

### 2. 数据源注册与绑定

支持 `DataSet`(多表)和 `DataTable`(单表)两种数据源,注册后需绑定到报表的 `DataBand`(报表模板中的数据带):

– 多表数据源:`report.RegisterData(dset);`,再通过 `report.GetDataSource(表名)` 获取指定表,绑定到 DataBand;

– 单表数据源:`report.RegisterData(dset, dset.TableName);`,直接注册并指定表名,简化操作。

关键注意:模板中的`DataBand` 名称(如工具类中的 “band”),必须与代码中`report.FindObject(“band”)` 的名称一致,否则绑定失败。

### 3. 打印机配置与校验

工具类中的 `DYJBOOL` 方法,用于校验指定打印机是否已安装,避免打印失败:

– 遍历系统已安装打印机:`PrinterSettings.InstalledPrinters`;

– 忽略大小写和空格匹配,提升兼容性;

– 若打印机不存在,返回 false,工具类会自动使用系统默认打印机。

### 4. 异常处理与返回值

核心打印方法 `FastReport_Print` 用 try-catch 捕获所有异常,错误信息存入 `MessageError`,并返回给调用者:

– 打印成功:返回空字符串;

– 打印失败(模板缺失、异常):返回具体错误信息,同时弹出提示框,提升用户体验。

### 5. 两种打印模式(灵活选择)

– 预览打印:`report.ShowPrepared(false);`,显示打印预览界面,用户可确认后再打印;

– 直接打印:注释预览代码,启用 `report.Print();`,不显示预览,直接发送到打印机。

## 五、工具类调用示例(实战演示)

以下是两种常见场景的调用示例,直接复制到业务代码中,替换参数即可使用:

### 示例1:调用核心方法(多表数据源,指定打印机)

“`csharp

// 1. 准备数据源(DataSet,可包含多个表)

DataSet ds = new DataSet();

// 假设已从数据库查询数据,填充到DataTable并加入DataSet

DataTable dt1 = GetDataFromDB(“SELECT * FROM 住院费用表”); // 自定义方法,获取数据

ds.Tables.Add(dt1);

// 2. 调用FastReport工具类打印

string printerName = “HP LaserJet Pro MFP M426fdw”; // 你的打印机名称

int reportType = 1; // 报表类型(对应工具类中的switch case)

string reportName = “住院费用分类汇总清单”; // 报表模板名称(无需加.frx)

string result = Fast_Report.FastReport_Print(printerName, reportType, reportName, ds);

// 3. 校验打印结果

if (string.IsNullOrEmpty(result))

{

    XtraMessageBox.Show(“打印操作已发起,正在预览!”);

}

else

{

    XtraMessageBox.Show(“打印失败:” + result);

}

“`

### 示例2:调用备用方法(单表数据源,默认打印机)

“`csharp

// 1. 准备单表数据源

DataTable dt = GetDataFromDB(“SELECT * FROM 普通报表数据”);

// 2. 调用备用打印方法(不指定打印机,使用默认打印机)

Fast_Report.FastReport_Print(“普通报表模板”, dt);

// 说明:备用方法无返回值,异常会直接弹出提示框

“`

## 六、避坑提醒(新手必看)

– 模板路径问题:必须在项目根目录创建 `Report` 文件夹,且模板名称与代码中传入的 `ReportNmae` 一致(区分大小写),否则会提示“未找到模板”;

– DataBand 名称匹配:模板中的 DataBand 名称(如 “band”)必须与代码中 `report.FindObject(“band”)` 的名称完全一致,否则数据源绑定失败,报表无数据;

– 打印机名称匹配:传入的 `PrinterName` 需与系统中打印机名称一致(可在“设备和打印机”中查看),工具类虽忽略大小写,但建议精准输入;

– 资源释放:备用方法中使用 `using` 包裹报表对象,可自动释放资源,核心方法若需优化,也可添加 `using`;

– DevExpress 依赖:若项目未使用 DevExpress,需将 `XtraMessageBox` 替换为 `System.Windows.Forms.MessageBox`,避免编译报错。

## 七、总结

本文提供的 FastReport 工具类,封装了报表打印的核心逻辑,解决了重复编码、逻辑分散、异常处理不统一等痛点,可直接复制到 C# 桌面项目中复用。无论是多表报表、单表报表,还是指定打印机打印、预览打印,都能通过简单调用实现。

工具类可根据自身项目需求灵活扩展:如增加更多报表类型(switch case 扩展)、调整模板路径、优化提示信息、添加打印参数(如打印份数)等。掌握这个工具类,能大幅节省报表打印功能的开发时间,提升代码可维护性。

如果在使用过程中遇到模板绑定失败、打印机不生效、异常报错等问题,欢迎在评论区留言交流,一一为你解答!

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » C# 实用工具类:FastReport 打印封装(完整可复用)

评论 抢沙发

7 + 2 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
×
订阅图标按钮