using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; namespace Bowin.Common.BarCode { /// /// Code128条码 分A、B、C三种 /// public class Code128 : BarCodeBase { private DataTable c128Table = new DataTable("c128"); private Code128Type type = Code128Type.Dynamic; private List formattedData = new List(); private List encodedData = new List(); private DataRow startCharacter = null; public Code128(string input) { this.rawData = input; } public Code128(string input, Code128Type type) { this.rawData = input; this.type = type; } public override string EncodeCode() { InitCode(); return GetEncoding(); } protected override void InitCode() { //区分大小写 this.c128Table.CaseSensitive = true; this.c128Table.Columns.Add("Value", typeof(string)); this.c128Table.Columns.Add("A", typeof(string)); this.c128Table.Columns.Add("B", typeof(string)); this.c128Table.Columns.Add("C", typeof(string)); this.c128Table.Columns.Add("Encoding", typeof(string)); this.c128Table.Rows.Add(new object[] { "0", " ", " ", "00", "11011001100" }); this.c128Table.Rows.Add(new object[] { "1", "!", "!", "01", "11001101100" }); this.c128Table.Rows.Add(new object[] { "2", "\"", "\"", "02", "11001100110" }); this.c128Table.Rows.Add(new object[] { "3", "#", "#", "03", "10010011000" }); this.c128Table.Rows.Add(new object[] { "4", "$", "$", "04", "10010001100" }); this.c128Table.Rows.Add(new object[] { "5", "%", "%", "05", "10001001100" }); this.c128Table.Rows.Add(new object[] { "6", "&", "&", "06", "10011001000" }); this.c128Table.Rows.Add(new object[] { "7", "'", "'", "07", "10011000100" }); this.c128Table.Rows.Add(new object[] { "8", "(", "(", "08", "10001100100" }); this.c128Table.Rows.Add(new object[] { "9", ")", ")", "09", "11001001000" }); this.c128Table.Rows.Add(new object[] { "10", "*", "*", "10", "11001000100" }); this.c128Table.Rows.Add(new object[] { "11", "+", "+", "11", "11000100100" }); this.c128Table.Rows.Add(new object[] { "12", ",", ",", "12", "10110011100" }); this.c128Table.Rows.Add(new object[] { "13", "-", "-", "13", "10011011100" }); this.c128Table.Rows.Add(new object[] { "14", ".", ".", "14", "10011001110" }); this.c128Table.Rows.Add(new object[] { "15", "/", "/", "15", "10111001100" }); this.c128Table.Rows.Add(new object[] { "16", "0", "0", "16", "10011101100" }); this.c128Table.Rows.Add(new object[] { "17", "1", "1", "17", "10011100110" }); this.c128Table.Rows.Add(new object[] { "18", "2", "2", "18", "11001110010" }); this.c128Table.Rows.Add(new object[] { "19", "3", "3", "19", "11001011100" }); this.c128Table.Rows.Add(new object[] { "20", "4", "4", "20", "11001001110" }); this.c128Table.Rows.Add(new object[] { "21", "5", "5", "21", "11011100100" }); this.c128Table.Rows.Add(new object[] { "22", "6", "6", "22", "11001110100" }); this.c128Table.Rows.Add(new object[] { "23", "7", "7", "23", "11101101110" }); this.c128Table.Rows.Add(new object[] { "24", "8", "8", "24", "11101001100" }); this.c128Table.Rows.Add(new object[] { "25", "9", "9", "25", "11100101100" }); this.c128Table.Rows.Add(new object[] { "26", ":", ":", "26", "11100100110" }); this.c128Table.Rows.Add(new object[] { "27", ";", ";", "27", "11101100100" }); this.c128Table.Rows.Add(new object[] { "28", "<", "<", "28", "11100110100" }); this.c128Table.Rows.Add(new object[] { "29", "=", "=", "29", "11100110010" }); this.c128Table.Rows.Add(new object[] { "30", ">", ">", "30", "11011011000" }); this.c128Table.Rows.Add(new object[] { "31", "?", "?", "31", "11011000110" }); this.c128Table.Rows.Add(new object[] { "32", "@", "@", "32", "11000110110" }); this.c128Table.Rows.Add(new object[] { "33", "A", "A", "33", "10100011000" }); this.c128Table.Rows.Add(new object[] { "34", "B", "B", "34", "10001011000" }); this.c128Table.Rows.Add(new object[] { "35", "C", "C", "35", "10001000110" }); this.c128Table.Rows.Add(new object[] { "36", "D", "D", "36", "10110001000" }); this.c128Table.Rows.Add(new object[] { "37", "E", "E", "37", "10001101000" }); this.c128Table.Rows.Add(new object[] { "38", "F", "F", "38", "10001100010" }); this.c128Table.Rows.Add(new object[] { "39", "G", "G", "39", "11010001000" }); this.c128Table.Rows.Add(new object[] { "40", "H", "H", "40", "11000101000" }); this.c128Table.Rows.Add(new object[] { "41", "I", "I", "41", "11000100010" }); this.c128Table.Rows.Add(new object[] { "42", "J", "J", "42", "10110111000" }); this.c128Table.Rows.Add(new object[] { "43", "K", "K", "43", "10110001110" }); this.c128Table.Rows.Add(new object[] { "44", "L", "L", "44", "10001101110" }); this.c128Table.Rows.Add(new object[] { "45", "M", "M", "45", "10111011000" }); this.c128Table.Rows.Add(new object[] { "46", "N", "N", "46", "10111000110" }); this.c128Table.Rows.Add(new object[] { "47", "O", "O", "47", "10001110110" }); this.c128Table.Rows.Add(new object[] { "48", "P", "P", "48", "11101110110" }); this.c128Table.Rows.Add(new object[] { "49", "Q", "Q", "49", "11010001110" }); this.c128Table.Rows.Add(new object[] { "50", "R", "R", "50", "11000101110" }); this.c128Table.Rows.Add(new object[] { "51", "S", "S", "51", "11011101000" }); this.c128Table.Rows.Add(new object[] { "52", "T", "T", "52", "11011100010" }); this.c128Table.Rows.Add(new object[] { "53", "U", "U", "53", "11011101110" }); this.c128Table.Rows.Add(new object[] { "54", "V", "V", "54", "11101011000" }); this.c128Table.Rows.Add(new object[] { "55", "W", "W", "55", "11101000110" }); this.c128Table.Rows.Add(new object[] { "56", "X", "X", "56", "11100010110" }); this.c128Table.Rows.Add(new object[] { "57", "Y", "Y", "57", "11101101000" }); this.c128Table.Rows.Add(new object[] { "58", "Z", "Z", "58", "11101100010" }); this.c128Table.Rows.Add(new object[] { "59", "[", "[", "59", "11100011010" }); this.c128Table.Rows.Add(new object[] { "60", @"\", @"\", "60", "11101111010" }); this.c128Table.Rows.Add(new object[] { "61", "]", "]", "61", "11001000010" }); this.c128Table.Rows.Add(new object[] { "62", "^", "^", "62", "11110001010" }); this.c128Table.Rows.Add(new object[] { "63", "_", "_", "63", "10100110000" }); this.c128Table.Rows.Add(new object[] { "64", "\0", "`", "64", "10100001100" }); this.c128Table.Rows.Add(new object[] { "65", Convert.ToChar(1).ToString(), "a", "65", "10010110000" }); this.c128Table.Rows.Add(new object[] { "66", Convert.ToChar(2).ToString(), "b", "66", "10010000110" }); this.c128Table.Rows.Add(new object[] { "67", Convert.ToChar(3).ToString(), "c", "67", "10000101100" }); this.c128Table.Rows.Add(new object[] { "68", Convert.ToChar(4).ToString(), "d", "68", "10000100110" }); this.c128Table.Rows.Add(new object[] { "69", Convert.ToChar(5).ToString(), "e", "69", "10110010000" }); this.c128Table.Rows.Add(new object[] { "70", Convert.ToChar(6).ToString(), "f", "70", "10110000100" }); this.c128Table.Rows.Add(new object[] { "71", Convert.ToChar(7).ToString(), "g", "71", "10011010000" }); this.c128Table.Rows.Add(new object[] { "72", Convert.ToChar(8).ToString(), "h", "72", "10011000010" }); this.c128Table.Rows.Add(new object[] { "73", Convert.ToChar(9).ToString(), "i", "73", "10000110100" }); this.c128Table.Rows.Add(new object[] { "74", Convert.ToChar(10).ToString(), "j", "74", "10000110010" }); this.c128Table.Rows.Add(new object[] { "75", Convert.ToChar(11).ToString(), "k", "75", "11000010010" }); this.c128Table.Rows.Add(new object[] { "76", Convert.ToChar(12).ToString(), "l", "76", "11001010000" }); this.c128Table.Rows.Add(new object[] { "77", Convert.ToChar(13).ToString(), "m", "77", "11110111010" }); this.c128Table.Rows.Add(new object[] { "78", Convert.ToChar(14).ToString(), "n", "78", "11000010100" }); this.c128Table.Rows.Add(new object[] { "79", Convert.ToChar(15).ToString(), "o", "79", "10001111010" }); this.c128Table.Rows.Add(new object[] { "80", Convert.ToChar(16).ToString(), "p", "80", "10100111100" }); this.c128Table.Rows.Add(new object[] { "81", Convert.ToChar(17).ToString(), "q", "81", "10010111100" }); this.c128Table.Rows.Add(new object[] { "82", Convert.ToChar(18).ToString(), "r", "82", "10010011110" }); this.c128Table.Rows.Add(new object[] { "83", Convert.ToChar(19).ToString(), "s", "83", "10111100100" }); this.c128Table.Rows.Add(new object[] { "84", Convert.ToChar(20).ToString(), "t", "84", "10011110100" }); this.c128Table.Rows.Add(new object[] { "85", Convert.ToChar(21).ToString(), "u", "85", "10011110010" }); this.c128Table.Rows.Add(new object[] { "86", Convert.ToChar(22).ToString(), "v", "86", "11110100100" }); this.c128Table.Rows.Add(new object[] { "87", Convert.ToChar(23).ToString(), "w", "87", "11110010100" }); this.c128Table.Rows.Add(new object[] { "88", Convert.ToChar(24).ToString(), "x", "88", "11110010010" }); this.c128Table.Rows.Add(new object[] { "89", Convert.ToChar(25).ToString(), "y", "89", "11011011110" }); this.c128Table.Rows.Add(new object[] { "90", Convert.ToChar(26).ToString(), "z", "90", "11011110110" }); this.c128Table.Rows.Add(new object[] { "91", Convert.ToChar(27).ToString(), "{", "91", "11110110110" }); this.c128Table.Rows.Add(new object[] { "92", Convert.ToChar(28).ToString(), "|", "92", "10101111000" }); this.c128Table.Rows.Add(new object[] { "93", Convert.ToChar(29).ToString(), "}", "93", "10100011110" }); this.c128Table.Rows.Add(new object[] { "94", Convert.ToChar(30).ToString(), "~", "94", "10001011110" }); this.c128Table.Rows.Add(new object[] { "95", Convert.ToChar(31).ToString(), Convert.ToChar(127).ToString(), "95", "10111101000" }); this.c128Table.Rows.Add(new object[] { "96", Convert.ToChar(202).ToString()/*FNC3*/, Convert.ToChar(202).ToString()/*FNC3*/, "96", "10111100010" }); this.c128Table.Rows.Add(new object[] { "97", Convert.ToChar(201).ToString()/*FNC2*/, Convert.ToChar(201).ToString()/*FNC2*/, "97", "11110101000" }); this.c128Table.Rows.Add(new object[] { "98", "SHIFT", "SHIFT", "98", "11110100010" }); this.c128Table.Rows.Add(new object[] { "99", "CODE_C", "CODE_C", "99", "10111011110" }); this.c128Table.Rows.Add(new object[] { "100", "CODE_B", Convert.ToChar(203).ToString()/*FNC4*/, "CODE_B", "10111101110" }); this.c128Table.Rows.Add(new object[] { "101", Convert.ToChar(203).ToString()/*FNC4*/, "CODE_A", "CODE_A", "11101011110" }); this.c128Table.Rows.Add(new object[] { "102", Convert.ToChar(200).ToString()/*FNC1*/, Convert.ToChar(200).ToString()/*FNC1*/, Convert.ToChar(200).ToString()/*FNC1*/, "11110101110" }); this.c128Table.Rows.Add(new object[] { "103", "START_A", "START_A", "START_A", "11010000100" }); this.c128Table.Rows.Add(new object[] { "104", "START_B", "START_B", "START_B", "11010010000" }); this.c128Table.Rows.Add(new object[] { "105", "START_C", "START_C", "START_C", "11010011100" }); this.c128Table.Rows.Add(new object[] { "", "STOP", "STOP", "STOP", "11000111010" }); } /// /// 分隔资料为字符串数组 /// private void BreakUpDataForEncoding() { string temp = ""; string tempRawData = RawData; //类型为A或B时 if (this.type == Code128Type.A || this.type == Code128Type.B) { foreach (char c in RawData) { formattedData.Add(c.ToString()); } return; } //类型为C时 if (this.type == Code128Type.C) { if (!BarCodeHelper.IsNumberic(RawData)) { BarCodeHelper.ThrowBarCodeException("Code128-C条码只能录入数字", BarCodeType.Code128); } //必须被2整除 if (RawData.Length % 2 > 0) tempRawData = "0" + rawData; } foreach (char c in tempRawData) { //添加双位数字字符,如"00"、"10"等 if (Char.IsNumber(c)) { if (temp == "") { temp += c; } else { temp += c; formattedData.Add(temp); temp = ""; } } else //其它字符 { if (temp != "") { formattedData.Add(temp); temp = ""; } formattedData.Add(c.ToString()); } } if (temp != "") { formattedData.Add(temp); temp = ""; } } /// /// 插入起始标记 /// private void InsertStartandCodeCharacters() { DataRow currentCodeSet = null; string currentCodeString = ""; if (this.type != Code128Type.Dynamic) { switch (this.type) { case Code128Type.A: formattedData.Insert(0, "START_A"); break; case Code128Type.B: formattedData.Insert(0, "START_B"); break; case Code128Type.C: formattedData.Insert(0, "START_C"); break; default: BarCodeHelper.ThrowBarCodeException("未知的类型", BarCodeType.Code128); break; } } else { try { for (int i = 0; i < formattedData.Count; i++) { int col = 0; List tempStartChars = FindStartorCodeCharacter(formattedData[i], ref col); bool sameCodeSet = false; foreach (DataRow row in tempStartChars) { if (row["A"].ToString().EndsWith(currentCodeString) || row["B"].ToString().EndsWith(currentCodeString) || row["C"].ToString().EndsWith(currentCodeString)) { sameCodeSet = true; break; } } if (currentCodeString == "" || !sameCodeSet) { currentCodeSet = tempStartChars[0]; bool error = true; while (error) { try { //获取条码类型A、B、C currentCodeString = currentCodeSet[col].ToString().Split(new char[] { '_' })[1]; error = false; } catch { error = true; if (col++ > currentCodeSet.ItemArray.Length) { BarCodeHelper.ThrowBarCodeException("未找到起始标记符", BarCodeType.Code128); } } } //插入起始标记 formattedData.Insert(i++, currentCodeSet[col].ToString()); } } } catch (Exception ex) { BarCodeHelper.ThrowBarCodeException("未能插入起始标记:" + ex.Message, BarCodeType.Code128); } } } /// /// 动态查找起始标记 /// /// /// /// private List FindStartorCodeCharacter(string s, ref int col) { List rows = new List(); //若前两位为数字 if (s.Length > 1 && char.IsNumber(s[0]) && char.IsNumber(s[1])) { if (startCharacter == null) { startCharacter = this.c128Table.Select("A = 'START_C'")[0]; rows.Add(startCharacter); } else { rows.Add(this.c128Table.Select("A = 'CODE_C'")[0]); } col = 1; } else { bool aFound = false; bool bFound = false; foreach (DataRow row in this.c128Table.Rows) { try { if (!aFound && s == row["A"].ToString()) { aFound = true; col = 2; if (startCharacter == null) { startCharacter = this.c128Table.Select("A = 'START_A'")[0]; rows.Add(startCharacter); } else { rows.Add(this.c128Table.Select("B = 'CODE_A'")[0]); } } else if (!bFound && s == row["B"].ToString()) { bFound = true; col = 1; if (startCharacter == null) { startCharacter = this.c128Table.Select("A = 'START_B'")[0]; rows.Add(startCharacter); } else rows.Add(this.c128Table.Select("A = 'CODE_B'")[0]); } else if (aFound && bFound) break; } catch (Exception ex) { throw ex; } } if (rows.Count <= 0) { BarCodeHelper.ThrowBarCodeException("找不到合适的条码类型", BarCodeType.Code128); } } return rows; } /// /// 计算校验值 /// /// private string CalculateCheckDigit() { string currentStartChar = formattedData[0]; uint checkSum = 0; for (uint i = 0; i < formattedData.Count; i++) { string s = formattedData[(int)i].Replace("'", "''"); DataRow[] rows = this.c128Table.Select("A = '" + s + "'"); if (rows.Length <= 0) rows = this.c128Table.Select("B = '" + s + "'"); if (rows.Length <= 0) rows = this.c128Table.Select("C = '" + s + "'"); uint value = uint.Parse(rows[0]["Value"].ToString()); uint addition = value * ((i == 0) ? 1 : i); checkSum += addition; } uint remainder = (checkSum % 103); DataRow[] RetRows = this.c128Table.Select("Value = '" + remainder.ToString() + "'"); return RetRows[0]["Encoding"].ToString(); } /// /// 编码 /// /// private string GetEncoding() { //分隔成数组 BreakUpDataForEncoding(); //插入起始标记 InsertStartandCodeCharacters(); //计算校验码 string checkDigit = CalculateCheckDigit(); string encodData = ""; foreach (string s in formattedData) { string s1 = s.Replace("'", "''"); DataRow[] eRow; switch (this.type) { case Code128Type.A: eRow = this.c128Table.Select("A = '" + s1 + "'"); break; case Code128Type.B: eRow = this.c128Table.Select("B = '" + s1 + "'"); break; case Code128Type.C: eRow = this.c128Table.Select("C = '" + s1 + "'"); break; case Code128Type.Dynamic: eRow = this.c128Table.Select("A = '" + s1 + "'"); if (eRow.Length <= 0) { eRow = this.c128Table.Select("B = '" + s1 + "'"); if (eRow.Length <= 0) { eRow = this.c128Table.Select("C = '" + s1 + "'"); } } break; default: eRow = null; break; } if (eRow == null || eRow.Length <= 0) { BarCodeHelper.ThrowBarCodeException("未找到数据", BarCodeType.Code128); } encodData += eRow[0]["Encoding"].ToString(); encodedData.Add(eRow[0]["Encoding"].ToString()); } encodData += checkDigit; encodedData.Add(checkDigit); encodData += this.c128Table.Select("A = 'STOP'")[0]["Encoding"].ToString(); encodedData.Add(this.c128Table.Select("A = 'STOP'")[0]["Encoding"].ToString()); encodData += "11"; encodedData.Add("11"); return encodData; } } }