本着开发与实施分离的思想,设计一个通用的报表设计窗体显得尤为重要(下图为图一):

要求与优点:

  I、报表设计窗体支持所有单据调用,一种单据支持多个打印模板。

  II、报表模板存储在数据库中。一是支持客户端设计及保存模板,二是一次修改所有客户端生效。

  III、点击保存是将模板保存在数据库中,点击另存为可将模板保存为文件。这样可以实现模板的复制。

  IV、预览与打印。已设计好的模板不需要每次都进入设计界面,直接预览或打印即可。

开发环境:

VS2017+SQL SERVER 2014+FastReport.Net(2017.1.16)

由于篇幅较多,本次主要分享设计按钮的功能。闲话少说!

1、数据表设计。

CREATE TABLE [dbo].[AT_REPORT](
[FORMID] [varchar](20) NOT NULL,
[RPT_NO] [varchar](20) NOT NULL,
[RPT_NAME] [varchar](50) NULL,
[FILEDATA] [varbinary](max) NULL,
CONSTRAINT [PK_AT_REPORT] PRIMARY KEY CLUSTERED
(
[FORMID] ASC,
[RPT_NO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

2、新增FastReportDesign窗体(图一):

  1.1引用FastReport库文件。

  

  1.2代码引用。

using System.Data.SqlClient;
using FastReport;
using FastReport.Utils;
using FastReport.Design;

2、定义属性及变量:

说明:FormID是单据ID,即哪种单据调用报表设计窗体则给此属性赋值。RptNo、RptName在点击图一报表种类时赋值。

public string FormID { get; set; } = "PRDT"; //单据ID
private string RptNo, RptName; //报表编号、名称
private DataTable RptTable; //数据表
private DataRow RptRow; //数据行(报表数据源)
private bool isSaveAs = false; //另存为

3、双击设计按钮:

说明:tvwRight是图一右边Treeview的名称。

//设计
private void btnDes_Click(object sender, EventArgs e)
{
if (tvwRight.SelectedNode != null)
{
if (!string.IsNullOrEmpty(FormID) && !string.IsNullOrEmpty(RptNo))
{
InitializeReport("DESIGN");
}
else
{
MessageBox.Show("报表获取失败。", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
else
{
MessageBox.Show("请先选择报表。", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}

4、初始化方法:

注:mymeans.GetDataSet是自己写的类方法,主要是将SQL生成DataSet。

//初始化报表
private void InitializeReport(string RptMode)
{
DataSet Ds = mymeans.GetDataSet("SELECT RPT_NO,RPT_NAME,FILEDATA FROM AT_REPORT WHERE FORMID='" + FormID + "' AND RPT_NO='" + RptNo + "'", "REPORT");
RptTable = Ds.Tables[];
RptRow = RptTable.Rows[];
RegisterDesignerEvents();
DesignReport(RptMode);
}

5、注册事件:

说明:FastReport设计器菜单保存及另存为功能,都是将设计模板保存成文件。由于我们需要将设计模板保存到数据库,所以需要屏蔽掉系统原有的功能自己写。另外需要说明的是,保存按钮不会弹出对话框,所以当点击另存为时,才会触发OpenSaveDialogEventHandler。(可参考FastReport自带范例CustomOpenSaveDialogs)


//菜单事件注册
private void RegisterDesignerEvents()
{
Config.DesignerSettings.CustomSaveDialog += new OpenSaveDialogEventHandler(DesignerSettings_CustomSaveDialog);
Config.DesignerSettings.CustomSaveReport += new OpenSaveReportEventHandler(DesignerSettings_CustomSaveReport);
}

6、设计模板加载:

//设计报表
private void DesignReport(string RptMode)
{
using (Report TargetReport = new Report())
{
TargetReport.FileName = RptName;
if (RptRow["FILEDATA"].ToString().Length > )
{
byte[] ReportBytes = (byte[])RptRow["FILEDATA"];
using (MemoryStream Stream = new MemoryStream(ReportBytes))
{
TargetReport.Load(Stream);
}
}
//操作方式:DESIGN-设计;PREVIEW-预览;PRINT-打印
if (RptMode == "DESIGN")
{
TargetReport.Design();
}
else if (RptMode == "PREVIEW")
{
TargetReport.Prepare();
TargetReport.ShowPrepared();
}
else if (RptMode == "PRINT")
{
TargetReport.Print();
}
}
}

7、另存为对话框:

说明:isSaveAs为true时,表明点击的是另存为按钮。

//保存菜单:对话框
private void DesignerSettings_CustomSaveDialog(object sender, OpenSaveDialogEventArgs e)
{
isSaveAs = true;
}

8、保存委托函数:

//保存菜单:委托函数
private void DesignerSettings_CustomSaveReport(object sender, OpenSaveReportEventArgs e)
{
SaveReport(e.Report);
}

9、报表模板保存:

说明:mymeans.ConOpen()是自己写的类方法,主要是连接数据库。


//保存报表
private void SaveReport(Report TargetReport)
{
try
{
using (MemoryStream msStream = new MemoryStream())
{
//解决困扰多时的多次保存问题。
Config.DesignerSettings.CustomSaveDialog -= new OpenSaveDialogEventHandler(DesignerSettings_CustomSaveDialog);
Config.DesignerSettings.CustomSaveReport -= new OpenSaveReportEventHandler(DesignerSettings_CustomSaveReport);
//保存
TargetReport.Save(msStream);
RptRow["FILEDATA"] = msStream.ToArray();
if (FrameClass.MyMeans.Con == null || FrameClass.MyMeans.Con.State != ConnectionState.Open)
{
mymeans.ConOpen();
}
SqlCommand Cmd = FrameClass.MyMeans.Con.CreateCommand();
Cmd.CommandText = "UPDATE AT_REPORT SET FILEDATA=@FILEDATA WHERE FORMID=@FORMID AND RPT_NO=@RPT_NO";
Cmd.Parameters.AddWithValue("@FILEDATA", msStream.ToArray());
Cmd.Parameters.AddWithValue("@FORMID", FormID);
Cmd.Parameters.AddWithValue("@RPT_NO", RptNo);
Cmd.ExecuteNonQuery();
//另存为
if (isSaveAs == true)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
//设置文件类型
saveFileDialog.Filter = "报表文件(*.frx)|*.frx";
//设置默认文件类型显示顺序
saveFileDialog.FilterIndex = ;
//是否自动在文件名中添加扩展名
saveFileDialog.AddExtension = true;
//是否记忆上次打开的目录
saveFileDialog.RestoreDirectory = true;
//设置默认文件名
saveFileDialog.FileName = RptName;
//按下确定选择的按钮
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
//获得文件路径
string localFilePath = saveFileDialog.FileName.ToString();
//文件保存
FileStream fsStream = new FileStream(localFilePath, FileMode.Create);
msStream.WriteTo(fsStream);
//资源释放
fsStream.Close();
fsStream = null;
}
//赋初始值
isSaveAs = false;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}

好了,主要的功能就分享到此,希望对大家有一些帮助。

VS2017集成FastReport.Net并将模板保存到数据库的更多相关文章

  1. POI读取Excel数据保存到数据库,并反馈给用户处理信息(导入带模板的数据)

    今天遇到这么一个需求,将课程信息以Excel的形式导入数据库,并且课程编号再数据库中不能重复,也就是我们需要先读取Excel提取信息之后保存到数据库,并将处理的信息反馈给用户.于是想到了POI读取文件 ...

  2. 【VBA】获取模板保存的路径

    使用VBA如何获取模板保存的路径呢?具体代码如下: Sub 获取Excle模板保存路径() MsgBox "获取Excle模板保存路径:" & Application.Te ...

  3. zabbix利用自带的模板监控mysql数据库

    zabbix利用自带的模板监控mysql数据库 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 有些东西你不会的时候觉得它特别难,但是当你去做的时候就发现如此的简单~zabbix功能 ...

  4. ASP.NET网络爬虫小研究 HtmlAgilityPack基础,爬取数据保存在数据库中再显示再自己的网页中

    1.什么是网络爬虫 关于爬虫百度百科这样定义的:网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些 ...

  5. 大数据-将MP3保存到数据库并读取出来《黑马程序员_超全面的JavaWeb视频教程vedio》day17

    黑马程序员_超全面的JavaWeb视频教程vedio\黑马程序员_超全面的JavaWeb教程-源码笔记\JavaWeb视频教程_day17-资料源码\day17_code\day17_1\ 大数据 目 ...

  6. JAVA从文本文件(txt)读取一百万条数据保存到数据库

    Java读取大文本文件保存到数据库 1.追求效率 将文件读取到内存,效率比较高,经过测试读取1G左右的文本文件,机器内存消耗达到接近3个G,对内存消耗太大,不建议使用 2.通过调用第三方类库实现 通过 ...

  7. Express+MySQL实现图片上传到服务器并把路径保存到数据库中

    demo准备:mysql5.7.20 express4.0 处理图片文件的中间件Multer 先搭建服务器并展示html页面 const express = require("express ...

  8. XAF:如何让用户在运行时个性化界面并将个性化信息保存到数据库中 win/web/entityframework/xpo

    本主题介绍如何启用管理模型差异(XAFML),并将设置存储在数据库中.   名词解释: 1.模型:XAF中把所有应用程序的结构都用模型来定义,比如列表,有哪些列,名称是什么,对应的字段名是什么,业务对 ...

  9. ASP.NET将Session保存到数据库中

    因为ASP.NET中Session的存取机制与ASP相同,都是保存在进行中, 一旦进程崩溃,所有Session信息将会丢失,所以我采取了将Session信息保存到SQL Server中,尽管还有其它的 ...

随机推荐

  1. sqserver2008触发器

    @参考博文 先上代码 先建个表用于测试 CREATE TRIGGER INSERT_forbidden on s after INSERT AS BEGIN RAISERROR(,) ROLLBACK ...

  2. 测试SQL

    create database testDB create table users(    id int primary key identity(1,1),    uname nvarchar(20 ...

  3. NetworkStateReceiver的简单应用

    一.网络状态接收者是一个广播接收者当网络状态发生改变时会收到网络状态改变的广播 本例当网络状态改变时会进行相应处理 例如当断网时会发出通知点击通知后 会打开网络设置界面 代码如下: package c ...

  4. centos7 二进制安装包安装 mysql5.6

    centos7 二进制安装包安装 mysql5.6 一.下载mysql5.6二进制安装包 http://mirrors.sohu.com/mysql/MySQL-5.6/ 如:mysql-5.6.34 ...

  5. nginx 反向代理 502 Bad Gateway

    查看nginx的error.log日志文件发现如下信息: upstream sent too big header while reading response header from upstrea ...

  6. MVC仓储使用join

    代码: var result = from mpc in this.Context.Set<Domain.S_MENU_PURVIEWCODE>() join menu in this.C ...

  7. js-移动端android浏览器中input框被软键盘遮住的问题解决方案

    我遇到的问题:在一个页面里有一个弹出层之前我给我的最外层加了固定定位 用了下面的方法也不好使:没有办法我将之改为绝对定位层级变高在加上一个顶部标签通过js计算顶部高度来实现满屏遮挡: <sect ...

  8. 抓取访客ip

    $realip = $_SERVER['REMOTE_ADDR'] $proxy_ip = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);//有用到代理 ...

  9. How to Set Up an Rsync Daemon on Your Linux Server

    Introduction This tutorial will take you through setting up an rsync daemon on your Linux server. Yo ...

  10. Java 8 可重复注解与类型注解

    Java 8 可重复注解与类型注解 Java 8 对注解处理提供了两点改进:可重复的注解及可用于类型的注解. // 首先要提供一个容器,MyAnnotation 才能用于可重复注解 @Target({ ...