.NET条形码

建议不要用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 }

 

如有需要,请点击下面链接进行下载:

基于128位的条形码Barcode.zip

 

你可能感兴趣的:(.net)