建议不要用CODE-39码,改用CODE-128码;
CODE-39码密度比较低,条码数字内容太多,导致条码太长,缩短长度就只能减小X尺寸,造成识读困难;
CODE-128码密度高,相同的数字生成条码更短。
你可以对比一下图中的两个条码,上面是CODE-39,下面是CODE-128,相同的内容:
解决方案:
Default.aspx
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="BarcodeTest.Default" %> 2 3 <!DOCTYPE html> 4 5 <html xmlns="http://www.w3.org/1999/xhtml"> 6 <head runat="server"> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 8 <title>条形码</title> 9 <script type="text/javascript" src="jquery-latest.min.js"></script> 10 <script type="text/javascript"> 11 $(function () { 12 $("#btnBar").click(function () { 13 var rawData = $.trim($("#txtRawData").val()); 14 $("#imgBarcode").attr("src", "BarcodeHandler.ashx?RawData=" + rawData + "&BarHeight=50&BarcodeType=" + $("#ddlBarcodeType").val() 15 + "&IsDisplayFontData=" + ($("#cbIsDisplayFontData").attr("checked") == "checked") + "&FontSize=" + $("#txtFontSize").val() + "&FontAlignment=" + $("#ddlFontAlignment").get(0).selectedIndex); 16 }); 17 }); 18 </script> 19 </head> 20 <body> 21 <form id="form1" runat="server"> 22 <div> 23 原始码: 24 <input type="text" id="txtRawData" maxlength="48" value="BJ-BJSJF-GCSG-0004-HTFY00002" /> 25 <br /> 26 编码选择:<select id="ddlBarcodeType"><option>Auto</option> 27 <option>A</option> 28 <option>B</option> 29 <option>C</option> 30 </select> 31 </div> 32 <br /> 33 字体大小:<input type="text" id="txtFontSize" value="16" />字体布局:<select id="ddlFontAlignment"><option>Near</option> 34 <option selected="selected">Center</option> 35 <option>Far</option> 36 </select><input checked="checked" type="checkbox" id="cbIsDisplayFontData" />字体显示 37 <div> 38 <input type="button" id="btnBar" value="生成条形码" /> 39 </div> 40 <div style="text-align: center;"> 41 <img id="imgBarcode" src="" alt="条形码" /> 42 </div> 43 </form> 44 </body> 45 </html>
BarcodeHandler.ashx
1 using Barcode; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Web; 6 7 namespace BarcodeTest 8 { 9 /// <summary> 10 /// author: Kenmu 11 /// created by: 2014-11-06 12 /// function: 条形码生成 13 /// </summary> 14 public class BarcodeHandler : IHttpHandler 15 { 16 17 public void ProcessRequest(HttpContext context) 18 { 19 HttpRequest request = context.Request; 20 HttpResponse response = context.Response; 21 response.ClearContent(); 22 response.ContentType = "image/jpeg"; 23 24 string barcodeType = request["BarcodeType"] ?? "Auto"; 25 string rawData = request["RawData"] ?? ((char)20).ToString() + @"123a" + ((char)18).ToString() + "ab"; 26 byte barHeight = byte.Parse(string.IsNullOrEmpty(request["BarHeight"]) ? "32" : request["BarHeight"]); 27 bool isDisplayFontData = string.IsNullOrEmpty(request["IsDisplayFontData"]) ? true : bool.Parse(request["IsDisplayFontData"]); 28 int fontSize = string.IsNullOrEmpty(request["FontSize"]) ? 16 : int.Parse(request["FontSize"]); 29 int fontAlignment = string.IsNullOrEmpty(request["FontAlignment"]) ? 1 : int.Parse(request["FontAlignment"]);//0(Near左)、1(Center中)、2(Far右) 30 BaseCode128 code128; 31 switch (barcodeType) 32 { 33 case "A": 34 code128 = new Code128A(rawData); 35 break; 36 case "B": 37 code128 = new Code128B(rawData); 38 break; 39 case "C": 40 code128 = new Code128C(rawData); 41 break; 42 case "Auto": 43 default: 44 code128 = new Code128Auto(rawData); 45 break; 46 } 47 code128.BarHeight = barHeight; 48 code128.IsDisplayFontData = isDisplayFontData; 49 code128.FontSize = fontSize; 50 code128.FontAlignment = (System.Drawing.StringAlignment)fontAlignment; 51 52 System.Drawing.Image img = code128.GetBarCodeImage(); 53 img.Save(response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg); 54 img.Dispose(); 55 } 56 57 public bool IsReusable 58 { 59 get 60 { 61 return false; 62 } 63 } 64 } 65 }
CharacterSet.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 //author: Kenmu 7 //created by: 2014-11-05 8 //function: 条形码 9 namespace Barcode 10 { 11 /// <summary> 12 /// Code128字符集 13 /// </summary> 14 internal enum CharacterSet 15 { 16 A, 17 B, 18 C 19 } 20 }
IBarCode.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Drawing; 4 using System.Linq; 5 using System.Text; 6 7 //author: Kenmu 8 //created by: 2014-11-05 9 //function: 条形码 10 namespace Barcode 11 { 12 /// <summary> 13 /// 条形码接口 14 /// </summary> 15 public interface IBarCode 16 { 17 string RawData { get; } 18 /// <summary> 19 /// 条形码对应的数据 20 /// </summary> 21 string EncodedData { get; } 22 /// <summary> 23 /// 当前条形码标准 24 /// </summary> 25 string BarCodeType { get; } 26 27 /// <summary> 28 /// 得到条形码对应的图片 29 /// </summary> 30 /// <returns></returns> 31 Image GetBarCodeImage(); 32 } 33 }
BaseCode128.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Drawing; 6 7 //author: Kenmu 8 //created by: 2014-11-06 9 //function: 条形码 10 namespace Barcode 11 { 12 /// <summary> 13 /// BaseCode128抽象类 14 /// </summary> 15 public abstract class BaseCode128 : IBarCode 16 { 17 protected Color backColor = Color.White;//条码背景色 18 protected Color barColor = Color.Black;//条码和原始数据字体颜色 19 20 /// <summary> 21 /// 当前条形码种类 22 /// </summary> 23 public string BarCodeType 24 { 25 get { return System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name; } 26 } 27 28 /// <summary> 29 /// 条形码对应的编码数据 30 /// </summary> 31 protected string _EncodedData; 32 public string EncodedData 33 { 34 get { return this._EncodedData; } 35 } 36 37 /// <summary> 38 /// 【原始数据】 39 /// </summary> 40 protected string _RawData; 41 public string RawData 42 { 43 get { return this._RawData; } 44 } 45 46 /// <summary> 47 /// 在条形码下面显示数据;如果为空,则取【原始数据】 48 /// </summary> 49 protected string _PresentationData = null; 50 public string PresentationData 51 { 52 get { return string.IsNullOrEmpty(this._PresentationData) ? this._RawData : this._PresentationData; } 53 } 54 55 /// <summary> 56 /// 条码单位宽度;单位Pix,默认为1 57 /// </summary> 58 protected byte _BarCellWidth = 1; 59 public byte BarCellWidth 60 { 61 get { return this._BarCellWidth; } 62 set 63 { 64 if (value == 0) 65 { 66 this._BarCellWidth = 1; 67 } 68 else 69 { 70 this._BarCellWidth = value; 71 } 72 } 73 } 74 75 /// <summary> 76 /// 条码高度,必须至少是条码宽度的0.15倍或6.35mm,两者取大者;默认按照实际为32,单位mm 77 /// </summary> 78 protected byte _BarHeight = 32; 79 public byte BarHeight 80 { 81 get { return this._BarHeight; } 82 set 83 { 84 this._BarHeight = value; 85 } 86 } 87 88 /// <summary> 89 /// 是否在条形码下面显示【原始数据】 90 /// </summary> 91 protected bool _IsDisplayFontData = true; 92 public bool IsDisplayFontData 93 { 94 get { return this._IsDisplayFontData; } 95 set { this._IsDisplayFontData = value; } 96 } 97 98 /// <summary> 99 /// 【原始数据】与条形码的空间间隔;单位Pix,默认为4 100 /// </summary> 101 protected byte _FontPadding = 4; 102 public byte FontPadding 103 { 104 get { return this._FontPadding; } 105 set { this._FontPadding = value; } 106 } 107 108 /// <summary> 109 /// 【原始数据】字体大小;单位Pix,默认为16 110 /// </summary> 111 protected float _FontSize = 16; 112 public float FontSize 113 { 114 get { return this._FontSize; } 115 set { this._FontSize = value; } 116 } 117 118 /// <summary> 119 /// 【原始数据】字体布局位置;默认水平居中 120 /// </summary> 121 protected StringAlignment _FontAlignment = StringAlignment.Center; 122 public StringAlignment FontAlignment 123 { 124 get { return this._FontAlignment; } 125 set { this._FontAlignment = value; } 126 } 127 128 public BaseCode128(string rawData) 129 { 130 this._RawData = rawData; 131 if (string.IsNullOrEmpty(this._RawData)) 132 { 133 throw new Exception("空字符串无法生成条形码"); 134 } 135 this._RawData = this._RawData.Trim(); 136 if (!this.RawDataCheck()) 137 { 138 throw new Exception(rawData + " 不符合 " + this.BarCodeType + " 标准"); 139 } 140 this._EncodedData = this.GetEncodedData(); 141 } 142 143 protected int GetBarCodePhyWidth() 144 { 145 //在212222这种BS单元下,要计算bsGroup对应模块宽度的倍率 146 //应该要将总长度减去1(因为Stop对应长度为7),然后结果乘以11再除以6,与左右空白相加后再加上2(Stop比正常的BS多出2个模块组) 147 int bsNum = (this._EncodedData.Length - 1) * 11 / 6 + 2; 148 return bsNum * this._BarCellWidth; 149 } 150 151 /// <summary> 152 /// 数据输入正确性验证 153 /// </summary> 154 /// <returns></returns> 155 protected abstract bool RawDataCheck(); 156 157 /// <summary> 158 /// 获取当前Data对应的编码数据(条空组合) 159 /// </summary> 160 /// <returns></returns> 161 protected abstract string GetEncodedData(); 162 163 /// <summary> 164 /// 获取完整的条形码 165 /// </summary> 166 /// <returns></returns> 167 public Image GetBarCodeImage() 168 { 169 Image barImage = this.GetBarOnlyImage(); 170 int width = barImage.Width; 171 int height = barImage.Height; 172 if (this._IsDisplayFontData) 173 { 174 height += this._FontPadding + (int)this._FontSize; 175 } 176 177 Image image = new Bitmap(width, height); 178 Graphics g = Graphics.FromImage(image); 179 g.Clear(this.backColor); 180 g.DrawImage(barImage, 0, 0, barImage.Width, barImage.Height); 181 182 if (this._IsDisplayFontData) 183 { 184 Font drawFont = new Font(new FontFamily("Times New Roman"), this._FontSize, FontStyle.Regular, GraphicsUnit.Pixel); 185 Brush drawBrush = new SolidBrush(this.barColor); 186 StringFormat drawFormat = new StringFormat(); 187 drawFormat.Alignment = this._FontAlignment; 188 RectangleF reF = new RectangleF(0, barImage.Height + this._FontPadding, width, this._FontSize); 189 g.DrawString(this.PresentationData, drawFont, drawBrush, reF, drawFormat); 190 191 drawFont.Dispose(); 192 drawBrush.Dispose(); 193 drawFormat.Dispose(); 194 } 195 196 System.IO.MemoryStream ms = new System.IO.MemoryStream(); 197 image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 198 //结束绘制 199 g.Dispose(); 200 image.Dispose(); 201 return Image.FromStream(ms); 202 } 203 /// <summary> 204 /// 获取仅包含条形码的图像 205 /// </summary> 206 /// <returns></returns> 207 private Image GetBarOnlyImage() 208 { 209 int width = (int)this.GetBarCodePhyWidth(); 210 Bitmap image = new Bitmap(width, this._BarHeight); 211 int ptr = 0; 212 for (int i = 0; i < this._EncodedData.Length; i++) 213 { 214 int w = (int)char.GetNumericValue(this._EncodedData[i]); 215 w *= this._BarCellWidth; 216 Color c = i % 2 == 0 ? this.barColor : this.backColor; 217 for (int j = 0; j < w; j++) 218 { 219 for (int h = 0; h < this._BarHeight; h++) 220 { 221 image.SetPixel(ptr, h, c); 222 } 223 ptr++; 224 } 225 } 226 return image; 227 } 228 } 229 }
Code128.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Text.RegularExpressions; 6 7 //author: Kenmu 8 //created by: 2014-11-05 9 //function: 条形码 10 namespace Barcode 11 { 12 /// <summary> 13 /// Code128基础相关类 14 /// </summary> 15 public static class Code128 16 { 17 /* 18 * 128 尺寸要求 19 * 最小模块宽度 x 最大1.016mm,最小0.250mm 一个系统中的x应为一恒定值 标准是1mm,放大系数0.25~1.2 20 * 左右侧空白区最小宽度为 10x 21 * 条高通常为32mm,实际可以根据具体要求 22 * 23 * 最大物理长度不应超过 165mm,可编码的最大数据字符数为48,其中包括应用标识符和作为分隔符使用的FNC1字符,但不包括辅助字符和校验符 24 * 25 * AI中FNC1同样作为分隔符使用 26 * 27 * ASCII 28 * 0~31 StartA 专有 29 * 96~127 StartB 专有 30 * 31 * EAN128不使用空格(ASCII码32) 32 */ 33 34 /// <summary> 35 /// Code128条空排列集合,1代表条b,0代表空s,Index对应符号字符值S 36 /// </summary> 37 internal static readonly List<string> BSList = new List<string>() 38 { 39 "212222" , "222122" , "222221" , "121223" , "121322" , "131222" , "122213" , "122312" , "132212" , "221213" , 40 "221312" , "231212" , "112232" , "122132" , "122231" , "113222" , "123122" , "123221" , "223211" , "221132" , 41 "221231" , "213212" , "223112" , "312131" , "311222" , "321122" , "321221" , "312212" , "322112" , "322211" , 42 "212123" , "212321" , "232121" , "111323" , "131123" , "131321" , "112313" , "132113" , "132311" , "211313" , 43 "231113" , "231311" , "112133" , "112331" , "132131" , "113123" , "113321" , "133121" , "313121" , "211331" , 44 "231131" , "213113" , "213311" , "213131" , "311123" , "311321" , "331121" , "312113" , "312311" , "332111" , 45 "314111" , "221411" , "431111" , "111224" , "111422" , "121124" , "121421" , "141122" , "141221" , "112214" , 46 "112412" , "122114" , "122411" , "142112" , "142211" , "241211" , "221114" , "413111" , "241112" , "134111" , 47 "111242" , "121142" , "121241" , "114212" , "124112" , "124211" , "411212" , "421112" , "421211" , "212141" , 48 "214121" , "412121" , "111143" , "111341" , "131141" , "114113" , "114311" , "411113" , "411311" , "113141" , 49 "114131" , "311141" , "411131" , "211412" , "211214" , "211232" , "2331112" 50 }; 51 52 internal const byte FNC3_AB = 96, FNC2_AB = 97, SHIFT_AB = 98, CODEC_AB = 99, CODEB_AC = 100, CODEA_BC = 101; 53 internal const byte FNC4_A = 101, FNC4_B = 100; 54 internal const byte FNC1 = 102, StartA = 103, StartB = 104, StartC = 105; 55 internal const byte Stop = 106; 56 57 /// <summary> 58 /// 获取字符在字符集A中对应的符号字符值S 59 /// </summary> 60 /// <param name="c"></param> 61 /// <returns></returns> 62 internal static byte GetSIndexFromA(char c) 63 { 64 byte sIndex = (byte)c; 65 //字符集A中 符号字符值S 若ASCII<32,则 S=ASCII+64 ,若95>=ASCII>=32,则S=ASCII-32 66 if (sIndex < 32) 67 { 68 sIndex += 64; 69 } 70 else if (sIndex < 96) 71 { 72 sIndex -= 32; 73 } 74 else 75 { 76 throw new NotImplementedException(); 77 } 78 return sIndex; 79 } 80 /// <summary> 81 /// 获取字符在字符集B中对应的符号字符值S 82 /// </summary> 83 /// <param name="c"></param> 84 /// <returns></returns> 85 internal static byte GetSIndexFromB(char c) 86 { 87 byte sIndex = (byte)c; 88 if (sIndex > 31 && sIndex < 128) 89 { 90 sIndex -= 32;//字符集B中ASCII码 减去32后就等于符号字符值 91 } 92 else 93 { 94 throw new NotImplementedException(); 95 } 96 return sIndex; 97 } 98 internal static byte GetSIndex(CharacterSet characterSet, char c) 99 { 100 switch (characterSet) 101 { 102 case CharacterSet.A: 103 return GetSIndexFromA(c); 104 case CharacterSet.B: 105 return GetSIndexFromB(c); 106 default: 107 throw new NotImplementedException(); 108 } 109 } 110 /// <summary> 111 /// 判断指定字符是否仅属于指定字符集 112 /// </summary> 113 /// <param name="characterSet"></param> 114 /// <param name="c"></param> 115 /// <returns></returns> 116 internal static bool CharOnlyBelongsTo(CharacterSet characterSet, char c) 117 { 118 switch (characterSet) 119 { 120 case CharacterSet.A: 121 return (byte)c < 32; 122 case CharacterSet.B: 123 return (byte)c > 95 && (byte)c < 128; 124 default: 125 throw new NotImplementedException(); 126 } 127 } 128 /// <summary> 129 /// 判断指定字符是否不属于指定字符集 130 /// </summary> 131 /// <param name="characterSet"></param> 132 /// <param name="c"></param> 133 /// <returns></returns> 134 internal static bool CharNotBelongsTo(CharacterSet characterSet, char c) 135 { 136 switch (characterSet) 137 { 138 case CharacterSet.A: 139 return (byte)c > 95; 140 case CharacterSet.B: 141 return (byte)c < 32 && (byte)c > 127; 142 default: 143 throw new NotImplementedException(); 144 } 145 } 146 /// <summary> 147 /// 当编码转换时,获取相应的切换符对应的符号字符值 148 /// </summary> 149 /// <param name="newCharacterSet"></param> 150 /// <returns></returns> 151 internal static byte GetCodeXIndex(CharacterSet newCharacterSet) 152 { 153 switch (newCharacterSet) 154 { 155 case CharacterSet.A: 156 return CODEA_BC; 157 case CharacterSet.B: 158 return CODEB_AC; 159 default: 160 return CODEC_AB; 161 } 162 } 163 /// <summary> 164 /// 获取转换后的字符集 165 /// </summary> 166 /// <param name="characterSet"></param> 167 /// <returns></returns> 168 internal static CharacterSet GetShiftCharacterSet(CharacterSet characterSet) 169 { 170 switch (characterSet) 171 { 172 case CharacterSet.A: 173 return CharacterSet.B; 174 case CharacterSet.B: 175 return CharacterSet.A; 176 default: 177 throw new NotImplementedException(); 178 } 179 } 180 /// <summary> 181 /// 获取应采用的字符集 182 /// </summary> 183 /// <param name="data"></param> 184 /// <param name="startIndex">判断开始位置</param> 185 /// <returns></returns> 186 internal static CharacterSet GetCharacterSet(string data, int startIndex) 187 { 188 CharacterSet returnSet = CharacterSet.B; 189 if (Regex.IsMatch(data.Substring(startIndex), @"^\d{4,}")) 190 { 191 returnSet = CharacterSet.C; 192 } 193 else 194 { 195 byte byteC = GetProprietaryChar(data, startIndex); 196 returnSet = byteC < 32 ? CharacterSet.A : CharacterSet.B; 197 } 198 return returnSet; 199 } 200 /// <summary> 201 /// 从指定位置开始,返回第一个大于95(并且小于128)或小于32的字符对应的值 202 /// </summary> 203 /// <param name="data"></param> 204 /// <param name="startIndex"></param> 205 /// <returns>如果没有任何字符匹配,则返回255</returns> 206 internal static byte GetProprietaryChar(string data, int startIndex) 207 { 208 byte returnByte = byte.MaxValue; 209 for (int i = startIndex; i < data.Length; i++) 210 { 211 byte byteC = (byte)data[i]; 212 if (byteC < 32 || byteC > 95 && byteC < 128) 213 { 214 returnByte = byteC; 215 break; 216 } 217 } 218 return returnByte; 219 } 220 /// <summary> 221 /// 获取字符串从指定位置开始连续出现数字的个数 222 /// </summary> 223 /// <param name="data"></param> 224 /// <param name="startIndex"></param> 225 /// <returns></returns> 226 internal static int GetDigitLength(string data, int startIndex) 227 { 228 int digitLength = data.Length - startIndex;//默认设定从起始位置开始至最后都是数字 229 for (int i = startIndex; i < data.Length; i++) 230 { 231 if (!char.IsDigit(data[i])) 232 { 233 digitLength = i - startIndex; 234 break; 235 } 236 } 237 return digitLength; 238 } 239 } 240 }
Code128A.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 //author: Kenmu 7 //created by: 2014-11-05 8 //function: 条形码 9 namespace Barcode 10 { 11 /// <summary> 12 /// Code128A条形码,只支持128字符集A(数字、大写字母、控制字符) 13 /// </summary> 14 public class Code128A : BaseCode128 15 { 16 public Code128A(string rawData) 17 : base(rawData) 18 { 19 } 20 21 protected override bool RawDataCheck() 22 { 23 //128字符集A对应的ASCII码范围为0~95 24 foreach (char c in this._RawData) 25 { 26 byte tempC = (byte)c; 27 if (tempC <= 95) 28 { 29 continue; 30 } 31 else 32 { 33 return false; 34 } 35 } 36 return true; 37 } 38 39 protected override string GetEncodedData() 40 { 41 StringBuilder tempBuilder = new StringBuilder(); 42 tempBuilder.Append(Code128.BSList[Code128.StartA]);//加上起始符StartA 43 byte sIndex; 44 int checkNum = Code128.StartA;//校验字符 45 for (int i = 0; i < this._RawData.Length; i++) 46 { 47 sIndex = Code128.GetSIndexFromA(this._RawData[i]); 48 tempBuilder.Append(Code128.BSList[sIndex]); 49 checkNum += (i + 1) * sIndex; 50 } 51 checkNum %= 103; 52 tempBuilder.Append(Code128.BSList[checkNum]);//加上校验符 53 tempBuilder.Append(Code128.BSList[Code128.Stop]);//加上结束符 54 return tempBuilder.ToString(); 55 } 56 } 57 }
Code128Auto.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 //author: Kenmu 7 //created by: 2014-11-05 8 //function: 条形码 9 namespace Barcode 10 { 11 /// <summary> 12 /// Code128Auto条形码,遵循长度最小原则 13 /// </summary> 14 public class Code128Auto : BaseCode128 15 { 16 public Code128Auto(string rawData) 17 : base(rawData) 18 { 19 } 20 21 protected override bool RawDataCheck() 22 { 23 //Code128对应的ASCII码范围是0~127 24 foreach (char c in this._RawData) 25 { 26 if ((byte)c > 127) 27 { 28 return false; 29 } 30 } 31 return true; 32 } 33 34 protected override string GetEncodedData() 35 { 36 StringBuilder tempBuilder = new StringBuilder(); 37 38 CharacterSet nowCharacterSet = Code128.GetCharacterSet(this._RawData, 0); 39 40 int checkNum;//校验字符 41 switch (nowCharacterSet) 42 { 43 case CharacterSet.A: 44 tempBuilder.Append(Code128.BSList[Code128.StartA]);//加上起始符StartA 45 checkNum = Code128.StartA; 46 break; 47 case CharacterSet.B: 48 tempBuilder.Append(Code128.BSList[Code128.StartB]);//加上起始符StartB 49 checkNum = Code128.StartB; 50 break; 51 default: 52 tempBuilder.Append(Code128.BSList[Code128.StartC]);//加上起始符StartC 53 checkNum = Code128.StartC; 54 break; 55 } 56 int nowWeight = 1, nowIndex = 0; 57 this.GetEncodedData(tempBuilder, nowCharacterSet, ref nowIndex, ref nowWeight, ref checkNum); 58 59 checkNum %= 103; 60 tempBuilder.Append(Code128.BSList[checkNum]);//加上校验符 61 tempBuilder.Append(Code128.BSList[Code128.Stop]);//加上结束符 62 return tempBuilder.ToString(); 63 } 64 /// <summary> 65 /// 通用方法 66 /// </summary> 67 /// <param name="tempBuilder"></param> 68 /// <param name="sIndex"></param> 69 /// <param name="nowWeight"></param> 70 /// <param name="checkNum"></param> 71 private void EncodingCommon(StringBuilder tempBuilder, byte sIndex, ref int nowWeight, ref int checkNum) 72 { 73 tempBuilder.Append(Code128.BSList[sIndex]); 74 checkNum += nowWeight * sIndex; 75 nowWeight++; 76 } 77 /// <summary> 78 /// 获取编码后的数据 79 /// </summary> 80 /// <param name="tempBuilder">编码数据容器</param> 81 /// <param name="nowCharacterSet">当前字符集</param> 82 /// <param name="i">字符串索引</param> 83 /// <param name="nowWeight">当前权值</param> 84 /// <param name="checkNum">当前检验值总和</param> 85 private void GetEncodedData(StringBuilder tempBuilder, CharacterSet nowCharacterSet, ref int i, ref int nowWeight, ref int checkNum) 86 {//因为可能存在字符集C,所以i与nowWeight可能存在不一致关系,所以要分别定义 87 byte sIndex; 88 switch (nowCharacterSet) 89 { 90 case CharacterSet.A: 91 case CharacterSet.B: 92 for (; i < this._RawData.Length; i++) 93 { 94 if (char.IsDigit(this._RawData[i])) 95 { 96 //数字 97 int digitLength = Code128.GetDigitLength(this._RawData, i); 98 if (digitLength >= 4) 99 { 100 //转入CodeC 101 if (digitLength % 2 != 0) 102 {//奇数位数字,在第一个数字之后插入CodeC字符 103 sIndex = Code128.GetSIndex(nowCharacterSet, (this._RawData[i])); 104 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum); 105 i++; 106 } 107 nowCharacterSet = CharacterSet.C; 108 sIndex = Code128.GetCodeXIndex(nowCharacterSet);//插入CodeC切换字符 109 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum); 110 this.GetEncodedData(tempBuilder, nowCharacterSet, ref i, ref nowWeight, ref checkNum); 111 return; 112 } 113 else 114 { 115 //如果小于4位数字,则直接内部循环结束 116 for (int j = 0; j < digitLength; j++) 117 { 118 sIndex = Code128.GetSIndex(nowCharacterSet, (this._RawData[i])); 119 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum); 120 i++; 121 } 122 i--;//因为上面循环结束后继续外部循环会导致i多加了1,所以要减去1 123 continue; 124 } 125 } 126 else if (Code128.CharNotBelongsTo(nowCharacterSet, this._RawData[i])) 127 {//当前字符不属于目前的字符集 128 byte tempByte = Code128.GetProprietaryChar(this._RawData, i + 1);//获取当前字符后第一个属于A,或B的字符集 129 CharacterSet tempCharacterSet = Code128.GetShiftCharacterSet(nowCharacterSet); 130 if (tempByte != byte.MaxValue && Code128.CharOnlyBelongsTo(nowCharacterSet, (char)tempByte)) 131 { 132 //加入转换符 133 sIndex = Code128.SHIFT_AB; 134 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum); 135 136 sIndex = Code128.GetSIndex(tempCharacterSet, this._RawData[i]); 137 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum); 138 continue; 139 } 140 else 141 { 142 //加入切换符 143 nowCharacterSet = tempCharacterSet; 144 sIndex = Code128.GetCodeXIndex(nowCharacterSet); 145 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum); 146 this.GetEncodedData(tempBuilder, nowCharacterSet, ref i, ref nowWeight, ref checkNum); 147 return; 148 } 149 } 150 else 151 { 152 sIndex = Code128.GetSIndex(nowCharacterSet, this._RawData[i]); 153 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum); 154 } 155 } 156 break; 157 default: 158 for (; i < this._RawData.Length; i += 2) 159 { 160 if (i != this._RawData.Length - 1 && char.IsDigit(this._RawData, i) && char.IsDigit(this._RawData, i + 1)) 161 { 162 sIndex = byte.Parse(this._RawData.Substring(i, 2)); 163 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum); 164 } 165 else 166 { 167 nowCharacterSet = Code128.GetCharacterSet(this._RawData, i); 168 //插入转换字符 169 sIndex = Code128.GetCodeXIndex(nowCharacterSet); 170 this.EncodingCommon(tempBuilder, sIndex, ref nowWeight, ref checkNum); 171 this.GetEncodedData(tempBuilder, nowCharacterSet, ref i, ref nowWeight, ref checkNum); 172 return; 173 } 174 } 175 break; 176 } 177 } 178 } 179 }
Code128B.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 //author: Kenmu 7 //created by: 2014-11-05 8 //function: 条形码 9 namespace Barcode 10 { 11 /// <summary> 12 /// Code128B条形码,只支持128字符集B(数字、大小字母、字符) 13 /// </summary> 14 public class Code128B : BaseCode128 15 { 16 public Code128B(string rawData) 17 : base(rawData) 18 { 19 } 20 21 protected override bool RawDataCheck() 22 { 23 //128字符集B对应的ASCII码范围为32~127 24 foreach (char c in this._RawData) 25 { 26 byte tempC = (byte)c; 27 if (tempC >= 32 && tempC <= 127) 28 { 29 continue; 30 } 31 else 32 { 33 return false; 34 } 35 } 36 return true; 37 } 38 39 protected override string GetEncodedData() 40 { 41 StringBuilder tempBuilder = new StringBuilder(); 42 tempBuilder.Append(Code128.BSList[Code128.StartB]);//加上起始符StartB 43 byte sIndex; 44 int checkNum = Code128.StartB;//校验字符 45 for (int i = 0; i < this._RawData.Length; i++) 46 { 47 sIndex = Code128.GetSIndexFromB(this._RawData[i]);//字符集B中ASCII码 减去32后就等于符号字符值 48 tempBuilder.Append(Code128.BSList[sIndex]); 49 checkNum += (i + 1) * sIndex; 50 } 51 checkNum %= 103; 52 tempBuilder.Append(Code128.BSList[checkNum]);//加上校验符 53 tempBuilder.Append(Code128.BSList[Code128.Stop]);//加上结束符 54 return tempBuilder.ToString(); 55 } 56 } 57 }
Code128C.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Text.RegularExpressions; 6 7 //author: Kenmu 8 //created by: 2014-11-05 9 //function: 条形码 10 namespace Barcode 11 { 12 /// <summary> 13 /// Code128C条形码,只支持128字符集C(双位数字) 14 /// </summary> 15 public class Code128C : BaseCode128 16 { 17 public Code128C(string rawData) 18 : base(rawData) 19 { 20 } 21 22 protected override bool RawDataCheck() 23 { 24 return Regex.IsMatch(this._RawData, @"^\d{2,96}$") && this._RawData.Length % 2 == 0;//Code128C 2个数字代表一个数据字符,所以最大可以96个数字 25 } 26 27 protected override string GetEncodedData() 28 { 29 StringBuilder tempBuilder = new StringBuilder(); 30 tempBuilder.Append(Code128.BSList[Code128.StartC]);//加上起始符StartC 31 byte sIndex; 32 int checkNum = Code128.StartC;//校验字符,StartC为105 33 for (int i = 0; i < this._RawData.Length / 2; i++) 34 { 35 sIndex = byte.Parse(this._RawData.Substring(i * 2, 2)); 36 tempBuilder.Append(Code128.BSList[sIndex]); 37 checkNum += (i + 1) * sIndex; 38 } 39 checkNum %= 103; 40 tempBuilder.Append(Code128.BSList[checkNum]);//加上校验符 41 tempBuilder.Append(Code128.BSList[Code128.Stop]);//加上结束符 42 return tempBuilder.ToString(); 43 } 44 } 45 }
如有需要,请点击下面链接进行下载: