LaTeXExport.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Text;
  6. using FastReport.Table;
  7. using FastReport.Utils;
  8. namespace FastReport.Export.LaTeX
  9. {
  10. /// <summary>
  11. /// Represents the LaTeX export filter.
  12. /// </summary>
  13. public partial class LaTeXExport : ExportBase
  14. {
  15. const float PT_MM = 2.834645669291f;
  16. const float PT_INCH = 72;
  17. const float PT_PX = 72f / 96f;
  18. private float leftMargin = 0;
  19. private float topMargin = 0;
  20. private float leftStartPos = 0;
  21. private float topStartPos = 0;
  22. #region Private Methods
  23. private void Write(Stream stream, string value)
  24. {
  25. byte[] buf = Encoding.UTF8.GetBytes(value);
  26. stream.Write(buf, 0, buf.Length);
  27. }
  28. private void WriteLn(Stream stream, string value)
  29. {
  30. byte[] buf = Encoding.UTF8.GetBytes(value);
  31. stream.Write(buf, 0, buf.Length);
  32. stream.WriteByte(13);
  33. stream.WriteByte(10);
  34. }
  35. #endregion
  36. #region Protected Methods
  37. /// <inheritdoc/>
  38. protected override void Start()
  39. {
  40. base.Start();
  41. WriteLn(Stream, @"\documentclass{report}");
  42. WriteLn(Stream, @"\usepackage{xltxtra}");
  43. WriteLn(Stream, @"\usepackage{vmargin}");
  44. WriteLn(Stream, @"\usepackage[absolute,overlay]{textpos}");
  45. WriteLn(Stream, @"\usepackage{ragged2e}");
  46. WriteLn(Stream, @"\author {" + PrepareString(Report.ReportInfo.Author) + "}");
  47. WriteLn(Stream, @"\title {" + PrepareString(Report.ReportInfo.Name) + "}");
  48. WriteLn(Stream, @"\date {\today}");
  49. WriteLn(Stream, @"\newcommand{\textout}[3]{\setlength{\parindent}{0mm}{\fontspec{#1}{\fontsize{#2}{12}\selectfont {#3}}}}");
  50. WriteLn(Stream, @"\newcommand{\text}[6]{");
  51. WriteLn(Stream, @"\raggedright\begin{textblock*}{#1}(#2,#3)");
  52. WriteLn(Stream, @"{\textout{#4}{#5}{#6}}");
  53. WriteLn(Stream, @"\end{textblock*}}");
  54. WriteLn(Stream, @"\newcommand{\textright}[6]{");
  55. WriteLn(Stream, @"\raggedleft\begin{textblock*}{#1}(#2,#3)");
  56. WriteLn(Stream, @"{\textout{#4}{#5}{#6}}");
  57. WriteLn(Stream, @"\end{textblock*}}");
  58. WriteLn(Stream, @"\newcommand{\textcenter}[6]{");
  59. WriteLn(Stream, @"\centering\begin{textblock*}{#1}(#2,#3)");
  60. WriteLn(Stream, @"{\textout{#4}{#5}{#6}}");
  61. WriteLn(Stream, @"\end{textblock*}}");
  62. WriteLn(Stream, @"\newcommand{\textjustify}[6]{");
  63. WriteLn(Stream, @"\justify\begin{textblock*}{#1}(#2,#3)");
  64. WriteLn(Stream, @"{\textout{#4}{#5}{#6}}");
  65. WriteLn(Stream, @"\end{textblock*}}");
  66. WriteLn(Stream, @"\begin{document}");
  67. }
  68. /// <inheritdoc/>
  69. protected override void Finish()
  70. {
  71. WriteLn(Stream, @"\end{document}");
  72. }
  73. /// <inheritdoc/>
  74. protected override string GetFileFilter()
  75. {
  76. return new MyRes("FileFilters").Get("LaTeXFile");
  77. }
  78. /// <inheritdoc/>
  79. protected override void ExportPageBegin(ReportPage page)
  80. {
  81. base.ExportPageBegin(page);
  82. leftMargin = page.LeftMargin * PT_MM;
  83. topMargin = page.TopMargin * PT_MM;
  84. leftStartPos = leftMargin + PT_INCH;
  85. topStartPos = topMargin + PT_INCH;
  86. WriteLn(Stream, @"\setpapersize{custom}{" + page.PaperWidth.ToString() + "mm}{" + page.PaperHeight.ToString() + "mm}");
  87. WriteLn(Stream, @"\setmarginsrb{" +
  88. Math.Round(leftMargin, 2).ToString("R") + "pt}{" +
  89. Math.Round(topMargin, 2).ToString("R") + "pt}{" +
  90. Math.Round(page.RightMargin * PT_MM, 2).ToString("R") + "pt}{" +
  91. Math.Round(page.BottomMargin * PT_MM, 2).ToString("R") + "pt}{0pt}{0pt}{0pt}{0pt}");
  92. WriteLn(Stream, @"\thispagestyle{empty}");
  93. WriteLn(Stream, @"\ ");
  94. }
  95. /// <inheritdoc/>
  96. protected override void ExportPageEnd(ReportPage page)
  97. {
  98. base.ExportPageEnd(page);
  99. WriteLn(Stream, @"\newpage");
  100. }
  101. /// <inheritdoc/>
  102. protected override void ExportBand(BandBase band)
  103. {
  104. base.ExportBand(band);
  105. if (band.Parent == null)
  106. return;
  107. // add export of band
  108. foreach (Base bandObject in band.ForEachAllConvectedObjects(this))
  109. {
  110. if (bandObject is TableBase)
  111. {
  112. ExportTableObject(bandObject as TableBase);
  113. }
  114. else if (bandObject is TextObject)
  115. {
  116. ExportTextObject(bandObject as TextObject);
  117. }
  118. }
  119. }
  120. private StringBuilder PrepareString(string line)
  121. {
  122. StringBuilder sb = new StringBuilder(line.Length);
  123. foreach (char c in line)
  124. {
  125. switch (c)
  126. {
  127. case '%':
  128. sb.Append(@"\%");
  129. break;
  130. case '$':
  131. sb.Append(@"\$");
  132. break;
  133. case '&':
  134. sb.Append(@"\&");
  135. break;
  136. case '_':
  137. sb.Append(@"\_");
  138. break;
  139. case '{':
  140. sb.Append(@"\{");
  141. break;
  142. case '}':
  143. sb.Append(@"\}");
  144. break;
  145. case '#':
  146. sb.Append(@"\#");
  147. break;
  148. case '^':
  149. sb.Append(@"\^");
  150. break;
  151. case '~':
  152. sb.Append(@"\~");
  153. break;
  154. case '\\':
  155. sb.Append(@"\textbackslash");
  156. break;
  157. case '\n':
  158. sb.Append("\n\\\\");
  159. break;
  160. default:
  161. sb.Append(c);
  162. break;
  163. }
  164. }
  165. return sb;
  166. }
  167. private void ExportTableObject(TableBase table)
  168. {
  169. if (table.ColumnCount > 0 && table.RowCount > 0)
  170. {
  171. float y = 0;
  172. for (int i = 0; i < table.RowCount; i++)
  173. {
  174. float x = 0;
  175. for (int j = 0; j < table.ColumnCount; j++)
  176. {
  177. if (!table.IsInsideSpan(table[j, i]))
  178. {
  179. TableCell textcell = table[j, i];
  180. textcell.Left = x;
  181. textcell.Top = y;
  182. if (textcell is TextObject)
  183. ExportTextObject(textcell as TextObject);
  184. }
  185. x += (table.Columns[j]).Width;
  186. }
  187. y += (table.Rows[i]).Height;
  188. }
  189. }
  190. }
  191. private void ExportTextObject(TextObject textObject)
  192. {
  193. StringBuilder sb = new StringBuilder();
  194. DrawTextFrame(sb, textObject.Text, textObject.Font, textObject.AbsLeft, textObject.AbsTop, textObject.Width, textObject.HorzAlign);
  195. Write(Stream, sb.ToString());
  196. }
  197. private void DrawTextFrame(StringBuilder sb, string text, Font font, float left, float top, float width, HorzAlign horizAlign)
  198. {
  199. sb.Append(@"\").Append(GetBlockJustify(horizAlign)).Append("{").
  200. Append(Math.Round(width * PT_PX, 2).ToString("R")).Append("pt}{").
  201. Append(Math.Round(leftStartPos + left * PT_PX, 2).ToString("R")).Append("pt}{").
  202. Append(Math.Round(topStartPos + top * PT_PX, 2).ToString("R")).Append("pt}{").
  203. Append(font.Name).Append("}{").Append(font.Size.ToString()).Append("}{").
  204. Append(GetFontStyle(font)).
  205. Append(PrepareString(text)).
  206. AppendLine("}");
  207. }
  208. private string GetBlockJustify(HorzAlign horizAlign)
  209. {
  210. if (horizAlign == HorzAlign.Left)
  211. return "text";
  212. else if (horizAlign == HorzAlign.Right)
  213. return "textright";
  214. else if (horizAlign == HorzAlign.Center)
  215. return "textcenter";
  216. else
  217. return "textjustify";
  218. }
  219. private StringBuilder GetFontStyle(Font font)
  220. {
  221. StringBuilder sb = new StringBuilder();
  222. if (font.Bold)
  223. sb.Append(@"\bfseries ");
  224. if (font.Italic)
  225. sb.Append(@"\itshape ");
  226. return sb;
  227. }
  228. #endregion
  229. /// <summary>
  230. /// Initializes a new instance of the <see cref="LaTeXExport"/> class.
  231. /// </summary>
  232. public LaTeXExport()
  233. {
  234. }
  235. }
  236. }