XYS.FRNet 4.2.0

dotnet add package XYS.FRNet --version 4.2.0
                    
NuGet\Install-Package XYS.FRNet -Version 4.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="XYS.FRNet" Version="4.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="XYS.FRNet" Version="4.2.0" />
                    
Directory.Packages.props
<PackageReference Include="XYS.FRNet" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add XYS.FRNet --version 4.2.0
                    
#r "nuget: XYS.FRNet, 4.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package XYS.FRNet@4.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=XYS.FRNet&version=4.2.0
                    
Install as a Cake Addin
#tool nuget:?package=XYS.FRNet&version=4.2.0
                    
Install as a Cake Tool

XYS.FRNet

FastReport .NET 渲染宿主。只负责:拿 XYS.FRXYS.FR.V3 项目)准备好的 DataSet 与模板路径,调用 FastReport 引擎出 PDF/JPG/HTML/XLSX 流或直接送打印机。不含任何数据契约与配置解析(实体注册、FRTables.frd 生成、模板号映射都在 XYS.FR 里)。

  • 目标框架:net462 / net8.0-windows
  • 报表引擎:FastReport.Net.Demo 2025.2.8
  • 依赖:XYS.FR.V3XYS.Utils.SysXYS.Utils.Log4Net(同解决方案项目引用)
  • 程序集名:XYS.FRNet;命名空间 XYS.FR

⚠️ 当前引用的是 Demo 版 FastReport 包,导出结果带演示水印、有页数限制。正式部署需替换为已授权的 FastReport.Net 包(仅需改 PackageReference,代码无需改动)。

核心类型

类型 职责
BaseFRNetService 抽象渲染服务基类:实现 BaseFRServiceExportStream,并实现 IFRPrintServicePrint

BaseFRNetService 是本项目唯一的公开类型。它实现 BaseFRService(在 XYS.FR)留下的 ExportStream 抽象成员,并额外声明实现 IFRPrintService 提供打印。下游只需继承它并实现 GetFRTypes + InitFRConfig

快速使用

using System.Collections.Generic;
using System.IO;
using XYS.FR;

public sealed class LabPrintService : BaseFRNetService
{
    public LabPrintService()
    {
        LoggerName  = "LabPrintService";
        ActualType  = typeof(LabPrintService);
        Printer     = "\\print-srv\Lab-HP";   // 可选:默认打印机
        Init();                                  // 注册实体 + 生成 frd + 加载配置,放在构造函数末尾
    }

    protected override List<Type> GetFRTypes() => new List<Type>
    {
        typeof(FRInfo),
        typeof(FRItem),
    };

    protected override void InitFRConfig()
    {
        var cfg = new XmlConfigManager();   // 默认 AppBase/Config/fr.config.xml
        cfg.Init();                         // 失败抛异常,视为致命错误
        ConfigManager = cfg;
    }
}
var svc = new LabPrintService();

var report = new FRReport { ModelNo = "LAB001", RID = "R123", Copies = 2 };
report.Items.Add(new FRInfo { ID = "1", RID = "R123", PatName = "张三" });

// 导出 PDF 流
using (var fs = File.Create("out.pdf"))
{
    svc.ExportStream(report, fs, ExportType.Pdf);
}

// 打印:本次用指定打印机,不传则回退到 Printer 属性,仍为空则系统默认
svc.Print(report, "\\print-srv\Ward-3F");

导出格式映射

ExportType → FastReport 导出器:

ExportType 导出器 默认设置(ConfigureExport
Pdf PDFExport HideWindowUI=trueEmbeddingFonts=trueAllowModify=false
Jpg ImageExportImageFormat=Jpeg SeparateFiles=false
Html HTMLExport SinglePage=trueEmbedPictures=trueNavigator=false
Xls Excel2007Export

默认设置只保证单流输出这一底线语义:图片/HTML 导出若不关掉分文件,FastReport 只会把首页写进 Stream,其余页和图片会散落成流外的独立文件。

定制导出参数(PDF 数字签名、图片分辨率、Excel 页面合并等)重写 ConfigureExport

protected override void ConfigureExport(ExportBase export, ExportType type)
{
    base.ConfigureExport(export, type);          // 保留单流语义与 PDF 基础安全设置

    if (export is PDFExport pdf)
    {
        pdf.UserPassword = "1234";
        pdf.AllowPrint   = true;
    }
}

关键契约

成员 语义
ExportStream(FRReport, Stream, ExportType) 渲染到调用方提供的流;负责创建或释放该流
ExportStreamAsync(FRReport, Stream, ExportType, CancellationToken) 沿用基类默认实现(线程池 + 丢弃结果式取消);客户端是单用户交互,不需要 XYS.FRCore 那套限流与真取消
Print(FRReport, string printer = null) printer 优先于 Printer 属性;两者皆空走系统默认打印机;ShowDialog 恒为 false
Printer 服务级默认打印机名
ConfigureExport(ExportBase, ExportType) virtual 扩展点;子类重写时建议先调 base
异常 参数为 nullArgumentNullException;未知 ExportTypeArgumentOutOfRangeException;渲染异常记日志后原样上抛(保留堆栈)

ExportStream / Print无状态:每次调用独立 DataStruct.GetSet() 取空数据集副本、独立 new Report()。同一服务实例可并发调用。

4.2.0 变更(相对 4.1.0)

  • 模板改走 BaseFRService.OpenModel 取内容流(ExportStreamPrint 两处),模板可来自对象存储;日志里的模板标识随之改为"编号(文件名)"
  • 静态构造新增脚本沙箱三开关:WebMode + EnableScriptSecurity + ForbidLocalData
  • ExportStreamAsyncXYS.FR 4.2.0 的基类默认实现提供,本项目不重写

关于脚本沙箱(请留意,此处有行为变化)

客户端渲染的标签和清单模板同样是实施和客户可编辑的,也就是不可信输入,只是爆炸半径从服务端变成单台工作站。

实测(FastReport.Net.Demo 2025.2.8,模板内嵌 File.WriteAllText):

配置 恶意脚本 PDF 导出 打印路径
全关(4.1.0 的状态) 照跑,文件真的写出来了 31303 bytes / 1 页 走到 InvalidPrinterException
只开 EnableScriptSecurity 照跑(官方摘要 "For WebMode only" 属实)
WebMode + 另两个(4.2.0) 编译期被拒:CS0117: Please, don't use the method 'WriteAllText' 31303 bytes / 1 页(字节数与页数均不变 走到 InvalidPrinterException同样

真正起作用的开关是 WebMode,这一点反直觉——它的官方描述只提"在 web 模式下关掉部分功能",没提它是脚本沙箱的总开关。同一组实测确认打开它之后导出输出与打印路径都不受影响:本类只做导出与打印,不使用 FastReport 的预览控件与设计器,WebMode 关掉的那部分交互功能与本类无关。

⚠️ 风险提示:若现网有标签模板依赖脚本调用被禁用的 API(文件系统、P/Invoke 等),升到 4.2.0 后这类模板会在编译期直接报错而不是静默降级。升级前建议先用现网模板跑一遍渲染。禁用名单默认为 DllImport / LoadLibrary / GetProcAddress,加上 WebMode 的存根类机制(覆盖 System.IO 等)。

4.1.0 变更(相对 4.0.0)

  • 跟随 XYS.FR 4.1.0 的接口拆分:BaseFRNetService: BaseFRService 改为 : BaseFRService, IFRPrintServicePrintpublic override 改为 public(不再是基类抽象成员的重写,而是接口实现)。
  • 对下游无影响BaseFRNetService 的公开 API 形状不变,Print 照常可调。

4.0.0 变更(相对 3.0.0)

破坏性

  • BasePrintServiceBaseStreamService 合并为 BaseFRNetService。原来的拆分与 XYS.FR 4.0.0 的 BaseFRService 契约冲突——基类要求同时实现 PrintExportStream,继承任一旧类的具体子类都必然缺另一半,无法落地。
  • BaseStreamService.ExportSream<T>(FRReport, Stream)(拼写错误 + 泛型导出器)删除,由 ExportStream(FRReport, Stream, ExportType) 取代,改为按 ExportType 枚举分发。
  • protected abstract void SetExport(ExportBase)protected virtual void ConfigureExport(ExportBase, ExportType)。由 abstractvirtual,子类不再被迫实现。

修复

  • 项目此前无法编译BasePrintService.Printoverride,隐藏基类抽象成员(CS0533)。
  • Printprinter 入参被完全忽略:无论传什么都用 Printer 属性。现改为 printer 优先。
  • 打印会弹出打印对话框:旧代码在未 Prepare() 的报表上先调 PrintPrepared()(该方法文档明确为"带 Print 对话框打印"),且此时 ShowDialog 还是默认的 true,服务端场景会直接卡死;随后又调一次 Print()。现改为先设好 PrintSettings(含 ShowDialog=false)再单调 Print()——Print() 内部自带 Prepare()
  • ExportType 分发从未实现Jpg/Html/Xls 三种格式此前无任何代码路径。
  • 图片/HTML 导出丢页:单 Stream 输出下未关闭 SeparateFiles / 未启用 EmbedPictures,只有首页进流。
  • throw ex; 丢失堆栈:改为 throw;,与 XYS.FR 4.0.0 统一。
  • EnvironmentSettings 每次调用 new/Dispose:它写的是 FastReport 进程级全局配置,现移入静态构造函数只设一次。
  • catch 块内可能二次抛 NRE:日志用 ActualType.FullName,子类未设 ActualType 时会 NRE 并掩盖真实异常。现回退到运行时类型名。

清理

  • 删除空方法 SetPrint(PrintSettings) 与注释掉的 FastReport.Utils.Config 死代码。
  • MethodBase.GetCurrentMethod().Name 反射取名 → nameof,与 XYS.FR 4.0.0 统一。
  • README 从残桩重写(原文写着"FastReport .NET 2021 版本",实际引用 2025.2.8)。

注意事项

  • net462 目标下语言版本是 C# 7.3(解决方案未设 LangVersion),本项目代码刻意避开 switch 表达式等 C# 8+ 语法。
  • Init() 放在子类构造函数末尾Printer 等属性设置在前。
  • 同进程内允许多个 BaseFRNetService 子类共存(如 Lab / Exam / EMR),共享 XYS.FRDataStruct 实体注册表。
  • 模板根目录默认 AppBase/FR,可通过 ModelRoot 覆盖(见 BaseFRService)。模板不在文件系统上时,改为实现 IConfigManager.OpenModel
Product Compatible and additional computed target framework versions.
.NET net8.0-windows7.0 is compatible.  net9.0-windows was computed.  net10.0-windows was computed. 
.NET Framework net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.2.0 56 9/5/2026
4.1.0 63 9/4/2026
2.1.0.3 381 8/4/2022
2.0.0.3 362 8/4/2022