Code128.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Data;
  6. namespace Bowin.Common.BarCode
  7. {
  8. /// <summary>
  9. /// Code128条码 分A、B、C三种
  10. /// </summary>
  11. public class Code128 : BarCodeBase
  12. {
  13. private DataTable c128Table = new DataTable("c128");
  14. private Code128Type type = Code128Type.Dynamic;
  15. private List<string> formattedData = new List<string>();
  16. private List<string> encodedData = new List<string>();
  17. private DataRow startCharacter = null;
  18. public Code128(string input)
  19. {
  20. this.rawData = input;
  21. }
  22. public Code128(string input, Code128Type type)
  23. {
  24. this.rawData = input;
  25. this.type = type;
  26. }
  27. public override string EncodeCode()
  28. {
  29. InitCode();
  30. return GetEncoding();
  31. }
  32. protected override void InitCode()
  33. {
  34. //区分大小写
  35. this.c128Table.CaseSensitive = true;
  36. this.c128Table.Columns.Add("Value", typeof(string));
  37. this.c128Table.Columns.Add("A", typeof(string));
  38. this.c128Table.Columns.Add("B", typeof(string));
  39. this.c128Table.Columns.Add("C", typeof(string));
  40. this.c128Table.Columns.Add("Encoding", typeof(string));
  41. this.c128Table.Rows.Add(new object[] { "0", " ", " ", "00", "11011001100" });
  42. this.c128Table.Rows.Add(new object[] { "1", "!", "!", "01", "11001101100" });
  43. this.c128Table.Rows.Add(new object[] { "2", "\"", "\"", "02", "11001100110" });
  44. this.c128Table.Rows.Add(new object[] { "3", "#", "#", "03", "10010011000" });
  45. this.c128Table.Rows.Add(new object[] { "4", "$", "$", "04", "10010001100" });
  46. this.c128Table.Rows.Add(new object[] { "5", "%", "%", "05", "10001001100" });
  47. this.c128Table.Rows.Add(new object[] { "6", "&", "&", "06", "10011001000" });
  48. this.c128Table.Rows.Add(new object[] { "7", "'", "'", "07", "10011000100" });
  49. this.c128Table.Rows.Add(new object[] { "8", "(", "(", "08", "10001100100" });
  50. this.c128Table.Rows.Add(new object[] { "9", ")", ")", "09", "11001001000" });
  51. this.c128Table.Rows.Add(new object[] { "10", "*", "*", "10", "11001000100" });
  52. this.c128Table.Rows.Add(new object[] { "11", "+", "+", "11", "11000100100" });
  53. this.c128Table.Rows.Add(new object[] { "12", ",", ",", "12", "10110011100" });
  54. this.c128Table.Rows.Add(new object[] { "13", "-", "-", "13", "10011011100" });
  55. this.c128Table.Rows.Add(new object[] { "14", ".", ".", "14", "10011001110" });
  56. this.c128Table.Rows.Add(new object[] { "15", "/", "/", "15", "10111001100" });
  57. this.c128Table.Rows.Add(new object[] { "16", "0", "0", "16", "10011101100" });
  58. this.c128Table.Rows.Add(new object[] { "17", "1", "1", "17", "10011100110" });
  59. this.c128Table.Rows.Add(new object[] { "18", "2", "2", "18", "11001110010" });
  60. this.c128Table.Rows.Add(new object[] { "19", "3", "3", "19", "11001011100" });
  61. this.c128Table.Rows.Add(new object[] { "20", "4", "4", "20", "11001001110" });
  62. this.c128Table.Rows.Add(new object[] { "21", "5", "5", "21", "11011100100" });
  63. this.c128Table.Rows.Add(new object[] { "22", "6", "6", "22", "11001110100" });
  64. this.c128Table.Rows.Add(new object[] { "23", "7", "7", "23", "11101101110" });
  65. this.c128Table.Rows.Add(new object[] { "24", "8", "8", "24", "11101001100" });
  66. this.c128Table.Rows.Add(new object[] { "25", "9", "9", "25", "11100101100" });
  67. this.c128Table.Rows.Add(new object[] { "26", ":", ":", "26", "11100100110" });
  68. this.c128Table.Rows.Add(new object[] { "27", ";", ";", "27", "11101100100" });
  69. this.c128Table.Rows.Add(new object[] { "28", "<", "<", "28", "11100110100" });
  70. this.c128Table.Rows.Add(new object[] { "29", "=", "=", "29", "11100110010" });
  71. this.c128Table.Rows.Add(new object[] { "30", ">", ">", "30", "11011011000" });
  72. this.c128Table.Rows.Add(new object[] { "31", "?", "?", "31", "11011000110" });
  73. this.c128Table.Rows.Add(new object[] { "32", "@", "@", "32", "11000110110" });
  74. this.c128Table.Rows.Add(new object[] { "33", "A", "A", "33", "10100011000" });
  75. this.c128Table.Rows.Add(new object[] { "34", "B", "B", "34", "10001011000" });
  76. this.c128Table.Rows.Add(new object[] { "35", "C", "C", "35", "10001000110" });
  77. this.c128Table.Rows.Add(new object[] { "36", "D", "D", "36", "10110001000" });
  78. this.c128Table.Rows.Add(new object[] { "37", "E", "E", "37", "10001101000" });
  79. this.c128Table.Rows.Add(new object[] { "38", "F", "F", "38", "10001100010" });
  80. this.c128Table.Rows.Add(new object[] { "39", "G", "G", "39", "11010001000" });
  81. this.c128Table.Rows.Add(new object[] { "40", "H", "H", "40", "11000101000" });
  82. this.c128Table.Rows.Add(new object[] { "41", "I", "I", "41", "11000100010" });
  83. this.c128Table.Rows.Add(new object[] { "42", "J", "J", "42", "10110111000" });
  84. this.c128Table.Rows.Add(new object[] { "43", "K", "K", "43", "10110001110" });
  85. this.c128Table.Rows.Add(new object[] { "44", "L", "L", "44", "10001101110" });
  86. this.c128Table.Rows.Add(new object[] { "45", "M", "M", "45", "10111011000" });
  87. this.c128Table.Rows.Add(new object[] { "46", "N", "N", "46", "10111000110" });
  88. this.c128Table.Rows.Add(new object[] { "47", "O", "O", "47", "10001110110" });
  89. this.c128Table.Rows.Add(new object[] { "48", "P", "P", "48", "11101110110" });
  90. this.c128Table.Rows.Add(new object[] { "49", "Q", "Q", "49", "11010001110" });
  91. this.c128Table.Rows.Add(new object[] { "50", "R", "R", "50", "11000101110" });
  92. this.c128Table.Rows.Add(new object[] { "51", "S", "S", "51", "11011101000" });
  93. this.c128Table.Rows.Add(new object[] { "52", "T", "T", "52", "11011100010" });
  94. this.c128Table.Rows.Add(new object[] { "53", "U", "U", "53", "11011101110" });
  95. this.c128Table.Rows.Add(new object[] { "54", "V", "V", "54", "11101011000" });
  96. this.c128Table.Rows.Add(new object[] { "55", "W", "W", "55", "11101000110" });
  97. this.c128Table.Rows.Add(new object[] { "56", "X", "X", "56", "11100010110" });
  98. this.c128Table.Rows.Add(new object[] { "57", "Y", "Y", "57", "11101101000" });
  99. this.c128Table.Rows.Add(new object[] { "58", "Z", "Z", "58", "11101100010" });
  100. this.c128Table.Rows.Add(new object[] { "59", "[", "[", "59", "11100011010" });
  101. this.c128Table.Rows.Add(new object[] { "60", @"\", @"\", "60", "11101111010" });
  102. this.c128Table.Rows.Add(new object[] { "61", "]", "]", "61", "11001000010" });
  103. this.c128Table.Rows.Add(new object[] { "62", "^", "^", "62", "11110001010" });
  104. this.c128Table.Rows.Add(new object[] { "63", "_", "_", "63", "10100110000" });
  105. this.c128Table.Rows.Add(new object[] { "64", "\0", "`", "64", "10100001100" });
  106. this.c128Table.Rows.Add(new object[] { "65", Convert.ToChar(1).ToString(), "a", "65", "10010110000" });
  107. this.c128Table.Rows.Add(new object[] { "66", Convert.ToChar(2).ToString(), "b", "66", "10010000110" });
  108. this.c128Table.Rows.Add(new object[] { "67", Convert.ToChar(3).ToString(), "c", "67", "10000101100" });
  109. this.c128Table.Rows.Add(new object[] { "68", Convert.ToChar(4).ToString(), "d", "68", "10000100110" });
  110. this.c128Table.Rows.Add(new object[] { "69", Convert.ToChar(5).ToString(), "e", "69", "10110010000" });
  111. this.c128Table.Rows.Add(new object[] { "70", Convert.ToChar(6).ToString(), "f", "70", "10110000100" });
  112. this.c128Table.Rows.Add(new object[] { "71", Convert.ToChar(7).ToString(), "g", "71", "10011010000" });
  113. this.c128Table.Rows.Add(new object[] { "72", Convert.ToChar(8).ToString(), "h", "72", "10011000010" });
  114. this.c128Table.Rows.Add(new object[] { "73", Convert.ToChar(9).ToString(), "i", "73", "10000110100" });
  115. this.c128Table.Rows.Add(new object[] { "74", Convert.ToChar(10).ToString(), "j", "74", "10000110010" });
  116. this.c128Table.Rows.Add(new object[] { "75", Convert.ToChar(11).ToString(), "k", "75", "11000010010" });
  117. this.c128Table.Rows.Add(new object[] { "76", Convert.ToChar(12).ToString(), "l", "76", "11001010000" });
  118. this.c128Table.Rows.Add(new object[] { "77", Convert.ToChar(13).ToString(), "m", "77", "11110111010" });
  119. this.c128Table.Rows.Add(new object[] { "78", Convert.ToChar(14).ToString(), "n", "78", "11000010100" });
  120. this.c128Table.Rows.Add(new object[] { "79", Convert.ToChar(15).ToString(), "o", "79", "10001111010" });
  121. this.c128Table.Rows.Add(new object[] { "80", Convert.ToChar(16).ToString(), "p", "80", "10100111100" });
  122. this.c128Table.Rows.Add(new object[] { "81", Convert.ToChar(17).ToString(), "q", "81", "10010111100" });
  123. this.c128Table.Rows.Add(new object[] { "82", Convert.ToChar(18).ToString(), "r", "82", "10010011110" });
  124. this.c128Table.Rows.Add(new object[] { "83", Convert.ToChar(19).ToString(), "s", "83", "10111100100" });
  125. this.c128Table.Rows.Add(new object[] { "84", Convert.ToChar(20).ToString(), "t", "84", "10011110100" });
  126. this.c128Table.Rows.Add(new object[] { "85", Convert.ToChar(21).ToString(), "u", "85", "10011110010" });
  127. this.c128Table.Rows.Add(new object[] { "86", Convert.ToChar(22).ToString(), "v", "86", "11110100100" });
  128. this.c128Table.Rows.Add(new object[] { "87", Convert.ToChar(23).ToString(), "w", "87", "11110010100" });
  129. this.c128Table.Rows.Add(new object[] { "88", Convert.ToChar(24).ToString(), "x", "88", "11110010010" });
  130. this.c128Table.Rows.Add(new object[] { "89", Convert.ToChar(25).ToString(), "y", "89", "11011011110" });
  131. this.c128Table.Rows.Add(new object[] { "90", Convert.ToChar(26).ToString(), "z", "90", "11011110110" });
  132. this.c128Table.Rows.Add(new object[] { "91", Convert.ToChar(27).ToString(), "{", "91", "11110110110" });
  133. this.c128Table.Rows.Add(new object[] { "92", Convert.ToChar(28).ToString(), "|", "92", "10101111000" });
  134. this.c128Table.Rows.Add(new object[] { "93", Convert.ToChar(29).ToString(), "}", "93", "10100011110" });
  135. this.c128Table.Rows.Add(new object[] { "94", Convert.ToChar(30).ToString(), "~", "94", "10001011110" });
  136. this.c128Table.Rows.Add(new object[] { "95", Convert.ToChar(31).ToString(), Convert.ToChar(127).ToString(), "95", "10111101000" });
  137. this.c128Table.Rows.Add(new object[] { "96", Convert.ToChar(202).ToString()/*FNC3*/, Convert.ToChar(202).ToString()/*FNC3*/, "96", "10111100010" });
  138. this.c128Table.Rows.Add(new object[] { "97", Convert.ToChar(201).ToString()/*FNC2*/, Convert.ToChar(201).ToString()/*FNC2*/, "97", "11110101000" });
  139. this.c128Table.Rows.Add(new object[] { "98", "SHIFT", "SHIFT", "98", "11110100010" });
  140. this.c128Table.Rows.Add(new object[] { "99", "CODE_C", "CODE_C", "99", "10111011110" });
  141. this.c128Table.Rows.Add(new object[] { "100", "CODE_B", Convert.ToChar(203).ToString()/*FNC4*/, "CODE_B", "10111101110" });
  142. this.c128Table.Rows.Add(new object[] { "101", Convert.ToChar(203).ToString()/*FNC4*/, "CODE_A", "CODE_A", "11101011110" });
  143. this.c128Table.Rows.Add(new object[] { "102", Convert.ToChar(200).ToString()/*FNC1*/, Convert.ToChar(200).ToString()/*FNC1*/, Convert.ToChar(200).ToString()/*FNC1*/, "11110101110" });
  144. this.c128Table.Rows.Add(new object[] { "103", "START_A", "START_A", "START_A", "11010000100" });
  145. this.c128Table.Rows.Add(new object[] { "104", "START_B", "START_B", "START_B", "11010010000" });
  146. this.c128Table.Rows.Add(new object[] { "105", "START_C", "START_C", "START_C", "11010011100" });
  147. this.c128Table.Rows.Add(new object[] { "", "STOP", "STOP", "STOP", "11000111010" });
  148. }
  149. /// <summary>
  150. /// 分隔资料为字符串数组
  151. /// </summary>
  152. private void BreakUpDataForEncoding()
  153. {
  154. string temp = "";
  155. string tempRawData = RawData;
  156. //类型为A或B时
  157. if (this.type == Code128Type.A || this.type == Code128Type.B)
  158. {
  159. foreach (char c in RawData)
  160. {
  161. formattedData.Add(c.ToString());
  162. }
  163. return;
  164. }
  165. //类型为C时
  166. if (this.type == Code128Type.C)
  167. {
  168. if (!BarCodeHelper.IsNumberic(RawData))
  169. {
  170. BarCodeHelper.ThrowBarCodeException("Code128-C条码只能录入数字", BarCodeType.Code128);
  171. }
  172. //必须被2整除
  173. if (RawData.Length % 2 > 0)
  174. tempRawData = "0" + rawData;
  175. }
  176. foreach (char c in tempRawData)
  177. {
  178. //添加双位数字字符,如"00"、"10"等
  179. if (Char.IsNumber(c))
  180. {
  181. if (temp == "")
  182. {
  183. temp += c;
  184. }
  185. else
  186. {
  187. temp += c;
  188. formattedData.Add(temp);
  189. temp = "";
  190. }
  191. }
  192. else //其它字符
  193. {
  194. if (temp != "")
  195. {
  196. formattedData.Add(temp);
  197. temp = "";
  198. }
  199. formattedData.Add(c.ToString());
  200. }
  201. }
  202. if (temp != "")
  203. {
  204. formattedData.Add(temp);
  205. temp = "";
  206. }
  207. }
  208. /// <summary>
  209. /// 插入起始标记
  210. /// </summary>
  211. private void InsertStartandCodeCharacters()
  212. {
  213. DataRow currentCodeSet = null;
  214. string currentCodeString = "";
  215. if (this.type != Code128Type.Dynamic)
  216. {
  217. switch (this.type)
  218. {
  219. case Code128Type.A: formattedData.Insert(0, "START_A");
  220. break;
  221. case Code128Type.B: formattedData.Insert(0, "START_B");
  222. break;
  223. case Code128Type.C: formattedData.Insert(0, "START_C");
  224. break;
  225. default:
  226. BarCodeHelper.ThrowBarCodeException("未知的类型", BarCodeType.Code128);
  227. break;
  228. }
  229. }
  230. else
  231. {
  232. try
  233. {
  234. for (int i = 0; i < formattedData.Count; i++)
  235. {
  236. int col = 0;
  237. List<DataRow> tempStartChars = FindStartorCodeCharacter(formattedData[i], ref col);
  238. bool sameCodeSet = false;
  239. foreach (DataRow row in tempStartChars)
  240. {
  241. if (row["A"].ToString().EndsWith(currentCodeString) || row["B"].ToString().EndsWith(currentCodeString) || row["C"].ToString().EndsWith(currentCodeString))
  242. {
  243. sameCodeSet = true;
  244. break;
  245. }
  246. }
  247. if (currentCodeString == "" || !sameCodeSet)
  248. {
  249. currentCodeSet = tempStartChars[0];
  250. bool error = true;
  251. while (error)
  252. {
  253. try
  254. {
  255. //获取条码类型A、B、C
  256. currentCodeString = currentCodeSet[col].ToString().Split(new char[] { '_' })[1];
  257. error = false;
  258. }
  259. catch
  260. {
  261. error = true;
  262. if (col++ > currentCodeSet.ItemArray.Length)
  263. {
  264. BarCodeHelper.ThrowBarCodeException("未找到起始标记符", BarCodeType.Code128);
  265. }
  266. }
  267. }
  268. //插入起始标记
  269. formattedData.Insert(i++, currentCodeSet[col].ToString());
  270. }
  271. }
  272. }
  273. catch (Exception ex)
  274. {
  275. BarCodeHelper.ThrowBarCodeException("未能插入起始标记:" + ex.Message, BarCodeType.Code128);
  276. }
  277. }
  278. }
  279. /// <summary>
  280. /// 动态查找起始标记
  281. /// </summary>
  282. /// <param name="s"></param>
  283. /// <param name="col"></param>
  284. /// <returns></returns>
  285. private List<DataRow> FindStartorCodeCharacter(string s, ref int col)
  286. {
  287. List<DataRow> rows = new List<DataRow>();
  288. //若前两位为数字
  289. if (s.Length > 1 && char.IsNumber(s[0]) && char.IsNumber(s[1]))
  290. {
  291. if (startCharacter == null)
  292. {
  293. startCharacter = this.c128Table.Select("A = 'START_C'")[0];
  294. rows.Add(startCharacter);
  295. }
  296. else
  297. {
  298. rows.Add(this.c128Table.Select("A = 'CODE_C'")[0]);
  299. }
  300. col = 1;
  301. }
  302. else
  303. {
  304. bool aFound = false;
  305. bool bFound = false;
  306. foreach (DataRow row in this.c128Table.Rows)
  307. {
  308. try
  309. {
  310. if (!aFound && s == row["A"].ToString())
  311. {
  312. aFound = true;
  313. col = 2;
  314. if (startCharacter == null)
  315. {
  316. startCharacter = this.c128Table.Select("A = 'START_A'")[0];
  317. rows.Add(startCharacter);
  318. }
  319. else
  320. {
  321. rows.Add(this.c128Table.Select("B = 'CODE_A'")[0]);
  322. }
  323. }
  324. else if (!bFound && s == row["B"].ToString())
  325. {
  326. bFound = true;
  327. col = 1;
  328. if (startCharacter == null)
  329. {
  330. startCharacter = this.c128Table.Select("A = 'START_B'")[0];
  331. rows.Add(startCharacter);
  332. }
  333. else
  334. rows.Add(this.c128Table.Select("A = 'CODE_B'")[0]);
  335. }
  336. else if (aFound && bFound)
  337. break;
  338. }
  339. catch (Exception ex)
  340. {
  341. throw ex;
  342. }
  343. }
  344. if (rows.Count <= 0)
  345. {
  346. BarCodeHelper.ThrowBarCodeException("找不到合适的条码类型", BarCodeType.Code128);
  347. }
  348. }
  349. return rows;
  350. }
  351. /// <summary>
  352. /// 计算校验值
  353. /// </summary>
  354. /// <returns></returns>
  355. private string CalculateCheckDigit()
  356. {
  357. string currentStartChar = formattedData[0];
  358. uint checkSum = 0;
  359. for (uint i = 0; i < formattedData.Count; i++)
  360. {
  361. string s = formattedData[(int)i].Replace("'", "''");
  362. DataRow[] rows = this.c128Table.Select("A = '" + s + "'");
  363. if (rows.Length <= 0)
  364. rows = this.c128Table.Select("B = '" + s + "'");
  365. if (rows.Length <= 0)
  366. rows = this.c128Table.Select("C = '" + s + "'");
  367. uint value = uint.Parse(rows[0]["Value"].ToString());
  368. uint addition = value * ((i == 0) ? 1 : i);
  369. checkSum += addition;
  370. }
  371. uint remainder = (checkSum % 103);
  372. DataRow[] RetRows = this.c128Table.Select("Value = '" + remainder.ToString() + "'");
  373. return RetRows[0]["Encoding"].ToString();
  374. }
  375. /// <summary>
  376. /// 编码
  377. /// </summary>
  378. /// <returns></returns>
  379. private string GetEncoding()
  380. {
  381. //分隔成数组
  382. BreakUpDataForEncoding();
  383. //插入起始标记
  384. InsertStartandCodeCharacters();
  385. //计算校验码
  386. string checkDigit = CalculateCheckDigit();
  387. string encodData = "";
  388. foreach (string s in formattedData)
  389. {
  390. string s1 = s.Replace("'", "''");
  391. DataRow[] eRow;
  392. switch (this.type)
  393. {
  394. case Code128Type.A:
  395. eRow = this.c128Table.Select("A = '" + s1 + "'");
  396. break;
  397. case Code128Type.B:
  398. eRow = this.c128Table.Select("B = '" + s1 + "'");
  399. break;
  400. case Code128Type.C:
  401. eRow = this.c128Table.Select("C = '" + s1 + "'");
  402. break;
  403. case Code128Type.Dynamic:
  404. eRow = this.c128Table.Select("A = '" + s1 + "'");
  405. if (eRow.Length <= 0)
  406. {
  407. eRow = this.c128Table.Select("B = '" + s1 + "'");
  408. if (eRow.Length <= 0)
  409. {
  410. eRow = this.c128Table.Select("C = '" + s1 + "'");
  411. }
  412. }
  413. break;
  414. default: eRow = null;
  415. break;
  416. }
  417. if (eRow == null || eRow.Length <= 0)
  418. {
  419. BarCodeHelper.ThrowBarCodeException("未找到数据", BarCodeType.Code128);
  420. }
  421. encodData += eRow[0]["Encoding"].ToString();
  422. encodedData.Add(eRow[0]["Encoding"].ToString());
  423. }
  424. encodData += checkDigit;
  425. encodedData.Add(checkDigit);
  426. encodData += this.c128Table.Select("A = 'STOP'")[0]["Encoding"].ToString();
  427. encodedData.Add(this.c128Table.Select("A = 'STOP'")[0]["Encoding"].ToString());
  428. encodData += "11";
  429. encodedData.Add("11");
  430. return encodData;
  431. }
  432. }
  433. }