CsvExport.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO;
  5. using System.Globalization;
  6. using System.Text.RegularExpressions;
  7. using FastReport.Utils;
  8. using FastReport.Export;
  9. namespace FastReport.Export.Csv
  10. {
  11. /// <summary>
  12. /// Represents the CSV export filter.
  13. /// </summary>
  14. public partial class CSVExport : ExportBase
  15. {
  16. #region Constants
  17. byte[] u_HEADER = { 239, 187, 191 };
  18. #endregion
  19. #region Private fields
  20. private ExportMatrix matrix;
  21. private string separator;
  22. private Encoding encoding;
  23. private bool dataOnly;
  24. private bool noQuotes;
  25. private bool escapeQuotes;
  26. #endregion
  27. #region Properties
  28. /// <summary>
  29. /// Gets or set the resulting file encoding.
  30. /// </summary>
  31. public Encoding Encoding
  32. {
  33. get { return encoding; }
  34. set { encoding = value; }
  35. }
  36. /// <summary>
  37. /// Gets or set the separator character used in csv format.
  38. /// </summary>
  39. public string Separator
  40. {
  41. get { return separator; }
  42. set { separator = value; }
  43. }
  44. /// <summary>
  45. /// Gets or sets a value that determines whether to export the databand rows only.
  46. /// </summary>
  47. public bool DataOnly
  48. {
  49. get { return dataOnly; }
  50. set { dataOnly = value; }
  51. }
  52. /// <summary>
  53. /// Gets or sets a value that disable quotation marks for text.
  54. /// </summary>
  55. public bool NoQuotes
  56. {
  57. get { return noQuotes; }
  58. set { noQuotes = value; }
  59. }
  60. /// <summary>
  61. /// Gets or sets a value that disable escaping quotation marks for text.
  62. /// </summary>
  63. public bool EscapeQuotes
  64. {
  65. get { return escapeQuotes; }
  66. set { escapeQuotes = value; }
  67. }
  68. #endregion
  69. #region Private Methods
  70. private void ExportCsvPage(Stream stream)
  71. {
  72. int i, x, y;
  73. ExportIEMObject obj;
  74. StringBuilder builder = new StringBuilder(matrix.Width * 64 * matrix.Height);
  75. for (y = 0; y < matrix.Height - 1; y++)
  76. {
  77. for (x = 0; x < matrix.Width; x++)
  78. {
  79. i = matrix.Cell(x, y);
  80. if (i != -1)
  81. {
  82. obj = matrix.ObjectById(i);
  83. if (obj.Counter == 0)
  84. {
  85. // TODO: deprecated method?
  86. if (obj.HtmlTags)
  87. obj.Text = DeleteHtmlTags(obj.Text);
  88. if (!noQuotes)
  89. {
  90. builder.Append("\"");
  91. builder.Append(escapeQuotes ? obj.Text.Replace("\"", "\"\"") : obj.Text);
  92. builder.Append("\"");
  93. }
  94. else
  95. builder.Append(obj.Text);
  96. obj.Counter = 1;
  97. }
  98. builder.Append(separator);
  99. }
  100. }
  101. // remove the last separator in a row
  102. if (builder.ToString(builder.Length - separator.Length, separator.Length) == separator)
  103. builder.Remove(builder.Length - separator.Length, separator.Length);
  104. builder.AppendLine();
  105. }
  106. // write the resulting string to a stream
  107. byte[] bytes = encoding.GetBytes(builder.ToString());
  108. stream.Write(bytes, 0, bytes.Length);
  109. }
  110. string DeleteHtmlTags(string text)
  111. {
  112. return Regex.Replace(text, @"<[^>]*>", String.Empty);
  113. }
  114. #endregion
  115. #region Protected Methods
  116. /// <inheritdoc/>
  117. protected override void Start()
  118. {
  119. base.Start();
  120. if (encoding == Encoding.UTF8)
  121. Stream.Write(u_HEADER, 0, 3);
  122. }
  123. /// <inheritdoc/>
  124. protected override void ExportPageBegin(ReportPage page)
  125. {
  126. base.ExportPageBegin(page);
  127. matrix = new ExportMatrix();
  128. matrix.Inaccuracy = 0.5f;
  129. matrix.PlainRich = true;
  130. matrix.AreaFill = false;
  131. matrix.CropAreaFill = true;
  132. matrix.Report = Report;
  133. matrix.Images = false;
  134. matrix.WrapText = false;
  135. matrix.DataOnly = dataOnly;
  136. matrix.ShowProgress = ShowProgress;
  137. matrix.AddPageBegin(page);
  138. }
  139. /// <inheritdoc/>
  140. protected override void ExportBand(BandBase band)
  141. {
  142. base.ExportBand(band);
  143. matrix.AddBand(band, this);
  144. }
  145. /// <inheritdoc/>
  146. protected override void ExportPageEnd(ReportPage page)
  147. {
  148. matrix.AddPageEnd(page);
  149. matrix.Prepare();
  150. ExportCsvPage(Stream);
  151. base.ExportPageEnd(page);
  152. }
  153. /// <inheritdoc/>
  154. protected override string GetFileFilter()
  155. {
  156. return new MyRes("FileFilters").Get("CsvFile");
  157. }
  158. #endregion
  159. #region Public Methods
  160. /// <inheritdoc/>
  161. public override void Serialize(FRWriter writer)
  162. {
  163. base.Serialize(writer);
  164. writer.WriteStr("Separator", Separator);
  165. writer.WriteBool("DataOnly", DataOnly);
  166. }
  167. #endregion
  168. /// <summary>
  169. /// Initializes a new instance of the <see cref="CSVExport"/> class.
  170. /// </summary>
  171. public CSVExport()
  172. {
  173. separator = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
  174. encoding = Encoding.Default;
  175. dataOnly = false;
  176. noQuotes = false;
  177. }
  178. }
  179. }