B/S FastReprot使用
FastReport 交流群
群 号:554714044
前言
由于公司开发新产品,前后端分离.netcore +Angular ,之前C/S项目一直使用FastReport ,考虑到员工切换比较困难,而且最最重要的是BS版少了很多内容,例如合计,函数最常用的功能都没有,所以B/S端打印控件继续沿用C/S模式。
一、逻辑视图
二、具体实现
1.Winform设计
如上图所示,这里做了一个打印模板与数据源的管理。在这里可以指定具体页面要调什么后端接口,打印什么数据,打印格式设计。全部WinForm实现。将数据源与打印格式模板存储到数据库。后端直接调取即可。
优点:1.与之前WinForm版无缝对接,开发人员不用学习即可使用。
2.做到数据源与打印格式集中化管理,而且可以根据客户需求,实施人员自己调整添加打印格式,不需要开发程序。
3.数据源多样化,可以根据特殊需求,自己拼接sql,也可以直接查询数据库表。满足客户多样化,个性化需求。
4.可以根据具体单据ID,调试打印格式。
缺点:WinForm 没有做成网络版,此设计器只能在服务器端(内网)使用。(本来设计就是要服务器设计,下面的人员用不到,缺点还可以接受
)
以下是部分代码
/// <summary>
/// 绑定数据明细
/// </summary>
public void BindGridDts()
{
SReportManageDtsRule rule = new SReportManageDtsRule();
DataTable dtDts = rule.RShow(" AND DMainID=" + SysString.ToDBString(HTDataID) + " ORDER BY DSeq", ProcessGrid.GetQueryField(gridView1)); gridView1.GridControl.DataSource = dtDts;
gridView1.GridControl.Show();
} /// <summary>
/// 新增
/// </summary>
public string EntityAdd()
{
SReportManageRule rule = new SReportManageRule();
SReportManage entity = EntityGet();
SReportManageDts[] entitydts = EntityDtsGet();
SReportFile entityFile = new SReportFile();
if (chkMB.Checked)
{
entityFile.DContext = HttSoft.WinUIBase.FastReportX.ConvertToBinaryByPath(txtFilePath.Text.Trim());
entityFile.DFileName = entity.DFileName;
} rule.RAdd(entity, entitydts, entityFile);
return entity.DID;
} /// <summary>
/// 修改
/// </summary>
public void EntityUpdate()
{
SReportManageRule rule = new SReportManageRule();
SReportManage entity = EntityGet();
SReportManageDts[] entitydts = EntityDtsGet();
SReportFile entityFile = new SReportFile();
if (chkMB.Checked)
{
entityFile.DID = entity.DFileID;
entityFile.SelectByID();
entityFile.DContext = HttSoft.WinUIBase.FastReportX.ConvertToBinaryByPath(txtFilePath.Text.Trim());
entityFile.DFileName = entity.DFileName;
} rule.RUpdate(entity, entitydts, entityFile);
} /// <summary>
/// 设置
/// </summary>
public void EntitySet()
{
SReportManage entity = new SReportManage();
entity.DID = HTDataID;
bool findFlag = entity.SelectByID();
drpForm.Text = SysConvert.ToString(entity.DMenuID);
txtReportName.Text = entity.DReportName.ToString();
txtDSeq.Text = entity.DSeq.ToString();
txtAPI.Text = entity.DWebApi.ToString(); BindGridDts();
} /// <summary>
/// 删除
/// </summary>
public void EntityDelete()
{
SReportManageRule rule = new SReportManageRule();
SReportManage entity = EntityGet();
rule.RDelete(entity);
} #region 自定义方法
/// <summary>
/// 获得实体
/// </summary>
/// <returns></returns>
private SReportManage EntityGet()
{
SReportManage entity = new SReportManage();
entity.DID = HTDataID;
entity.SelectByID();
entity.DMenuID = SysConvert.ToString(drpForm.Text.Trim());
entity.DReportName = txtReportName.Text.Trim();
entity.DSeq = SysConvert.ToInt32(txtDSeq.Text.Trim());
entity.DWebApi = txtAPI.Text.Trim();
entity.DFileName = txtReportName.Text.Trim() + ".frx"; return entity;
} /// <summary>
/// 获得实体
/// </summary>
/// <returns></returns>
private SReportManageDts[] EntityDtsGet()
{ int index = ;
for (int i = ; i < gridView1.RowCount; i++)
{
if (SysConvert.ToString(gridView1.GetRowCellValue(i, "SqlName")) != "")
{
index++;
}
}
SReportManageDts[] entitydts = new SReportManageDts[index];
index = ;
for (int i = ; i < gridView1.RowCount; i++)
{
if (SysConvert.ToString(gridView1.GetRowCellValue(i, "SqlName")) != "")
{
entitydts[index] = new SReportManageDts();
entitydts[index].DMainID = SysConvert.ToString(gridView1.GetRowCellValue(i, "DMainID"));
if (entitydts[index].DMainID == HTDataID && HTDataID != "")//已存在表示修改
{
entitydts[index].DID = SysConvert.ToString(gridView1.GetRowCellValue(i, "DID"));
entitydts[index].SelectByID();
}
else//新增
{
entitydts[index].DMainID = HTDataID;
entitydts[index].DSeq = i + ;
} entitydts[index].DMainID = SysConvert.ToString(gridView1.GetRowCellValue(i, "DMainID"));
entitydts[index].DSeq = SysConvert.ToInt32(gridView1.GetRowCellValue(i, "DSeq"));
entitydts[index].DataSourceName = SysConvert.ToString(gridView1.GetRowCellValue(i, "DataSourceName"));
entitydts[index].SqlName = SysConvert.ToString(gridView1.GetRowCellValue(i, "SqlName"));
entitydts[index].SqlStr = SysConvert.ToString(gridView1.GetRowCellValue(i, "SqlStr"));
entitydts[index].QueryName = SysConvert.ToString(gridView1.GetRowCellValue(i, "QueryName"));
entitydts[index].SqlFlag = SysConvert.ToInt32(gridView1.GetRowCellValue(i, "SqlFlag"));
entitydts[index].SourceType = SysConvert.ToInt32(gridView1.GetRowCellValue(i, "SourceType"));
entitydts[index].Remark = SysConvert.ToString(gridView1.GetRowCellValue(i, "Remark")); index++;
}
}
return entitydts;
} #endregion
//添加一个基础模板
private void btnLook_Click(object sender, EventArgs e)
{
try
{
if (HTFormStatus == FormStatus.新增 || HTFormStatus == FormStatus.修改)
{
openFileDialog1.FileName = "";
openFileDialog1.Filter = "(*.frx)|*.frx|(*.fr3)|*.fr3|(*.*)|*.*";
openFileDialog1.ShowDialog();
if (openFileDialog1.FileName != string.Empty)
{
txtFilePath.Text = openFileDialog1.FileName;
}
} }
catch (Exception E)
{
MessageBox.Show(E.Message);
}
}
//窗体加载
private void HSPrintEdit_Load(object sender, EventArgs e)
{
//Common.BindFormID(drpForm);
Common.BindReportSource(drpReportSource, true);
}
//设计
private void btnDesign_Click(object sender, EventArgs e)
{
try
{
if (HTDataID == "")
{
MessageBox.Show("请先保存单据");
return;
}
SReportManage reportManage = new SReportManage();
reportManage.DID = HTDataID;
reportManage.SelectByID();
if (reportManage.DFileID == "")
{
MessageBox.Show("没有找到打印格式");
return;
} if (!chksql.Checked)
{
if (SysConvert.ToString(txtDataID.Text.Trim()) == "")
{
MessageBox.Show("请输入数据源ID");
return;
}
FastReport.ReportRun(HTDataID, (int)ReportPrintType.设计, new string[] { "DID", "DMainID" }, new string[] { SysConvert.ToString(txtDataID.Text.Trim()), SysConvert.ToString(txtDataID.Text.Trim()) });
}
else
{
if (SysConvert.ToString(txtsql.Text.Trim()) == "")
{
MessageBox.Show("请输入数据源sql");
return;
}
DataTable dt = SysUtils.Fill(txtsql.Text.Trim());
FastReport.ReportRunTable(HTDataID, (int)ReportPrintType.设计, dt);
} }
catch (Exception E)
{
MessageBox.Show(E.Message);
}
}
//预览
private void btnPreview_Click(object sender, EventArgs e)
{
try
{
if (HTDataID == "")
{
MessageBox.Show("请先保存单据");
return;
}
SReportManage reportManage = new SReportManage();
reportManage.DID = HTDataID;
reportManage.SelectByID();
if (reportManage.DFileID == "")
{
MessageBox.Show("没有找到打印格式");
return;
} if (!chksql.Checked)
{
if (SysConvert.ToString(txtDataID.Text.Trim()) == "")
{
MessageBox.Show("请输入数据源ID");
return;
}
FastReport.ReportRun(HTDataID, (int)ReportPrintType.预览, new string[] { "DID", "DMainID" }, new string[] { SysConvert.ToString(txtDataID.Text.Trim()), SysConvert.ToString(txtDataID.Text.Trim()) });
}
else
{
if (SysConvert.ToString(txtsql.Text.Trim()) == "")
{
MessageBox.Show("请输入数据源");
return;
}
DataTable dt = SysUtils.Fill(txtsql.Text.Trim());
FastReport.ReportRunTable(HTDataID, (int)ReportPrintType.预览, dt);
} }
catch (Exception E)
{
MessageBox.Show(E.Message);
}
}
2.MVC端
为了将打印格式发布出去,这里特意做了一个mvc的程序,放在前端与后端之间,作为桥梁。
因为客户端只需要预览和打印,所以这里我只做了一个预览+打印的接口。设计在WinForm端处理,这里不需要。
以下是Preview的代码实现。
public ActionResult Preview()
{
webReport = new WebReport();
webReport.Width = Unit.Percentage();
webReport.Height = Unit.Percentage(); string DataID = Request.QueryString["id"]; string ReportID = Request.QueryString["rid"]; string token = Request.QueryString["token"]; ReportModel model = new ReportModel();
model.DataID = DataID;
model.ReportID = ReportID; String token2 = "Bearer " + token;
HttpClient client = new HttpClient();
client.BaseAddress = _baseAddress;
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
//获取模板文件地址,获取打印数据源webapi接口地址
#region 获取模板文件地址,获取打印数据源webapi接口地址
var jsonStr = JsonConvert.SerializeObject(model);
HttpContent cont = new StringContent(jsonStr);
cont.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var returnStr = "";
HttpResponseMessage resp = client.PostAsync("/api/SReportManage/getdataurl", cont).Result;//post提交数据,
if (resp.IsSuccessStatusCode)
{
returnStr = resp.Content.ReadAsStringAsync().Result;
}
ReportResult dtos = JsonConvert.DeserializeObject<ReportResult>(returnStr); #endregion //获取打印数据源
#region 获取打印数据源 HttpClient client2 = new HttpClient();
client2.BaseAddress = _baseAddress;
client2.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client2.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); var jsonStr2 = JsonConvert.SerializeObject(model);
HttpContent cont2 = new StringContent(jsonStr2);
cont2.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var returnStr2 = "";
HttpResponseMessage resp2 = client2.PostAsync(dtos.Data.WebApi, cont2).Result;//post提交数据,
if (resp2.IsSuccessStatusCode)
{
returnStr2 = resp2.Content.ReadAsStringAsync().Result;
}
ReportSourceResult result = JsonConvert.DeserializeObject<ReportSourceResult>(returnStr2);
if (result != null)
{
for (int i = ; i < result.Data.Count; i++)
{
webReport.Report.RegisterData(result.Data[i].dtsource, result.Data[i].TBName);
webReport.Report.GetDataSource(result.Data[i].TBName).Enabled = true;
}
} #endregion //webReport.Report.Load(dtos.Data.FileUrl + "Test.frx");
webReport.Report.Load(ConfigurationManager.AppSettings["ReportFilePath"] + dtos.Data.FileUrl);
webReport.ToolbarStyle = ToolbarStyle.Small;
webReport.ToolbarIconsStyle = ToolbarIconsStyle.Blue;
webReport.ToolbarBackgroundStyle = ToolbarBackgroundStyle.Custom; //webReport.PrintPdf(); webReport.PreviewMode = true;//预览模式
webReport.PrintInPdf = true;//在PDF打印 //webReport.DesignerPath = "~/WebReportDesigner/index.html";
//webReport.DesignerSavePath = "~/App_Data/DesignedReports";
//webReport.DesignerSaveCallBack = "~/Report/SaveDesignedReport";
webReport.ID = "DesignReport";
ViewBag.WebReport = webReport;
return View();
}
其中以下几点是我做了特殊化的设置
webReport.ToolbarStyle = ToolbarStyle.Small; //将原先的图标变小(太大太难看了)
webReport.ToolbarIconsStyle = ToolbarIconsStyle.Blue;
webReport.ToolbarBackgroundStyle = ToolbarBackgroundStyle.Custom;
(下拉菜单的汉化还没有找到,需要研究一下。)
webReport.PreviewMode = true;//预览模式
webReport.PrintInPdf = true;//在PDF打印
这里就是对接前端的打印接口。前端只需要调取我发布的网址,并且把我需要的参数(数据ID,打印模板ID,token传送给我即可。)
3.后端
后端接口主要是实现根据MVC端传送过来的打印模板ID,将数据源和模板传送给MVC端。由MVC端进行拼接组装。
主要代码如下:
public List<ReportDataSource> GetDataSource(ReportModel entitydto)
{
try
{
List<ReportDataSource> lst = new List<ReportDataSource>();
IDBTransAccess sqlTrans = TransSysUtils.GetDBTransAccess();
try
{
sqlTrans.OpenTrans(); lst = this.GetDataSource(entitydto, sqlTrans); sqlTrans.CommitTrans();
return lst;
}
catch (Exception TE)
{
sqlTrans.RollbackTrans();
throw TE;
}
}
catch (BaseException)
{
throw;
}
catch (Exception E)
{
throw new BaseException(E.Message);
}
} public List<ReportDataSource> GetDataSource(ReportModel entitydto, IDBTransAccess sqlTrans)
{
try
{
List<ReportDataSource> lst = ReportRun(entitydto.ReportID, new string[] { "DID","DMainID" }, new string[] { entitydto.DataID,entitydto.DataID }, sqlTrans); return lst; }
catch (BaseException)
{
throw;
}
catch (Exception E)
{
throw new BaseException(E.Message);
}
} #endregion public List<ReportDataSource> ReportRun(string reportID, string[] queryName, string[] queryValue, IDBTransAccess sqlTrans)
{
List<ReportDataSource> lst = new List<ReportDataSource>();
string sql = "Select * from Data_SReportManageDts where DMainID=" + SysString.ToDBString(reportID);
DataTable dtSource = sqlTrans.Fill(sql);
if (dtSource.Rows.Count > )
{
foreach (DataRow dr in dtSource.Rows)
{
bool findSource = false;
string conditionStr = string.Empty;
if (SysConvert.ToInt32(dr["SqlFlag"]) == )
{
string[] tempA = dr["QueryName"].ToString().Split(' ');
for (int q = ; q < queryName.Length; q++)
{
for (int fi = ; fi < tempA.Length; fi++)
{
if (queryName[q].ToString().ToUpper() == tempA[fi].ToUpper())
{
if (conditionStr != string.Empty)
{
conditionStr += " AND ";
}
conditionStr += queryName[q].ToString() + "=" + SysString.ToDBString(queryValue[q]);
findSource = true;
break;
}
} }
}
else
{
conditionStr = SysConvert.ToString(dr["QueryName"]).ToUpper();
for (int i = ; i < queryName.Length; i++)
{
string queryStr = "{" + queryName[i].ToUpper() + "}"; conditionStr = conditionStr.Replace(queryStr, SysString.ToDBString(queryValue[i]));
}
if (conditionStr.Contains("{") || conditionStr.Contains("}"))
{
findSource = false;
}
else
{
findSource = true;
}
}
if (findSource)
{ if (SysConvert.ToInt32(dr["SqlFlag"]) == )
{ sql = "select * from (" + dr["SqlStr"].ToString() + ") a where " + conditionStr;
}
else
{ sql = dr["SqlStr"].ToString() + " " + conditionStr;
}
DataTable dt = sqlTrans.Fill(sql); ReportDataSource source = new ReportDataSource();
source.dtsource = dt;
source.TBName = dr["SqlName"].ToString();
lst.Add(source); }
else
{
if (dr["SqlStr"].ToString() != string.Empty)
{
sql = dr["SqlStr"].ToString();
DataTable dt = sqlTrans.Fill(sql); ReportDataSource source = new ReportDataSource();
source.dtsource = dt;
source.TBName = dr["SqlName"].ToString();
lst.Add(source); }
}
}
} return lst;
}
FastReport 交流群
群 号:554714044
B/S FastReprot使用的更多相关文章
- FastReport调用Delphi中的自定义函数(人民币大写金额)mtm
1. 在 FormCreate 中向FastReprot添加函数 (fPrint)窗口 procedure TfPrint.FormCreate(Sender: TObject); frxReport ...
随机推荐
- [Hbase]Hbase技术方案
HBase架构简介 HBase在完全分布式环境下,由Master进程负责管理RegionServers集群的负载均衡以及资源分配,ZooKeeper负责集群元数据的维护并且监控集群的状态以防止单点故障 ...
- Pairs of Songs With Total Durations Divisible by 60 LT1010
In a list of songs, the i-th song has a duration of time[i] seconds. Return the number of pairs of s ...
- ubuntu系统ftp连接 以及ssh连接
tfp连接 ssh连接 ubuntu下ssh使用 与 SCP 使用 1 ssh远程登录服务器 ssh username@remote_ip #将username换成自己的用户名,将remote_ip换 ...
- 2018.11.02 NOIP模拟 优美的序列(数论+单调栈/链表)
传送门 考虑如果一个区间满足最小值等于最大公约数那么这个区间是合法的. 因此我们对于每一个点维护可以延展到的最左/右端点保证这一段区间的gcdgcdgcd等于这个点的值. 这个可以用之前同类的链表或者 ...
- IntelliJ IDEA 2017版 SpringBoot测试类编写
SpringBoot的测试类编写Demo 源码见 https://github.com/liushaoye/baseone.git
- 学以致用三----centos7.2基本环境补充
补充: 在上一篇里,加时间戳 echo ‘export HISTTIMEFORMAT ="%F %T `whoami`" ’ >> /etc/profile sourc ...
- ThinkPHP3.2.3:使用模块映射隐藏后台真实访问地址
例如:项目应用目录/Application下模块如下,默认后台模块为Admin 现在需要修改后台模块的访问地址,以防被别有用心的人很容易就猜到,然后各种乱搞... (在公共配置文件/Applicati ...
- 11-border(边框)
边框 border:边框的意思,描述盒子的边框 边框有三个要素: 粗细 线性样式 颜色 border: solid 如果颜色不写,默认是黑色.如果粗细不写,不显示边框.如果只写线性样式,默认的有上下左 ...
- weat!!团队
摘要: 团队名称:weat!! 团队成员:刘波 崔和杰 简介: 刘波:性别男,爱好:动漫,徒步旅行.在组内负责程序编写这一部分. 优点:认真负责,不懂就会去问. 崔和杰:性别男,爱好:篮球.在组内负责 ...
- Mapnik
Downloads Latest Release The latest release is Mapnik v3.0.22.最新版本是Mapnik v3.0.22. Mapnik 3.0.22 Rel ...