ReceiptLineItem.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace Dfs.WayneChina.HyperPrinterHandler
  5. {
  6. internal class ReceiptLineItem
  7. {
  8. /// <summary>
  9. /// items included in one receipt line
  10. /// </summary>
  11. public List<ReceiptColumnItem> ColumnItems = new List<ReceiptColumnItem>();
  12. /// <summary>
  13. /// text for total line that will print on receipt
  14. /// </summary>
  15. public string[] LineText { get; }
  16. /// <summary>
  17. /// Reserve several bytes at the beginning of each line, default value is zero
  18. /// </summary>
  19. private int prefixLen = 0;
  20. /// <summary>
  21. /// Reserve several bytes at the end of each line
  22. /// </summary>
  23. private int endLen = 0;
  24. /// <summary>
  25. /// maximun length for each line, default value is 37
  26. /// </summary>
  27. private int totalLength = 37;
  28. private char space = ' ';
  29. /// <summary>
  30. ///
  31. /// </summary>
  32. /// <param name="prefixLength">Reserve several bytes at the beginning of each line, default value is zero</param>
  33. /// <param name="remainingLength">Reserve several bytes at the end of each line , default value is zero</param>
  34. /// <param name="totalLength">maximun length for each line, default value is 37</param>
  35. public ReceiptLineItem(int prefixLength, int remainingLength, int totalLength)
  36. {
  37. System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
  38. prefixLen = prefixLength;
  39. endLen = remainingLength;
  40. this.totalLength = totalLength;
  41. }
  42. /// <summary>
  43. /// Returns a list of HEX string, format for this string is as it on real receipt
  44. /// </summary>
  45. /// <returns>a list of HEX string</returns>
  46. public List<string> Format()
  47. {
  48. List<string> tempTexts = new List<string>();
  49. foreach (var ci in ColumnItems)
  50. {
  51. int lengthForEachColumn = 0;
  52. if (ci.colspan > 0)
  53. {
  54. lengthForEachColumn = (int)((float)ci.colspan / GetTotalColSpanForEachLine() * (totalLength - prefixLen - endLen));
  55. }
  56. else if (ci.width > 0)
  57. {
  58. lengthForEachColumn = (int)((float)ci.width / 100 * (totalLength - prefixLen - endLen));
  59. }
  60. byte[] b = Encoding.GetEncoding("GB2312").GetBytes(ci.Text);
  61. string tempCiText;
  62. //if the length of current column is longer than the maximun length for each column, then need to split it to serval
  63. //lines
  64. if (b.Length > lengthForEachColumn)
  65. {
  66. int tempindex = 0;
  67. int bytesToFetch = lengthForEachColumn % 2 > 0 ? lengthForEachColumn - 1 : lengthForEachColumn;
  68. int splitLines = b.Length % bytesToFetch > 0
  69. ? b.Length / bytesToFetch + 1
  70. : b.Length / bytesToFetch;
  71. for (int i = 0; i < splitLines; i++)
  72. {
  73. int bytesFetched = 0;
  74. List<byte> tempb = new List<byte>();
  75. if (i + 1 != splitLines)//not the last line
  76. {
  77. while (bytesFetched < bytesToFetch)
  78. {
  79. tempb.Add(b[tempindex++]);
  80. bytesFetched++;
  81. }
  82. tempCiText = FormatColumnItem(Encoding.GetEncoding("GB2312").GetString(tempb.ToArray()), ci.align, lengthForEachColumn, ColumnItems.IndexOf(ci));
  83. if (tempTexts.Count < i + 1)
  84. {
  85. tempTexts.Add(ToHexString(Encoding.GetEncoding("GB2312").GetBytes("".PadRight(lengthForEachColumn * ColumnItems.IndexOf(ci), space))));
  86. tempTexts[i] += ToHexString(Encoding.GetEncoding("GB2312").GetBytes(tempCiText));
  87. //tempTexts.Add("".PadRight(lengthForEachColumn * ColumnItems.IndexOf(ci), space));
  88. //tempTexts[i] += tempCiText;
  89. }
  90. else
  91. {
  92. tempTexts[i] += ToHexString(Encoding.GetEncoding("GB2312").GetBytes(tempCiText));
  93. //tempTexts[i] += tempCiText;
  94. }
  95. }
  96. else//need to add space to make sure the legth equals to lengthForEachColumn
  97. {
  98. bytesToFetch = b.Length - bytesToFetch * i;
  99. while (bytesFetched < bytesToFetch)
  100. {
  101. tempb.Add(b[tempindex++]);
  102. bytesFetched++;
  103. }
  104. tempCiText = FormatColumnItem(Encoding.GetEncoding("GB2312").GetString(tempb.ToArray()), ci.align, lengthForEachColumn, ColumnItems.IndexOf(ci));
  105. if (tempTexts.Count < i + 1)
  106. {
  107. tempTexts.Add(ToHexString(Encoding.GetEncoding("GB2312").GetBytes("".PadRight(lengthForEachColumn * ColumnItems.IndexOf(ci), space))));
  108. tempTexts[i] += ToHexString(Encoding.GetEncoding("GB2312").GetBytes(tempCiText));
  109. //tempTexts.Add("".PadRight(lengthForEachColumn * ColumnItems.IndexOf(ci), space));
  110. //tempTexts[i] += tempCiText;
  111. }
  112. else
  113. {
  114. tempTexts[i] += ToHexString(Encoding.GetEncoding("GB2312").GetBytes(tempCiText));
  115. //tempTexts[i] += tempCiText;
  116. }
  117. }
  118. }
  119. }
  120. else
  121. {
  122. tempCiText = FormatColumnItem(ci.Text, ci.align, lengthForEachColumn, ColumnItems.IndexOf(ci));
  123. if (tempTexts.Count > 0)
  124. tempTexts[0] += ToHexString(Encoding.GetEncoding("GB2312").GetBytes(tempCiText));
  125. //tempTexts[0] += tempCiText;
  126. else
  127. tempTexts.Add(ToHexString(Encoding.GetEncoding("GB2312").GetBytes(tempCiText)));
  128. //tempTexts.Add(tempCiText);
  129. //if there're serval lines exits, need to add space to rest columns
  130. for (int i = 1; i < tempTexts.Count; i++)
  131. tempTexts[i] += ToHexString(Encoding.GetEncoding("GB2312").GetBytes("".PadRight(lengthForEachColumn, space)));
  132. //tempTexts[i] += "".PadRight(lengthForEachColumn, space);
  133. }
  134. }
  135. return tempTexts;
  136. }
  137. /// <summary>
  138. ///
  139. /// </summary>
  140. /// <param name="rawData">data will be formatted</param>
  141. /// <param name="agline">agliment, left, right or center</param>
  142. /// <param name="targetLength">total length of result string</param>
  143. /// <returns></returns>
  144. private string FormatColumnItem(string rawData, string agline, int targetLength, int index)
  145. {
  146. string temp = index == 0 ? "".PadRight(prefixLen, space) : string.Empty;
  147. if (rawData.Contains("---"))
  148. {
  149. temp += rawData.PadRight(targetLength, '-');
  150. return temp;
  151. }
  152. int spaceLen = targetLength - Encoding.GetEncoding("GB2312").GetBytes(rawData).Length;
  153. if (agline.Equals("left", StringComparison.CurrentCultureIgnoreCase))
  154. {
  155. temp += rawData.PadRight(rawData.Length + spaceLen, space);
  156. }
  157. else if (agline.Equals("right", StringComparison.CurrentCultureIgnoreCase))
  158. {
  159. temp += rawData.PadLeft(rawData.Length + spaceLen, space);
  160. }
  161. else
  162. {
  163. temp += rawData.PadLeft(spaceLen / 2 + rawData.Length, space).PadRight(rawData.Length + spaceLen, space);
  164. }
  165. return temp;
  166. }
  167. /// <summary>
  168. /// return total count of column spans in each line
  169. /// </summary>
  170. /// <returns></returns>
  171. private int GetTotalColSpanForEachLine()
  172. {
  173. var totalColSpan = 0;
  174. foreach (var ci in ColumnItems)
  175. {
  176. totalColSpan += ci.colspan > 0 ? ci.colspan : 0;
  177. }
  178. return totalColSpan;
  179. }
  180. private string ToHexString(byte[] sourceBytes)
  181. {
  182. string tempHexString = "";
  183. foreach (var b in sourceBytes)
  184. {
  185. tempHexString += System.Convert.ToString(b, 16);
  186. }
  187. return tempHexString;
  188. }
  189. }
  190. }