WebReportHtml.Backend.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. using FastReport.Preview;
  2. using FastReport.Table;
  3. using System;
  4. using System.IO;
  5. using System.Net;
  6. using System.Text;
  7. using System.Collections.Generic;
  8. using Microsoft.Extensions.Primitives;
  9. using System.Linq;
  10. using System.Globalization;
  11. using FastReport.Web.Services;
  12. using FastReport.Export.Html;
  13. using FastReport.Web.Infrastructure;
  14. namespace FastReport.Web
  15. {
  16. public partial class WebReport
  17. {
  18. internal StringBuilder ReportBody()
  19. {
  20. #if DIALOGS
  21. if (Mode == WebReportMode.Dialog)
  22. {
  23. StringBuilder sb = new StringBuilder();
  24. Dialog.ProcessDialogs(sb);
  25. return sb;
  26. }
  27. else
  28. #endif
  29. return ReportInHtml();
  30. }
  31. internal StringBuilder ReportInHtml()
  32. {
  33. PictureCache.Clear();
  34. var sb = new StringBuilder();
  35. using (HTMLExport html = new HTMLExport())
  36. {
  37. html.ExportMode = HTMLExport.ExportType.WebPreview;
  38. //html.CustomDraw += this.CustomDraw;
  39. html.StylePrefix = $"fr{ID}"; //html.StylePrefix = Prop.ControlID.Substring(0, 6);
  40. html.Init_WebMode();
  41. html.Pictures = Pictures; //html.Pictures = Prop.Pictures;
  42. html.EmbedPictures = EmbedPictures; //html.EmbedPictures = EmbedPictures;
  43. html.OnClickTemplate = "fr{0}.click(this,'{1}','{2}')";
  44. html.ReportID = ID; //html.ReportID = Prop.ControlID;
  45. html.EnableMargins = EnableMargins; //html.EnableMargins = Prop.EnableMargins;
  46. // calc zoom
  47. //CalcHtmlZoom(html);
  48. html.Zoom = Zoom;
  49. html.Layers = Layers; //html.Layers = Layers;
  50. html.PageNumbers = SinglePage ? "" : (CurrentPageIndex + 1).ToString(); //html.PageNumbers = SinglePage ? "" : (Prop.CurrentPage + 1).ToString();
  51. //if (Prop.AutoWidth)
  52. // html.WidthUnits = HtmlSizeUnits.Percent;
  53. //if (Prop.AutoHeight)
  54. // html.HeightUnits = HtmlSizeUnits.Percent;
  55. //html.WebImagePrefix = WebUtils.ToUrl(FastReportGlobal.FastReportOptions.RouteBasePath, controller.RouteBasePath, ID, "picture") + "/"; //html.WebImagePrefix = String.Concat(context.Response.ApplyAppPathModifier(WebUtils.HandlerFileName), "?", WebUtils.PicsPrefix);
  56. html.WebImagePrefix = WebUtils.ToUrl(FastReportGlobal.FastReportOptions.RoutePathBaseRoot, FastReportGlobal.FastReportOptions.RouteBasePath, $"preview.getPicture?reportId={ID}&pictureId=");
  57. html.SinglePage = SinglePage; //html.SinglePage = SinglePage;
  58. html.CurPage = CurrentPageIndex; //html.CurPage = CurrentPage;
  59. html.Export(Report, (Stream)null);
  60. //sb.Append("<div class=\"frbody\" style =\"");
  61. //if (HtmlLayers)
  62. // sb.Append("position:relative;z-index:0;");
  63. //sb.Append("\">");
  64. // container for html report body
  65. //int pageWidth = (int)Math.Ceiling(GetReportPageWidthInPixels() * html.Zoom);
  66. //int pageHeight = (int)Math.Ceiling(GetReportPageHeightInPixels() * html.Zoom);
  67. //int paddingLeft = (int)Math.Ceiling(Padding.Left * html.Zoom);
  68. //int paddingRight = (int)Math.Ceiling(Padding.Right * html.Zoom);
  69. //int paddingTop = (int)Math.Ceiling(Padding.Top * html.Zoom);
  70. //int paddingBottom = (int)Math.Ceiling(Padding.Bottom * html.Zoom);
  71. //sb.Append("<div class=\"frcontainer\" style=\"width:" + pageWidth +
  72. // "px;height:" + (SinglePage ? pageHeight * html.Count : pageHeight) +
  73. // "px;padding-left:" + paddingLeft +
  74. // "px;padding-right:" + paddingRight +
  75. // "px;padding-top:" + paddingTop +
  76. // "px;padding-bottom:" + paddingBottom + "px\">");
  77. if (html.Count > 0)
  78. {
  79. if (SinglePage)
  80. {
  81. DoAllHtmlPages(sb, html);
  82. CurrentPageIndex = 0; //Prop.CurrentPage = 0;
  83. }
  84. else
  85. {
  86. DoHtmlPage(sb, html, 0);
  87. }
  88. }
  89. //sb.Append("</div>");
  90. //sb.Append("</div>");
  91. // important container, it cuts off elements that are outside of the report page bounds
  92. int pageWidth = (int)Math.Ceiling(GetReportPageWidthInPixels() * html.Zoom);
  93. int pageHeight = (int)Math.Ceiling(GetReportPageHeightInPixels() * html.Zoom);
  94. ReportMaxWidth = pageWidth;
  95. sb.Insert(0, $@"<div style=""width:{pageWidth}px;height:{pageHeight}px;overflow:hidden;display:inline-block;"">");
  96. sb.Append("</div>");
  97. }
  98. return sb;
  99. }
  100. #if DIALOGS
  101. internal void Dialogs(DialogParams @params)
  102. {
  103. string dialogN = @params.DialogN;
  104. string controlName = @params.DialogControlName;
  105. string eventName = @params.DialogEventName;
  106. string data = @params.DialogData;
  107. Dialog.SetDialogs(dialogN, controlName, eventName, data);
  108. }
  109. #endif
  110. internal void ProcessClick(ClickParams clickParams)
  111. {
  112. var click = clickParams.Click;
  113. if (!click.IsNullOrWhiteSpace())
  114. {
  115. var @params = click.Split(',');
  116. if (@params.Length == 4)
  117. {
  118. if (int.TryParse(@params[1], out var pageN) &&
  119. float.TryParse(@params[2], out var left) &&
  120. float.TryParse(@params[3], out var top))
  121. {
  122. DoClickObjectByParamID(@params[0], pageN, left, top);
  123. }
  124. }
  125. return;
  126. }
  127. var checkbox_click = clickParams.CheckBoxClick;
  128. if (!checkbox_click.IsNullOrWhiteSpace())
  129. {
  130. var @params = checkbox_click.Split(',');
  131. if (@params.Length == 4)
  132. {
  133. if (int.TryParse(@params[1], out var pageN) &&
  134. float.TryParse(@params[2], out var left) &&
  135. float.TryParse(@params[3], out var top))
  136. {
  137. Report.FindClickedObject<CheckBoxObject>(@params[0], pageN, left, top, CheckboxClick);
  138. }
  139. }
  140. return;
  141. }
  142. var text_edit = clickParams.TextEdit;
  143. if (!text_edit.IsNullOrWhiteSpace())
  144. {
  145. var text = clickParams.Text;
  146. var @params = text_edit.Split(',');
  147. if (@params.Length == 4 && text != null)
  148. {
  149. if (int.TryParse(@params[1], out var pageN) &&
  150. float.TryParse(@params[2], out var left) &&
  151. float.TryParse(@params[3], out var top))
  152. {
  153. Report.FindClickedObject<TextObject>(@params[0], pageN, left, top,
  154. (obj, reportPage, _pageN) =>
  155. {
  156. obj.Text = text;
  157. Refresh(_pageN, reportPage);
  158. });
  159. }
  160. }
  161. return;
  162. }
  163. var advmatrix_button = clickParams.AdvMatrixClick;
  164. if (!advmatrix_button.IsNullOrWhiteSpace())
  165. {
  166. var @params = advmatrix_button.Split(',');
  167. if (@params.Length == 3)
  168. {
  169. if (
  170. int.TryParse(@params[1], out var pageN) &&
  171. int.TryParse(@params[2], out var index))
  172. {
  173. DoClickAdvancedMatrixByParamID(@params[0], pageN, index);
  174. }
  175. }
  176. }
  177. }
  178. internal void SetReportZoom(string zoom)
  179. {
  180. if (int.TryParse(zoom, out int result))
  181. if (result / 100f > 0f)
  182. Zoom = result / 100f;
  183. }
  184. internal void SetReportPage(ReportPageParams @params)
  185. {
  186. string @goto = @params.GoTo;
  187. if (!@goto.IsNullOrWhiteSpace())
  188. {
  189. GoToPageNumber(@goto);
  190. return;
  191. }
  192. string bookmark = @params.Bookmark;
  193. if (!bookmark.IsNullOrWhiteSpace())
  194. {
  195. int i = PageNByBookmark(WebUtility.UrlDecode(bookmark));
  196. if (i != -1)
  197. GotoPage(i);
  198. return;
  199. }
  200. string detailed_report = @params.DetailedReport;
  201. if (!detailed_report.IsNullOrWhiteSpace())
  202. {
  203. string[] detailParams = WebUtility.UrlDecode(detailed_report).Split(',');
  204. if (detailParams.Length == 3)
  205. {
  206. if (!String.IsNullOrEmpty(detailParams[0]) &&
  207. !String.IsNullOrEmpty(detailParams[1]) &&
  208. !String.IsNullOrEmpty(detailParams[2])
  209. )
  210. {
  211. DoDetailedReport(detailParams[0], detailParams[1], detailParams[2]);
  212. }
  213. }
  214. return;
  215. }
  216. string detailed_page = @params.DetailedPage;
  217. if (!detailed_page.IsNullOrWhiteSpace())
  218. {
  219. string[] detailParams = WebUtility.UrlDecode(detailed_page).Split(',');
  220. if (detailParams.Length == 3)
  221. {
  222. if (!String.IsNullOrEmpty(detailParams[0]) &&
  223. !String.IsNullOrEmpty(detailParams[1]) &&
  224. !String.IsNullOrEmpty(detailParams[2])
  225. )
  226. {
  227. DoDetailedPage(detailParams[0], detailParams[1], detailParams[2]);
  228. }
  229. }
  230. return;
  231. }
  232. }
  233. internal void SetReportTab(ReportTabParams @params)
  234. {
  235. string settab = @params.SetTab;
  236. if (!settab.IsNullOrWhiteSpace())
  237. {
  238. if (int.TryParse(settab, out int i))
  239. {
  240. //if (i >= 0 && i < Tabs.Count)
  241. SetTab(i);
  242. }
  243. }
  244. string closetab = @params.CloseTab;
  245. if (!closetab.IsNullOrWhiteSpace())
  246. {
  247. int i = 0;
  248. if (int.TryParse(closetab, out i) && (i >= 0 && i < Tabs.Count))
  249. {
  250. var activeTab = CurrentTab;
  251. Tabs[i].Report.Dispose();
  252. Tabs.RemoveAt(i);
  253. if (activeTab == null)
  254. {
  255. CurrentTabIndex = 0;
  256. }
  257. else
  258. {
  259. for (int j = 0; j < Tabs.Count; j++)
  260. if (Tabs[j] == activeTab)
  261. {
  262. CurrentTabIndex = j;
  263. break;
  264. }
  265. }
  266. //if (i < Tabs.Count)
  267. // CurrentTabIndex = i;
  268. //else
  269. // CurrentTabIndex = i - 1;
  270. }
  271. }
  272. }
  273. #region Private Methods
  274. private void DoClickObjectByParamID(string objectName, int pageN, float left, float top)
  275. {
  276. if (Report.PreparedPages != null)
  277. {
  278. bool found = false;
  279. while (pageN < Report.PreparedPages.Count && !found)
  280. {
  281. ReportPage page = Report.PreparedPages.GetPage(pageN);
  282. if (page != null)
  283. {
  284. ObjectCollection allObjects = page.AllObjects;
  285. System.Drawing.PointF point = new System.Drawing.PointF(left + 1, top + 1);
  286. foreach (Base obj in allObjects)
  287. {
  288. if (obj is ReportComponentBase)
  289. {
  290. ReportComponentBase c = obj as ReportComponentBase;
  291. if (c is TableBase)
  292. {
  293. TableBase table = c as TableBase;
  294. for (int i = 0; i < table.RowCount; i++)
  295. {
  296. for (int j = 0; j < table.ColumnCount; j++)
  297. {
  298. TableCell textcell = table[j, i];
  299. if (textcell.Name == objectName)
  300. {
  301. System.Drawing.RectangleF rect =
  302. new System.Drawing.RectangleF(table.Columns[j].AbsLeft,
  303. table.Rows[i].AbsTop,
  304. textcell.Width,
  305. textcell.Height);
  306. if (rect.Contains(point))
  307. {
  308. Click(textcell, page, pageN);
  309. found = true;
  310. break;
  311. }
  312. }
  313. }
  314. if (found)
  315. break;
  316. }
  317. }
  318. else
  319. if (c.Name == objectName &&
  320. //#if FRCORE
  321. c.AbsBounds.Contains(point))
  322. //#else
  323. // c.PointInObject(point))
  324. //#endif
  325. {
  326. Click(c, page, pageN);
  327. found = true;
  328. break;
  329. }
  330. }
  331. }
  332. page.Dispose();
  333. pageN++;
  334. }
  335. }
  336. }
  337. }
  338. private void DoDetailedReport(string objectName, string paramName, string paramValue)
  339. {
  340. if (!String.IsNullOrEmpty(objectName))
  341. {
  342. ReportComponentBase obj = Report.FindObject(objectName) as ReportComponentBase;
  343. DoDetailedReport(obj, paramValue);
  344. }
  345. }
  346. private void DoDetailedPage(string objectName, string paramName, string paramValue)
  347. {
  348. if (!String.IsNullOrEmpty(objectName))
  349. {
  350. Report currentReport = CurrentTab.NeedParent ? Tabs[0].Report : Report;
  351. ReportComponentBase obj = currentReport.FindObject(objectName) as ReportComponentBase;
  352. if (obj != null && obj.Hyperlink.Kind == HyperlinkKind.DetailPage)
  353. {
  354. ReportPage reportPage = currentReport.FindObject(obj.Hyperlink.DetailPageName) as ReportPage;
  355. if (reportPage != null)
  356. {
  357. Data.Parameter param = currentReport.Parameters.FindByName(paramName);
  358. if (param != null && param.ChildObjects.Count > 0)
  359. {
  360. string[] paramValues = paramValue.Split(obj.Hyperlink.ValuesSeparator[0]);
  361. if (paramValues.Length > 0)
  362. {
  363. int i = 0;
  364. foreach (Data.Parameter childParam in param.ChildObjects)
  365. {
  366. childParam.Value = paramValues[i++];
  367. if (i >= paramValues.Length)
  368. break;
  369. }
  370. }
  371. }
  372. else
  373. currentReport.SetParameterValue(paramName, paramValue);
  374. PreparedPages oldPreparedPages = currentReport.PreparedPages;
  375. PreparedPages pages = new PreparedPages(currentReport);
  376. currentReport.SetPreparedPages(pages);
  377. currentReport.PreparePage(reportPage, true);
  378. Report tabReport = new Report();
  379. tabReport.SetPreparedPages(currentReport.PreparedPages);
  380. Tabs.Add(new ReportTab()
  381. {
  382. Name = paramValue,
  383. Report = tabReport,
  384. Closeable = true,
  385. NeedParent = true
  386. });
  387. int prevTab = CurrentTabIndex;
  388. currentReport.SetPreparedPages(oldPreparedPages);
  389. CurrentTabIndex = Tabs.Count - 1;
  390. //Prop.PreviousTab = prevTab;
  391. }
  392. }
  393. }
  394. }
  395. #endregion
  396. }
  397. }