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 没有做成网络版,此设计器只能在服务器端(内网)使用。(本来设计就是要服务器设计,下面的人员用不到,缺点还可以接受
)
以下是部分代码
1 /// <summary> 2 /// 绑定数据明细 3 /// </summary> 4 public void bindgriddts() 5 { 6 sreportmanagedtsrule rule = new sreportmanagedtsrule(); 7 datatable dtdts = rule.rshow(" and dmainid=" + sysstring.todbstring(htdataid) + " order by dseq", processgrid.getqueryfield(gridview1)); 8 9 gridview1.gridcontrol.datasource = dtdts; 10 gridview1.gridcontrol.show(); 11 } 12 13 /// <summary> 14 /// 新增 15 /// </summary> 16 public string entityadd() 17 { 18 sreportmanagerule rule = new sreportmanagerule(); 19 sreportmanage entity = entityget(); 20 sreportmanagedts[] entitydts = entitydtsget(); 21 sreportfile entityfile = new sreportfile(); 22 if (chkmb.checked) 23 { 24 entityfile.dcontext = httsoft.winuibase.fastreportx.converttobinarybypath(txtfilepath.text.trim()); 25 entityfile.dfilename = entity.dfilename; 26 } 27 28 rule.radd(entity, entitydts, entityfile); 29 return entity.did; 30 } 31 32 /// <summary> 33 /// 修改 34 /// </summary> 35 public void entityupdate() 36 { 37 sreportmanagerule rule = new sreportmanagerule(); 38 sreportmanage entity = entityget(); 39 sreportmanagedts[] entitydts = entitydtsget(); 40 sreportfile entityfile = new sreportfile(); 41 if (chkmb.checked) 42 { 43 entityfile.did = entity.dfileid; 44 entityfile.selectbyid(); 45 entityfile.dcontext = httsoft.winuibase.fastreportx.converttobinarybypath(txtfilepath.text.trim()); 46 entityfile.dfilename = entity.dfilename; 47 } 48 49 rule.rupdate(entity, entitydts, entityfile); 50 } 51 52 /// <summary> 53 /// 设置 54 /// </summary> 55 public void entityset() 56 { 57 sreportmanage entity = new sreportmanage(); 58 entity.did = htdataid; 59 bool findflag = entity.selectbyid(); 60 drpform.text = sysconvert.tostring(entity.dmenuid); 61 txtreportname.text = entity.dreportname.tostring(); 62 txtdseq.text = entity.dseq.tostring(); 63 txtapi.text = entity.dwebapi.tostring(); 64 65 bindgriddts(); 66 } 67 68 69 /// <summary> 70 /// 删除 71 /// </summary> 72 public void entitydelete() 73 { 74 sreportmanagerule rule = new sreportmanagerule(); 75 sreportmanage entity = entityget(); 76 rule.rdelete(entity); 77 } 78 79 #region 自定义方法 80 /// <summary> 81 /// 获得实体 82 /// </summary> 83 /// <returns></returns> 84 private sreportmanage entityget() 85 { 86 sreportmanage entity = new sreportmanage(); 87 entity.did = htdataid; 88 entity.selectbyid(); 89 entity.dmenuid = sysconvert.tostring(drpform.text.trim()); 90 entity.dreportname = txtreportname.text.trim(); 91 entity.dseq = sysconvert.toint32(txtdseq.text.trim()); 92 entity.dwebapi = txtapi.text.trim(); 93 entity.dfilename = txtreportname.text.trim() + ".frx"; 94 95 96 return entity; 97 } 98 99 /// <summary> 100 /// 获得实体 101 /// </summary> 102 /// <returns></returns> 103 private sreportmanagedts[] entitydtsget() 104 { 105 106 int index = 0; 107 for (int i = 0; i < gridview1.rowcount; i++) 108 { 109 if (sysconvert.tostring(gridview1.getrowcellvalue(i, "sqlname")) != "") 110 { 111 index++; 112 } 113 } 114 sreportmanagedts[] entitydts = new sreportmanagedts[index]; 115 index = 0; 116 for (int i = 0; i < gridview1.rowcount; i++) 117 { 118 if (sysconvert.tostring(gridview1.getrowcellvalue(i, "sqlname")) != "") 119 { 120 entitydts[index] = new sreportmanagedts(); 121 entitydts[index].dmainid = sysconvert.tostring(gridview1.getrowcellvalue(i, "dmainid")); 122 if (entitydts[index].dmainid == htdataid && htdataid != "")//已存在表示修改 123 { 124 entitydts[index].did = sysconvert.tostring(gridview1.getrowcellvalue(i, "did")); 125 entitydts[index].selectbyid(); 126 } 127 else//新增 128 { 129 entitydts[index].dmainid = htdataid; 130 entitydts[index].dseq = i + 1; 131 } 132 133 134 entitydts[index].dmainid = sysconvert.tostring(gridview1.getrowcellvalue(i, "dmainid")); 135 entitydts[index].dseq = sysconvert.toint32(gridview1.getrowcellvalue(i, "dseq")); 136 entitydts[index].datasourcename = sysconvert.tostring(gridview1.getrowcellvalue(i, "datasourcename")); 137 entitydts[index].sqlname = sysconvert.tostring(gridview1.getrowcellvalue(i, "sqlname")); 138 entitydts[index].sqlstr = sysconvert.tostring(gridview1.getrowcellvalue(i, "sqlstr")); 139 entitydts[index].queryname = sysconvert.tostring(gridview1.getrowcellvalue(i, "queryname")); 140 entitydts[index].sqlflag = sysconvert.toint32(gridview1.getrowcellvalue(i, "sqlflag")); 141 entitydts[index].sourcetype = sysconvert.toint32(gridview1.getrowcellvalue(i, "sourcetype")); 142 entitydts[index].remark = sysconvert.tostring(gridview1.getrowcellvalue(i, "remark")); 143 144 145 index++; 146 } 147 } 148 return entitydts; 149 } 150 151 #endregion 152 //添加一个基础模板 153 private void btnlook_click(object sender, eventargs e) 154 { 155 try 156 { 157 if (htformstatus == formstatus.新增 || htformstatus == formstatus.修改) 158 { 159 openfiledialog1.filename = ""; 160 openfiledialog1.filter = "(*.frx)|*.frx|(*.fr3)|*.fr3|(*.*)|*.*"; 161 openfiledialog1.showdialog(); 162 if (openfiledialog1.filename != string.empty) 163 { 164 txtfilepath.text = openfiledialog1.filename; 165 } 166 } 167 168 } 169 catch (exception e) 170 { 171 messagebox.show(e.message); 172 } 173 } 174 //窗体加载 175 private void hsprintedit_load(object sender, eventargs e) 176 { 177 //common.bindformid(drpform); 178 common.bindreportsource(drpreportsource, true); 179 } 180 //设计 181 private void btndesign_click(object sender, eventargs e) 182 { 183 try 184 { 185 if (htdataid == "") 186 { 187 messagebox.show("请先保存单据"); 188 return; 189 } 190 sreportmanage reportmanage = new sreportmanage(); 191 reportmanage.did = htdataid; 192 reportmanage.selectbyid(); 193 if (reportmanage.dfileid == "") 194 { 195 messagebox.show("没有找到打印格式"); 196 return; 197 } 198 199 200 201 if (!chksql.checked) 202 { 203 if (sysconvert.tostring(txtdataid.text.trim()) == "") 204 { 205 messagebox.show("请输入数据源id"); 206 return; 207 } 208 fastreport.reportrun(htdataid, (int)reportprinttype.设计, new string[] { "did", "dmainid" }, new string[] { sysconvert.tostring(txtdataid.text.trim()), sysconvert.tostring(txtdataid.text.trim()) }); 209 } 210 else 211 { 212 if (sysconvert.tostring(txtsql.text.trim()) == "") 213 { 214 messagebox.show("请输入数据源sql"); 215 return; 216 } 217 datatable dt = sysutils.fill(txtsql.text.trim()); 218 fastreport.reportruntable(htdataid, (int)reportprinttype.设计, dt); 219 } 220 221 222 223 } 224 catch (exception e) 225 { 226 messagebox.show(e.message); 227 } 228 } 229 //预览 230 private void btnpreview_click(object sender, eventargs e) 231 { 232 try 233 { 234 if (htdataid == "") 235 { 236 messagebox.show("请先保存单据"); 237 return; 238 } 239 sreportmanage reportmanage = new sreportmanage(); 240 reportmanage.did = htdataid; 241 reportmanage.selectbyid(); 242 if (reportmanage.dfileid == "") 243 { 244 messagebox.show("没有找到打印格式"); 245 return; 246 } 247 248 if (!chksql.checked) 249 { 250 if (sysconvert.tostring(txtdataid.text.trim()) == "") 251 { 252 messagebox.show("请输入数据源id"); 253 return; 254 } 255 fastreport.reportrun(htdataid, (int)reportprinttype.预览, new string[] { "did", "dmainid" }, new string[] { sysconvert.tostring(txtdataid.text.trim()), sysconvert.tostring(txtdataid.text.trim()) }); 256 } 257 else 258 { 259 if (sysconvert.tostring(txtsql.text.trim()) == "") 260 { 261 messagebox.show("请输入数据源"); 262 return; 263 } 264 datatable dt = sysutils.fill(txtsql.text.trim()); 265 fastreport.reportruntable(htdataid, (int)reportprinttype.预览, dt); 266 } 267 268 } 269 catch (exception e) 270 { 271 messagebox.show(e.message); 272 } 273 }
2.mvc端
为了将打印格式发布出去,这里特意做了一个mvc的程序,放在前端与后端之间,作为桥梁。
因为客户端只需要预览和打印,所以这里我只做了一个预览+打印的接口。设计在winform端处理,这里不需要。
以下是preview的代码实现。
1 public actionresult preview() 2 { 3 webreport = new webreport(); 4 webreport.width = unit.percentage(100); 5 webreport.height = unit.percentage(100); 6 7 string dataid = request.querystring["id"]; 8 9 string reportid = request.querystring["rid"]; 10 11 string token = request.querystring["token"]; 12 13 reportmodel model = new reportmodel(); 14 model.dataid = dataid; 15 model.reportid = reportid; 16 17 string token2 = "bearer " + token; 18 httpclient client = new httpclient(); 19 client.baseaddress = _baseaddress; 20 client.defaultrequestheaders.accept.add(new mediatypewithqualityheadervalue("application/json")); 21 22 client.defaultrequestheaders.add("authorization", "bearer " + token); 23 //获取模板文件地址,获取打印数据源webapi接口地址 24 #region 获取模板文件地址,获取打印数据源webapi接口地址 25 var jsonstr = jsonconvert.serializeobject(model); 26 httpcontent cont = new stringcontent(jsonstr); 27 cont.headers.contenttype = new mediatypeheadervalue("application/json"); 28 29 30 var returnstr = ""; 31 httpresponsemessage resp = client.postasync("/api/sreportmanage/getdataurl", cont).result;//post提交数据, 32 if (resp.issuccessstatuscode) 33 { 34 returnstr = resp.content.readasstringasync().result; 35 } 36 reportresult dtos = jsonconvert.deserializeobject<reportresult>(returnstr); 37 38 #endregion 39 40 //获取打印数据源 41 #region 获取打印数据源 42 43 44 httpclient client2 = new httpclient(); 45 client2.baseaddress = _baseaddress; 46 client2.defaultrequestheaders.accept.add(new mediatypewithqualityheadervalue("application/json")); 47 48 client2.defaultrequestheaders.add("authorization", "bearer " + token); 49 50 var jsonstr2 = jsonconvert.serializeobject(model); 51 httpcontent cont2 = new stringcontent(jsonstr2); 52 cont2.headers.contenttype = new mediatypeheadervalue("application/json"); 53 54 var returnstr2 = ""; 55 httpresponsemessage resp2 = client2.postasync(dtos.data.webapi, cont2).result;//post提交数据, 56 if (resp2.issuccessstatuscode) 57 { 58 returnstr2 = resp2.content.readasstringasync().result; 59 } 60 reportsourceresult result = jsonconvert.deserializeobject<reportsourceresult>(returnstr2); 61 if (result != null) 62 { 63 for (int i = 0; i < result.data.count; i++) 64 { 65 webreport.report.registerdata(result.data[i].dtsource, result.data[i].tbname); 66 webreport.report.getdatasource(result.data[i].tbname).enabled = true; 67 } 68 } 69 70 #endregion 71 72 73 74 75 //webreport.report.load(dtos.data.fileurl + "test.frx"); 76 webreport.report.load(configurationmanager.appsettings["reportfilepath"] + dtos.data.fileurl); 77 webreport.toolbarstyle = toolbarstyle.small; 78 webreport.toolbariconsstyle = toolbariconsstyle.blue; 79 webreport.toolbarbackgroundstyle = toolbarbackgroundstyle.custom; 80 81 //webreport.printpdf(); 82 83 webreport.previewmode = true;//预览模式 84 webreport.printinpdf = true;//在pdf打印 85 86 //webreport.designerpath = "~/webreportdesigner/index.html"; 87 //webreport.designersavepath = "~/app_data/designedreports"; 88 //webreport.designersavecallback = "~/report/savedesignedreport"; 89 webreport.id = "designreport"; 90 viewbag.webreport = webreport; 91 return view(); 92 }
其中以下几点是我做了特殊化的设置
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端进行拼接组装。
主要代码如下:
1 public list<reportdatasource> getdatasource(reportmodel entitydto) 2 { 3 try 4 { 5 list<reportdatasource> lst = new list<reportdatasource>(); 6 idbtransaccess sqltrans = transsysutils.getdbtransaccess(); 7 try 8 { 9 sqltrans.opentrans(); 10 11 lst = this.getdatasource(entitydto, sqltrans); 12 13 14 sqltrans.committrans(); 15 return lst; 16 } 17 catch (exception te) 18 { 19 sqltrans.rollbacktrans(); 20 throw te; 21 } 22 } 23 catch (baseexception) 24 { 25 throw; 26 } 27 catch (exception e) 28 { 29 throw new baseexception(e.message); 30 } 31 } 32 33 34 public list<reportdatasource> getdatasource(reportmodel entitydto, idbtransaccess sqltrans) 35 { 36 try 37 { 38 list<reportdatasource> lst = reportrun(entitydto.reportid, new string[] { "did","dmainid" }, new string[] { entitydto.dataid,entitydto.dataid }, sqltrans); 39 40 return lst; 41 42 } 43 catch (baseexception) 44 { 45 throw; 46 } 47 catch (exception e) 48 { 49 throw new baseexception(e.message); 50 } 51 } 52 53 54 55 56 57 58 59 60 61 #endregion 62 63 64 public list<reportdatasource> reportrun(string reportid, string[] queryname, string[] queryvalue, idbtransaccess sqltrans) 65 { 66 list<reportdatasource> lst = new list<reportdatasource>(); 67 string sql = "select * from data_sreportmanagedts where dmainid=" + sysstring.todbstring(reportid); 68 datatable dtsource = sqltrans.fill(sql); 69 if (dtsource.rows.count > 0) 70 { 71 foreach (datarow dr in dtsource.rows) 72 { 73 bool findsource = false; 74 string conditionstr = string.empty; 75 if (sysconvert.toint32(dr["sqlflag"]) == 0) 76 { 77 string[] tempa = dr["queryname"].tostring().split(' '); 78 for (int q = 0; q < queryname.length; q++) 79 { 80 for (int fi = 0; fi < tempa.length; fi++) 81 { 82 if (queryname[q].tostring().toupper() == tempa[fi].toupper()) 83 { 84 if (conditionstr != string.empty) 85 { 86 conditionstr += " and "; 87 } 88 conditionstr += queryname[q].tostring() + "=" + sysstring.todbstring(queryvalue[q]); 89 findsource = true; 90 break; 91 } 92 } 93 94 } 95 } 96 else 97 { 98 conditionstr = sysconvert.tostring(dr["queryname"]).toupper(); 99 for (int i = 0; i < queryname.length; i++) 100 { 101 string querystr = "{" + queryname[i].toupper() + "}"; 102 103 conditionstr = conditionstr.replace(querystr, sysstring.todbstring(queryvalue[i])); 104 } 105 if (conditionstr.contains("{") || conditionstr.contains("}")) 106 { 107 findsource = false; 108 } 109 else 110 { 111 findsource = true; 112 } 113 } 114 if (findsource) 115 { 116 117 if (sysconvert.toint32(dr["sqlflag"]) == 0) 118 { 119 120 sql = "select * from (" + dr["sqlstr"].tostring() + ") a where " + conditionstr; 121 } 122 else 123 { 124 125 sql = dr["sqlstr"].tostring() + " " + conditionstr; 126 } 127 datatable dt = sqltrans.fill(sql); 128 129 reportdatasource source = new reportdatasource(); 130 source.dtsource = dt; 131 source.tbname = dr["sqlname"].tostring(); 132 lst.add(source); 133 134 135 } 136 else 137 { 138 if (dr["sqlstr"].tostring() != string.empty) 139 { 140 sql = dr["sqlstr"].tostring(); 141 datatable dt = sqltrans.fill(sql); 142 143 reportdatasource source = new reportdatasource(); 144 source.dtsource = dt; 145 source.tbname = dr["sqlname"].tostring(); 146 lst.add(source); 147 148 } 149 } 150 } 151 } 152 153 return lst; 154 }
fastreport 交流群
554714044
上一篇: (一)C++游戏开发-本地存储-介绍
下一篇: 聊聊DataTable下载