HTMLExportDraw.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. using System;
  2. using System.Drawing;
  3. using System.IO;
  4. using FastReport.Utils;
  5. using System.Windows.Forms;
  6. namespace FastReport.Export.Html
  7. {
  8. public partial class HTMLExport : ExportBase
  9. {
  10. private void HTMLFontStyle(FastString FFontDesc, Font font, float LineHeight)
  11. {
  12. FFontDesc.Append((((font.Style & FontStyle.Bold) > 0) ? "font-weight:bold;" : String.Empty) +
  13. (((font.Style & FontStyle.Italic) > 0) ? "font-style:italic;" : "font-style:normal;"));
  14. if ((font.Style & FontStyle.Underline) > 0 && (font.Style & FontStyle.Strikeout) > 0)
  15. FFontDesc.Append("text-decoration:underline|line-through;");
  16. else if ((font.Style & FontStyle.Underline) > 0)
  17. FFontDesc.Append("text-decoration:underline;");
  18. else if ((font.Style & FontStyle.Strikeout) > 0)
  19. FFontDesc.Append("text-decoration:line-through;");
  20. FFontDesc.Append("font-family:").Append(font.Name).Append(";");
  21. FFontDesc.Append("font-size:").Append(Px(font.Size * 96 / 72));
  22. if (LineHeight > 0)
  23. FFontDesc.Append("line-height:").Append(Px(LineHeight)).Append(";");
  24. }
  25. private void HTMLPadding(FastString PaddingDesc, Padding padding, float ParagraphOffset)
  26. {
  27. PaddingDesc.Append("text-indent:").Append(Px(ParagraphOffset));
  28. PaddingDesc.Append("padding-left:").Append(Px(padding.Left));
  29. PaddingDesc.Append("padding-right:").Append(Px(padding.Right));
  30. PaddingDesc.Append("padding-top:").Append(Px(padding.Top));
  31. PaddingDesc.Append("padding-bottom:").Append(Px(padding.Bottom));
  32. }
  33. private string HTMLBorderStyle(BorderLine line)
  34. {
  35. switch (line.Style)
  36. {
  37. case LineStyle.Dash:
  38. case LineStyle.DashDot:
  39. case LineStyle.DashDotDot:
  40. return "dashed";
  41. case LineStyle.Dot:
  42. return "dotted";
  43. case LineStyle.Double:
  44. return "double";
  45. default:
  46. return "solid";
  47. }
  48. }
  49. private float HTMLBorderWidth(BorderLine line)
  50. {
  51. if (line.Style == LineStyle.Double)
  52. return (line.Width * 3 * Zoom);
  53. else
  54. return line.Width * Zoom;
  55. }
  56. private string HTMLBorderWidthPx(BorderLine line)
  57. {
  58. if (line.Style != LineStyle.Double && line.Width == 1 && Zoom == 1)
  59. return "1px;";
  60. float width;
  61. if (line.Style == LineStyle.Double)
  62. width = line.Width * 3 * Zoom;
  63. else if (layers)
  64. width = line.Width * Zoom;
  65. else
  66. width = line.Width;
  67. return ExportUtils.FloatToString(width) + "px;";
  68. }
  69. private void HTMLBorder(FastString BorderDesc, Border border)
  70. {
  71. if (!layers)
  72. BorderDesc.Append("border-collapse: separate;");
  73. if (border.Lines > 0)
  74. {
  75. // bottom
  76. if ((border.Lines & BorderLines.Bottom) > 0)
  77. BorderDesc.Append("border-bottom-width:").
  78. Append(HTMLBorderWidthPx(border.BottomLine)).
  79. Append("border-bottom-color:").
  80. Append(ExportUtils.HTMLColor(border.BottomLine.Color)).Append(";border-bottom-style:").
  81. Append(HTMLBorderStyle(border.BottomLine)).Append(";");
  82. else
  83. BorderDesc.Append("border-bottom:none;");
  84. // top
  85. if ((border.Lines & BorderLines.Top) > 0)
  86. BorderDesc.Append("border-top-width:").
  87. Append(HTMLBorderWidthPx(border.TopLine)).
  88. Append("border-top-color:").
  89. Append(ExportUtils.HTMLColor(border.TopLine.Color)).Append(";border-top-style:").
  90. Append(HTMLBorderStyle(border.TopLine)).Append(";");
  91. else
  92. BorderDesc.Append("border-top:none;");
  93. // left
  94. if ((border.Lines & BorderLines.Left) > 0)
  95. BorderDesc.Append("border-left-width:").
  96. Append(HTMLBorderWidthPx(border.LeftLine)).
  97. Append("border-left-color:").
  98. Append(ExportUtils.HTMLColor(border.LeftLine.Color)).Append(";border-left-style:").
  99. Append(HTMLBorderStyle(border.LeftLine)).Append(";");
  100. else
  101. BorderDesc.Append("border-left:none;");
  102. // right
  103. if ((border.Lines & BorderLines.Right) > 0)
  104. BorderDesc.Append("border-right-width:").
  105. Append(HTMLBorderWidthPx(border.RightLine)).
  106. Append("border-right-color:").
  107. Append(ExportUtils.HTMLColor(border.RightLine.Color)).Append(";border-right-style:").
  108. Append(HTMLBorderStyle(border.RightLine)).Append(";");
  109. else
  110. BorderDesc.Append("border-right:none;");
  111. }
  112. else
  113. BorderDesc.Append("border:none;");
  114. }
  115. private bool HTMLBorderWidthValues(ReportComponentBase obj, out float left, out float top, out float right, out float bottom)
  116. {
  117. Border border = obj.Border;
  118. left = 0;
  119. top = 0;
  120. right = 0;
  121. bottom = 0;
  122. if (border.Lines > 0)
  123. {
  124. if ((border.Lines & BorderLines.Left) > 0)
  125. left += HTMLBorderWidth(border.LeftLine);
  126. if ((border.Lines & BorderLines.Right) > 0)
  127. right += HTMLBorderWidth(border.RightLine);
  128. if ((border.Lines & BorderLines.Top) > 0)
  129. top += HTMLBorderWidth(border.TopLine);
  130. if ((border.Lines & BorderLines.Bottom) > 0)
  131. bottom += HTMLBorderWidth(border.BottomLine);
  132. return true;
  133. }
  134. return false;
  135. }
  136. private void HTMLAlign(FastString sb, HorzAlign horzAlign, VertAlign vertAlign, bool wordWrap)
  137. {
  138. sb.Append("text-align:");
  139. if (horzAlign == HorzAlign.Left)
  140. sb.Append("Left");
  141. else if (horzAlign == HorzAlign.Right)
  142. sb.Append("Right");
  143. else if (horzAlign == HorzAlign.Center)
  144. sb.Append("Center");
  145. else if (horzAlign == HorzAlign.Justify)
  146. sb.Append("Justify");
  147. sb.Append(";vertical-align:");
  148. if (vertAlign == VertAlign.Top)
  149. sb.Append("Top");
  150. else if (vertAlign == VertAlign.Bottom)
  151. sb.Append("Bottom");
  152. else if (vertAlign == VertAlign.Center)
  153. sb.Append("Middle");
  154. if (wordWrap)
  155. sb.Append(";word-wrap:break-word");
  156. sb.Append(";overflow:hidden;");
  157. }
  158. private void HTMLRtl(FastString sb, bool rtl)
  159. {
  160. if (rtl)
  161. sb.Append("direction:rtl;");
  162. }
  163. private string HTMLGetStylesHeader()
  164. {
  165. return "<style type=\"text/css\"><!-- ";
  166. }
  167. private void PrintPageStyle(FastString sb)
  168. {
  169. if (singlePage && pageBreaks)
  170. {
  171. sb.AppendLine("<style type=\"text/css\" media=\"print\"><!--");
  172. sb.Append("div.").Append(pageStyleName)
  173. .Append(" { break-after: always; page-break-inside: avoid; ");
  174. if (d.page.Landscape && !NotRotateLandscapePage)
  175. {
  176. sb.Append("width:").Append(Px(maxHeight * Zoom).Replace(";", " !important;"))
  177. .Append("transform: rotate(90deg); -webkit-transform: rotate(90deg)");
  178. }
  179. sb.AppendLine("}")
  180. .AppendLine("--></style>");
  181. }
  182. }
  183. private string HTMLGetStyleHeader(long index, long subindex)
  184. {
  185. FastString header = new FastString();
  186. return header.Append(".").
  187. Append(stylePrefix).
  188. Append("s").
  189. Append(index.ToString()).
  190. Append((singlePage || layers) ? String.Empty : String.Concat("-", subindex.ToString())).
  191. Append(" { ").ToString();
  192. }
  193. private void HTMLGetStyle(FastString style, Font Font, Color TextColor, Color FillColor, HorzAlign HAlign, VertAlign VAlign,
  194. Border Border, Padding Padding, bool RTL, bool wordWrap, float LineHeight, float ParagraphOffset)
  195. {
  196. HTMLFontStyle(style, Font, LineHeight);
  197. style.Append("color:").Append(ExportUtils.HTMLColor(TextColor)).Append(";");
  198. style.Append("background-color:");
  199. style.Append(FillColor.A == 0 ? "transparent" : ExportUtils.HTMLColor(FillColor)).Append(";");
  200. HTMLAlign(style, HAlign, VAlign, wordWrap);
  201. HTMLBorder(style, Border);
  202. HTMLPadding(style, Padding, ParagraphOffset);
  203. HTMLRtl(style, RTL);
  204. style.AppendLine("}");
  205. }
  206. private string HTMLGetStylesFooter()
  207. {
  208. return "--></style>";
  209. }
  210. private string HTMLGetAncor(string ancorName)
  211. {
  212. FastString ancor = new FastString();
  213. return ancor.Append("<a name=\"PageN").Append(ancorName).Append("\" style=\"padding:0;margin:0;font-size:1px;\"></a>").ToString();
  214. }
  215. private string HTMLGetImageTag(string file)
  216. {
  217. return "<img src=\"" + file + "\" alt=\"\"/>";
  218. }
  219. private string HTMLGetImage(int PageNumber, int CurrentPage, int ImageNumber, string hash, bool Base,
  220. System.Drawing.Image Metafile, MemoryStream PictureStream, bool isSvg)
  221. {
  222. if (pictures)
  223. {
  224. System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Bmp;
  225. if (imageFormat == ImageFormat.Png)
  226. format = System.Drawing.Imaging.ImageFormat.Png;
  227. else if (imageFormat == ImageFormat.Jpeg)
  228. format = System.Drawing.Imaging.ImageFormat.Jpeg;
  229. else if (imageFormat == ImageFormat.Gif)
  230. format = System.Drawing.Imaging.ImageFormat.Gif;
  231. string formatNm = isSvg ? "svg" : format.ToString().ToLower();
  232. string embedImgType = isSvg ? "svg+xml" : format.ToString();
  233. string embedPreffix = "data:image/" + embedImgType + ";base64,";
  234. FastString ImageFileNameBuilder = new FastString(48);
  235. string ImageFileName;
  236. if (!saveStreams)
  237. ImageFileNameBuilder.Append(Path.GetFileName(targetFileName)).Append(".");
  238. ImageFileNameBuilder.Append(hash).
  239. Append(".").Append(formatNm);
  240. ImageFileName = ImageFileNameBuilder.ToString();
  241. if (!webMode && !(preview || print))
  242. {
  243. if (Base)
  244. {
  245. if (Metafile != null && !EmbedPictures)
  246. {
  247. if (saveStreams)
  248. {
  249. MemoryStream ImageFileStream = new MemoryStream();
  250. Metafile.Save(ImageFileStream, format);
  251. GeneratedUpdate(targetPath + ImageFileName, ImageFileStream);
  252. }
  253. else
  254. {
  255. using (FileStream ImageFileStream =
  256. new FileStream(targetPath + ImageFileName, FileMode.Create))
  257. Metafile.Save(ImageFileStream, format);
  258. }
  259. }
  260. else if (PictureStream != null && !EmbedPictures)
  261. {
  262. if (this.format == HTMLExportFormat.HTML)
  263. {
  264. string fileName = targetPath + ImageFileName;
  265. FileInfo info = new FileInfo(fileName);
  266. if (!(info.Exists && info.Length == PictureStream.Length))
  267. {
  268. if (saveStreams)
  269. {
  270. GeneratedUpdate(targetPath + ImageFileName, PictureStream);
  271. }
  272. else
  273. {
  274. using (FileStream ImageFileStream =
  275. new FileStream(fileName, FileMode.Create))
  276. PictureStream.WriteTo(ImageFileStream);
  277. }
  278. }
  279. }
  280. else
  281. {
  282. PicsArchiveItem item = new PicsArchiveItem(ImageFileName, PictureStream);
  283. bool founded = false;
  284. for (int i = 0; i < picsArchive.Count; i++)
  285. if (item.FileName == picsArchive[i].FileName)
  286. {
  287. founded = true;
  288. break;
  289. }
  290. if (!founded)
  291. picsArchive.Add(item);
  292. }
  293. }
  294. if (!saveStreams)
  295. GeneratedFiles.Add(targetPath + ImageFileName);
  296. }
  297. if (EmbedPictures && PictureStream != null)
  298. {
  299. return embedPreffix + GetBase64Image(PictureStream, hash);
  300. }
  301. else if (subFolder && singlePage && !navigator)
  302. return ExportUtils.HtmlURL(subFolderPath + ImageFileName);
  303. else
  304. return ExportUtils.HtmlURL(ImageFileName);
  305. }
  306. else
  307. {
  308. if (EmbedPictures)
  309. {
  310. return embedPreffix + GetBase64Image(PictureStream, hash);
  311. }
  312. else
  313. {
  314. if (print || preview)
  315. {
  316. printPageData.Pictures.Add(PictureStream);
  317. printPageData.Guids.Add(hash);
  318. }
  319. else if (Base)
  320. {
  321. pages[CurrentPage].Pictures.Add(PictureStream);
  322. pages[CurrentPage].Guids.Add(hash);
  323. }
  324. return webImagePrefix + "=" + hash + webImageSuffix;
  325. }
  326. }
  327. }
  328. else
  329. return String.Empty;
  330. }
  331. private string GetBase64Image(MemoryStream PictureStream, string hash)
  332. {
  333. string base64Image = String.Empty;
  334. if (!EmbeddedImages.TryGetValue(hash, out base64Image))
  335. {
  336. base64Image = Convert.ToBase64String(PictureStream.ToArray());
  337. EmbeddedImages.Add(hash, base64Image);
  338. }
  339. return base64Image;
  340. }
  341. }
  342. }