最近项目上整合打印模块,之前是将打印报表用文件的形式保存,在代码控制上比较方便,如下图红框的文件保存按钮,点击保存就好了
这种做法呢也有相应的缺点:报表更新时,需要给每台客户端都更新一遍,比较繁琐,而且容易更新漏。。。
现在的做法是将报表保存至数据库中,这样的话,有报表更新的话,就不用再一台一台客户端繁琐的更新了。
在调研的过程中,习惯性的去找XRDesignFormEx对象有没有保存相关的事件,结果发现并没有,只公开了一个ReportStateChanged事件,显然不能满足需求。
只好继续探索,过程不再熬述,直接上结论吧
XRDesignFormEx对象有一个DesignPanel属性(XRDesignPanel对象),这个对象公开了一个AddCommandHandler的方法,可以基于这个方法给编辑器绑定Command,我们只要实现自己想要的Command就可以了。
话不多说,上代码,
首先继承ICommandHandler接口,实现自己的CommandHandler,代码如下:
/// <summary>
/// Dev报表设计命令捕获自定义处理
/// </summary>
public class ReportCommandHandler : ICommandHandler
{
/// <summary>
/// 报表保存事件
/// </summary>
public event Action ReportSave;
/// <summary>
/// 设置支持自定义处理的命令
/// </summary>
/// <param name="command"></param>
/// <param name="useNextHandler"></param>
/// <returns></returns>
public bool CanHandleCommand(ReportCommand command, ref bool useNextHandler)
{
//捕获保存事件
if (command == ReportCommand.SaveFile || command == ReportCommand.SaveAll)
{
//控制是否执行报表默认处理,此处需要设置为false,屏蔽报表默认Command行为
useNextHandler = false;
return true;
}
return false;
}
/// <summary>
/// 针对特定命令执行自定义操作
/// </summary>
/// <param name="command"></param>
/// <param name="args"></param>
public void HandleCommand(ReportCommand command, object[] args)
{
if (command == ReportCommand.SaveFile || command == ReportCommand.SaveAll)
{
ReportSave?.Invoke();
}
}
第二步,将上述自定义的CommandHandler添加至报表编辑器
var designForm = new XRDesignFormEx
{
FormBorderStyle = FormBorderStyle.None,
Dock = DockStyle.Fill
};
//隐藏另存为和保存全部按钮
designForm.DesignPanel.SetCommandVisibility(new ReportCommand[]
{
ReportCommand.SaveFileAs,
ReportCommand.SaveAll
}, CommandVisibility.None);
var command = new ReportCommandHandler();
command.ReportSave += ReportSave;
designForm.DesignPanel.AddCommandHandler(command);
第三步,在ReportSave方法中处理保存数据库的逻辑即可
/// <summary>
/// 报表保存事件
/// </summary>
private void ReportSave()
{
try
{
using (var memory = new MemoryStream())
{
//将报表文件保存至内存中
report.SaveLayout(memory);
//转换成字符串
var content = Encoding.UTF8.GetString(memory.ToArray());
//保存入库操作。。。
}
}
catch (Exception ex)
{
MessageBox.Show("保存失败"+ ex.Message, "保存", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
第三部代码中的report对象是在编辑器中打开的报表对象,参考代码如下:
var report = new XtraReport();
//加载模板
using (var templateStream = new MemoryStream(Encoding.UTF8.GetBytes(实际的模板字符串)))
{
report.LoadLayout(templateStream);
}
//打开模板
designForm.OpenReport(report);