BlazorExport.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Drawing;
  7. using System.Drawing.Imaging;
  8. using System.Globalization;
  9. using Microsoft.AspNetCore.Components;
  10. using Microsoft.AspNetCore.Components.Rendering;
  11. using FastReport.Export;
  12. using FastReport.Utils;
  13. using FastReport.Export.Html;
  14. using System.Threading.Tasks;
  15. using ImageFormat = System.Drawing.Imaging.ImageFormat;
  16. using System.Threading;
  17. namespace FastReport.Web.Blazor.Export
  18. {
  19. public partial class BlazorExport : ExportBase
  20. {
  21. #region Private fields
  22. private readonly struct HTMLData
  23. {
  24. public readonly int PageNumber;
  25. public readonly int CurrentPage;
  26. public readonly ReportPage page;
  27. public HTMLData(int pageNumber, int curPage, ReportPage page)
  28. {
  29. PageNumber = pageNumber;
  30. CurrentPage = curPage;
  31. this.page = page;
  32. }
  33. }
  34. private int pagesCount;
  35. private ImageFormat imageFormat;
  36. private bool singlePage;
  37. private bool pictures;
  38. private bool embedPictures;
  39. private string? stylePrefix;
  40. private int prevStyleListIndex;
  41. private bool pageBreaks;
  42. private List<StringBuilder> cssStyles;
  43. private string pageStyleName;
  44. private const string NBSP = "&nbsp;";
  45. private int currentPage = 0;
  46. private HTMLData d;
  47. private IGraphics htmlMeasureGraphics;
  48. private float maxWidth, maxHeight;
  49. private float leftMargin, topMargin;
  50. private bool enableMargins = false;
  51. #endregion Private fields
  52. #region Public properties
  53. private RenderContext globalContext;
  54. private CancellationToken cancellationToken;
  55. /// <summary>
  56. /// Sets an onclick event handler
  57. /// </summary>
  58. public EventHandler<OnClickEventArgs> OnClick;
  59. /// <summary>
  60. /// Gets or sets images, embedded in html (hash:base64Image)
  61. /// </summary>
  62. public Dictionary<string, string> EmbeddedImages
  63. {
  64. get;
  65. set;
  66. }
  67. /// <summary>
  68. /// For internal use only.
  69. /// </summary>
  70. public string? StylePrefix
  71. {
  72. get { return stylePrefix; }
  73. set { stylePrefix = value; }
  74. }
  75. /// <summary>
  76. /// For internal use only.
  77. /// </summary>
  78. public string? WebImagePrefix
  79. {
  80. get;
  81. set;
  82. }
  83. /// <summary>
  84. /// For internal use only.
  85. /// </summary>
  86. public List<BlazorPageData> PreparedPages { get; }
  87. /// <summary>
  88. /// Enable or disable the breaks between pages in print preview when single page mode is enabled
  89. /// </summary>
  90. public bool PageBreaks
  91. {
  92. get { return pageBreaks; }
  93. set { pageBreaks = value; }
  94. }
  95. /// <summary>
  96. /// Enable or disable the pictures in HTML export
  97. /// </summary>
  98. public bool Pictures
  99. {
  100. get { return pictures; }
  101. set { pictures = value; }
  102. }
  103. /// <summary>
  104. /// Enable or disable embedding pictures in HTML export
  105. /// </summary>
  106. public bool EmbedPictures
  107. {
  108. get { return embedPictures; }
  109. set { embedPictures = value; }
  110. }
  111. /// <summary>
  112. /// Enable or disable the single HTML page creation
  113. /// </summary>
  114. public bool SinglePage
  115. {
  116. get { return singlePage; }
  117. set { singlePage = value; }
  118. }
  119. /// <summary>
  120. /// Gets or sets the image format.
  121. /// </summary>
  122. public ImageFormat ImageFormat
  123. {
  124. get { return imageFormat; }
  125. set { imageFormat = value; }
  126. }
  127. /// <summary>
  128. /// Enable or disable margins for pages.
  129. /// </summary>
  130. public bool EnableMargins
  131. {
  132. get { return enableMargins; }
  133. set { enableMargins = value; }
  134. }
  135. #endregion Public properties
  136. #region Private methods
  137. private void ExportHTMLPageStart(int PageNumber, int CurrentPage)
  138. {
  139. PreparedPages[CurrentPage].PageNumber = PageNumber;
  140. }
  141. private void ExportHTMLPageFinal(in HTMLData d, float MaxWidth, float MaxHeight)
  142. {
  143. // CalcPageSize
  144. var page = PreparedPages[d.CurrentPage];
  145. page.Width = MaxWidth;
  146. page.Height = MaxHeight;
  147. }
  148. private void Init()
  149. {
  150. htmlMeasureGraphics = Report.MeasureGraphics;
  151. cssStyles = new List<StringBuilder>();
  152. pagesCount = 0;
  153. prevStyleListIndex = 0;
  154. //GeneratedStreams = new List<Stream>();
  155. }
  156. private void StartWeb()
  157. {
  158. PreparedPages.Clear();
  159. for (int i = 0; i < Report.PreparedPages.Count; i++)
  160. PreparedPages.Add(new BlazorPageData());
  161. }
  162. #endregion Private methods
  163. #region Protected methods
  164. /// <inheritdoc/>
  165. protected override void Start()
  166. {
  167. base.Start();
  168. Init();
  169. StartWeb();
  170. }
  171. /// <inheritdoc/>
  172. protected override void ExportPageBegin(ReportPage page)
  173. {
  174. pagesCount++;
  175. // Web
  176. ProcessPageBegin(CurPage, page);
  177. }
  178. /// <inheritdoc/>
  179. protected override void ExportPageEnd(ReportPage page)
  180. {
  181. // Web
  182. ProcessPageEnd();
  183. }
  184. public void Export(Report report, RenderTreeBuilder builder)
  185. {
  186. Export(report, builder, default);
  187. }
  188. public void Export(Report report, RenderTreeBuilder builder, CancellationToken cancellationToken = default)
  189. {
  190. var context = new RenderContext(builder, OnClick);
  191. globalContext = context;
  192. this.cancellationToken = cancellationToken;
  193. Export(report, (Stream)null);
  194. }
  195. /// <summary>
  196. /// Process Page with number p and real page ReportPage
  197. /// </summary>
  198. /// <param name="p"></param>
  199. /// <param name="page"></param>
  200. public void ProcessPageBegin(int p, ReportPage page)
  201. {
  202. d = new HTMLData(pagesCount, p, page);
  203. ExportHTMLPageLayeredBegin(d);
  204. }
  205. /// <summary>
  206. /// Process Page with number p and real page ReportPage
  207. /// </summary>
  208. /// <param name="p"></param>
  209. /// <param name="ReportPage"></param>
  210. public void ProcessPageEnd()
  211. {
  212. ExportHTMLPageLayeredEnd(d);
  213. }
  214. #endregion Protected methods
  215. /// <summary>
  216. /// Initializes a new instance of the <see cref="BlazorExport"/> class.
  217. /// </summary>
  218. public BlazorExport()
  219. {
  220. Zoom = 1.0f;
  221. //HasMultipleFiles = true;
  222. pictures = true;
  223. singlePage = false;
  224. imageFormat = ImageFormat.Png;
  225. prevStyleListIndex = 0;
  226. pageBreaks = true;
  227. EmbeddedImages = new Dictionary<string, string>();
  228. // Init_WebMode
  229. ShowProgress = false;
  230. PreparedPages = new List<BlazorPageData>();
  231. OpenAfterExport = false;
  232. }
  233. }
  234. }