XYS.FRNet
4.2.0
dotnet add package XYS.FRNet --version 4.2.0
NuGet\Install-Package XYS.FRNet -Version 4.2.0
<PackageReference Include="XYS.FRNet" Version="4.2.0" />
<PackageVersion Include="XYS.FRNet" Version="4.2.0" />
<PackageReference Include="XYS.FRNet" />
paket add XYS.FRNet --version 4.2.0
#r "nuget: XYS.FRNet, 4.2.0"
#:package XYS.FRNet@4.2.0
#addin nuget:?package=XYS.FRNet&version=4.2.0
#tool nuget:?package=XYS.FRNet&version=4.2.0
XYS.FRNet
FastReport .NET 渲染宿主。只负责:拿 XYS.FR(XYS.FR.V3 项目)准备好的 DataSet 与模板路径,调用 FastReport 引擎出 PDF/JPG/HTML/XLSX 流或直接送打印机。不含任何数据契约与配置解析(实体注册、FRTables.frd 生成、模板号映射都在 XYS.FR 里)。
- 目标框架:
net462/net8.0-windows - 报表引擎:
FastReport.Net.Demo2025.2.8 - 依赖:
XYS.FR.V3、XYS.Utils.Sys、XYS.Utils.Log4Net(同解决方案项目引用) - 程序集名:
XYS.FRNet;命名空间XYS.FR
⚠️ 当前引用的是 Demo 版 FastReport 包,导出结果带演示水印、有页数限制。正式部署需替换为已授权的
FastReport.Net包(仅需改PackageReference,代码无需改动)。
核心类型
| 类型 | 职责 |
|---|---|
BaseFRNetService |
抽象渲染服务基类:实现 BaseFRService 的 ExportStream,并实现 IFRPrintService 的 Print |
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=true、EmbeddingFonts=true、AllowModify=false |
Jpg |
ImageExport(ImageFormat=Jpeg) |
SeparateFiles=false |
Html |
HTMLExport |
SinglePage=true、EmbedPictures=true、Navigator=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 |
| 异常 | 参数为 null 抛 ArgumentNullException;未知 ExportType 抛 ArgumentOutOfRangeException;渲染异常记日志后原样上抛(保留堆栈) |
ExportStream / Print 均无状态:每次调用独立 DataStruct.GetSet() 取空数据集副本、独立 new Report()。同一服务实例可并发调用。
4.2.0 变更(相对 4.1.0)
- 模板改走
BaseFRService.OpenModel取内容流(ExportStream与Print两处),模板可来自对象存储;日志里的模板标识随之改为"编号(文件名)" - 静态构造新增脚本沙箱三开关:
WebMode+EnableScriptSecurity+ForbidLocalData ExportStreamAsync由XYS.FR4.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.FR4.1.0 的接口拆分:BaseFRNetService由: BaseFRService改为: BaseFRService, IFRPrintService,Print由public override改为public(不再是基类抽象成员的重写,而是接口实现)。 - 对下游无影响:
BaseFRNetService的公开 API 形状不变,Print照常可调。
4.0.0 变更(相对 3.0.0)
破坏性
BasePrintService与BaseStreamService合并为BaseFRNetService。原来的拆分与XYS.FR4.0.0 的BaseFRService契约冲突——基类要求同时实现Print与ExportStream,继承任一旧类的具体子类都必然缺另一半,无法落地。BaseStreamService.ExportSream<T>(FRReport, Stream)(拼写错误 + 泛型导出器)删除,由ExportStream(FRReport, Stream, ExportType)取代,改为按ExportType枚举分发。protected abstract void SetExport(ExportBase)→protected virtual void ConfigureExport(ExportBase, ExportType)。由abstract改virtual,子类不再被迫实现。
修复
- 项目此前无法编译:
BasePrintService.Print缺override,隐藏基类抽象成员(CS0533)。 Print的printer入参被完全忽略:无论传什么都用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.FR4.0.0 统一。EnvironmentSettings每次调用 new/Dispose:它写的是 FastReport 进程级全局配置,现移入静态构造函数只设一次。catch块内可能二次抛 NRE:日志用ActualType.FullName,子类未设ActualType时会 NRE 并掩盖真实异常。现回退到运行时类型名。
清理
- 删除空方法
SetPrint(PrintSettings)与注释掉的FastReport.Utils.Config死代码。 MethodBase.GetCurrentMethod().Name反射取名 →nameof,与XYS.FR4.0.0 统一。- README 从残桩重写(原文写着"FastReport .NET 2021 版本",实际引用 2025.2.8)。
注意事项
net462目标下语言版本是 C# 7.3(解决方案未设LangVersion),本项目代码刻意避开 switch 表达式等 C# 8+ 语法。Init()放在子类构造函数末尾,Printer等属性设置在前。- 同进程内允许多个
BaseFRNetService子类共存(如 Lab / Exam / EMR),共享XYS.FR的DataStruct实体注册表。 - 模板根目录默认
AppBase/FR,可通过ModelRoot覆盖(见BaseFRService)。模板不在文件系统上时,改为实现IConfigManager.OpenModel。
| Product | Versions 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. |
-
.NETFramework 4.6.2
- FastReport.Net.Demo (>= 2025.2.8)
- XYS.FR (>= 4.2.0)
- XYS.Utils.Log4Net (>= 2.5.0)
- XYS.Utils.Sys (>= 2.6.0)
-
net8.0-windows7.0
- FastReport.Net.Demo (>= 2025.2.8)
- XYS.FR (>= 4.2.0)
- XYS.Utils.Log4Net (>= 2.5.0)
- XYS.Utils.Sys (>= 2.6.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.