asp.net mvc 生成条形码

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.Drawing;
  5 using System.Linq;
  6 using System.Text;
  7 using System.Threading.Tasks;
  8 
  9 namespace JXUtil
 10 {
 11     public class BarCode
 12     {
 13         private Hashtable _Code39 = new Hashtable();
 14 
 15         /// <summary>
 16         /// 内容
 17         /// </summary>
 18         public string Text { get; set; }
 19 
 20         /// <summary>
 21         /// 放大倍数
 22         /// </summary>
 23         public byte Magnify { get; set; }
 24 
 25         /// <summary>
 26         /// 图形高
 27         /// </summary>
 28         public int Height { get; set; }
 29 
 30         /// <summary>
 31         /// 字体大小
 32         /// </summary>
 33         public Font ViewFont { get; set; }
 34 
 35         public BarCode()
 36         {
 37             _Code39.Add("A", "1101010010110");
 38             _Code39.Add("B", "1011010010110");
 39             _Code39.Add("C", "1101101001010");
 40             _Code39.Add("D", "1010110010110");
 41             _Code39.Add("E", "1101011001010");
 42             _Code39.Add("F", "1011011001010");
 43             _Code39.Add("G", "1010100110110");
 44             _Code39.Add("H", "1101010011010");
 45             _Code39.Add("I", "1011010011010");
 46             _Code39.Add("J", "1010110011010");
 47             _Code39.Add("K", "1101010100110");
 48             _Code39.Add("L", "1011010100110");
 49             _Code39.Add("M", "1101101010010");
 50             _Code39.Add("N", "1010110100110");
 51             _Code39.Add("O", "1101011010010");
 52             _Code39.Add("P", "1011011010010");
 53             _Code39.Add("Q", "1010101100110");
 54             _Code39.Add("R", "1101010110010");
 55             _Code39.Add("S", "1011010110010");
 56             _Code39.Add("T", "1010110110010");
 57             _Code39.Add("U", "1100101010110");
 58             _Code39.Add("V", "1001101010110");
 59             _Code39.Add("W", "1100110101010");
 60             _Code39.Add("X", "1001011010110");
 61             _Code39.Add("Y", "1100101101010");
 62             _Code39.Add("Z", "1001101101010");
 63             _Code39.Add("0", "1010011011010");
 64             _Code39.Add("1", "1101001010110");
 65             _Code39.Add("2", "1011001010110");
 66             _Code39.Add("3", "1101100101010");
 67             _Code39.Add("4", "1010011010110");
 68             _Code39.Add("5", "1101001101010");
 69             _Code39.Add("6", "1011001101010");
 70             _Code39.Add("7", "1010010110110");
 71             _Code39.Add("8", "1101001011010");
 72             _Code39.Add("9", "1011001011010");
 73             _Code39.Add("+", "1001010010010");
 74             _Code39.Add("-", "1001010110110");
 75             _Code39.Add("*", "1001011011010");
 76             _Code39.Add("/", "1001001010010");
 77             _Code39.Add("%", "1010010010010");
 78             _Code39.Add("&", "1001001001010");
 79             _Code39.Add(".", "1100101011010");
 80             _Code39.Add(" ", "1001101011010");
 81         }
 82 
 83         public enum Code39Model
 84         {
 85             /// <summary>
 86             /// 基本类别 1234567890ABC
 87             /// </summary>
 88             Code39Normal,
 89             /// <summary>
 90             /// 全ASCII方式 +A+B 来表示小写
 91             /// </summary>
 92             Code39FullAscII
 93         }
 94 
 95         /// <summary>
 96         /// 获得条码图形
 97         /// </summary>
 98         /// <param name="text">文字信息</param>
 99         /// <param name="model">类别</param>
100         /// <param name="stat">是否增加前后*号</param>
101         /// <returns>图形</returns>
102         public Bitmap GetCodeImage(Code39Model model, bool star)
103         {
104             string textVal = "";
105             string textCode = "";
106             char[] charVal = null;
107             switch (model)
108             {
109                 case Code39Model.Code39Normal:
110                     textVal = Text.ToUpper();
111                     break;
112                 default:
113                     charVal = Text.ToCharArray();
114                     for (int i = 0; i != charVal.Length; i++)
115                     {
116                         if ((int)charVal[i] >= 97 && (int)charVal[i] <= 122)
117                         {
118                             textVal += "+" + charVal[i].ToString().ToUpper();
119 
120                         }
121                         else
122                         {
123                             textVal += charVal[i].ToString();
124                         }
125                     }
126                     break;
127             }
128             charVal = textVal.ToCharArray();
129             if (star == true) textCode += _Code39["*"];
130             for (int i = 0; i != charVal.Length; i++)
131             {
132                 if (star == true && charVal[i] == '*') throw new Exception("带有起始符号不能出现*");
133                 object _CharCode = _Code39[charVal[i].ToString()];
134                 if (_CharCode == null) throw new Exception("不可用的字符" + charVal[i].ToString());
135                 textCode += _CharCode.ToString();
136             }
137             if (star == true) textCode += _Code39["*"];
138             Bitmap bmp = GetImage(textCode);
139             GetViewImage(bmp, Text);
140             return bmp;
141         }
142 
143         /// <summary>
144         /// 绘制编码图形
145         /// </summary>
146         /// <param name="text">编码</param>
147         /// <returns>图形</returns>
148         private Bitmap GetImage(string text)
149         {
150             char[] val = text.ToCharArray();
151 
152             //宽 == 需要绘制的数量*放大倍数 + 两个字的宽   
153             Bitmap codeImg = new Bitmap(val.Length * ((int)Magnify + 1), (int)Height);
154             Graphics graph = Graphics.FromImage(codeImg);
155 
156             graph.FillRectangle(Brushes.White, new Rectangle(0, 0, codeImg.Width, codeImg.Height));
157 
158             int len = 0;
159             for (int i = 0; i != val.Length; i++)
160             {
161                 int width = Magnify + 1;
162                 if (val[i] == '1')
163                 {
164                     graph.FillRectangle(Brushes.Black, new Rectangle(len, 0, width, Height));
165 
166                 }
167                 else
168                 {
169                     graph.FillRectangle(Brushes.White, new Rectangle(len, 0, width, Height));
170                 }
171                 len += width;
172             }
173 
174             graph.Dispose();
175             return codeImg;
176         }
177 
178         /// <summary>
179         /// 绘制文字
180         /// </summary>
181         /// <param name="codeImage">图形</param>
182         /// <param name="text">文字</param>
183         private void GetViewImage(Bitmap codeImage, string text)
184         {
185             if (ViewFont == null) return;
186             Graphics graphic = Graphics.FromImage(codeImage);
187             SizeF fontSize = graphic.MeasureString(text, ViewFont);
188 
189             if (fontSize.Width > codeImage.Width || fontSize.Height > codeImage.Height - 20)
190             {
191                 graphic.Dispose();
192                 return;
193             }
194             int starHeight = codeImage.Height - (int)fontSize.Height;
195             graphic.FillRectangle(Brushes.White, new Rectangle(0, starHeight, codeImage.Width, (int)fontSize.Height));
196 
197             int _StarWidth = (codeImage.Width - (int)fontSize.Width) / 2;
198             graphic.DrawString(text, ViewFont, Brushes.Black, _StarWidth, starHeight);
199             graphic.Dispose();
200 
201         }
202     }
203 
204     public class BarCode128
205     {
206         //  ASCII从32到127对应的条码区,由3个条、3个空、共11个单元构成,符号内含校验码
207         private string[] Code128Encoding = new string[] {
208 "11011001100", "11001101100", "11001100110", "10010011000", "10010001100", "10001001100", "10011001000", "10011000100", "10001100100", "11001001000",
209 "11001000100", "11000100100", "10110011100", "10011011100", "10011001110", "10111001100", "10011101100", "10011100110", "11001110010", "11001011100",
210 "11001001110", "11011100100", "11001110100", "11101101110", "11101001100", "11100101100", "11100100110", "11101100100", "11100110100", "11100110010",
211 "11011011000", "11011000110", "11000110110", "10100011000", "10001011000", "10001000110", "10110001000", "10001101000", "10001100010", "11010001000",
212 "11000101000", "11000100010", "10110111000", "10110001110", "10001101110", "10111011000", "10111000110", "10001110110", "11101110110", "11010001110",
213 "11000101110", "11011101000", "11011100010", "11011101110", "11101011000", "11101000110", "11100010110", "11101101000", "11101100010", "11100011010",
214 "11101111010", "11001000010", "11110001010", "10100110000", "10100001100", "10010110000", "10010000110", "10000101100", "10000100110", "10110010000",
215 "10110000100", "10011010000", "10011000010", "10000110100", "10000110010", "11000010010", "11001010000", "11110111010", "11000010100", "10001111010",
216 "10100111100", "10010111100", "10010011110", "10111100100", "10011110100", "10011110010", "11110100100", "11110010100", "11110010010", "11011011110",
217 "11011110110", "11110110110", "10101111000", "10100011110", "10001011110", "10111101000", "10111100010", "11110101000", "11110100010", "10111011110",
218 "10111101110", "11101011110", "11110101110", "11010000100", "11010010000", "11010011100"
219 };
220         private const string Code128Stop = "11000111010", Code128End = "11"; //固定码尾
221         private enum Code128ChangeModes { CodeA = 101, CodeB = 100, CodeC = 99 }; //变更
222         private enum Code128StartModes { CodeUnset = 0, CodeA = 103, CodeB = 104, CodeC = 105 };//各类编码的码头
223 
224         /// <summary>
225         /// 绘制Code128码(以像素为单位)
226         /// </summary>
227         public int EncodeBarcode(string code, System.Drawing.Graphics g, int x, int y, int width, int height, bool showText)
228         {
229             if (string.IsNullOrEmpty(code)) new Exception("条码不能为空");
230             List<int> encoded = CodetoEncoded(code); //1.拆分转义
231             encoded.Add(CheckDigitCode128(encoded)); //2.加入校验码
232             string encodestring = EncodeString(encoded); //3.编码
233 
234             if (showText) //计算文本的大小,字体占图像的1/4高
235             {
236                 Font font = new System.Drawing.Font("宋体", height / 4F, System.Drawing.FontStyle.Regular, GraphicsUnit.Pixel, ((byte)(0)));
237                 SizeF size = g.MeasureString(code, font);
238                 height = height - (int)size.Height;
239 
240                 int _StarWidth = (width - (int)size.Width) / 2;
241                 g.DrawString(code, font, System.Drawing.Brushes.Black, _StarWidth, height);
242                 int w = DrawBarCode(g, encodestring, x, y, width, height); //4.绘制
243                 return ((int)size.Width > w ? (int)size.Width : w);
244             }
245             else
246                 return DrawBarCode(g, encodestring, x, y, width, height); //4.绘制
247         }
248 
249         //1.检测并将字符串拆分并加入码头
250         private List<int> CodetoEncoded(string code)
251         {
252             List<int> encoded = new List<int>();
253             int type = 0;//2:B类,3:C类
254             for (int i = 0; code.Length > 0; i++)
255             {
256                 int k = isNumber(code);
257                 if (k >= 4) //连续偶个数字可优先使用C类(其实并不定要转C类,但能用C类时条码会更短)
258                 {
259                     if (type == 0) encoded.Add((int)Code128StartModes.CodeC); //加入码头
260                     else if (type != 3) encoded.Add((int)(Code128ChangeModes.CodeC)); //转义
261                     type = 3;
262                     for (int j = 0; j < k; j = j + 2) //两位数字合为一个码身
263                     {
264                         encoded.Add(Int32.Parse(code.Substring(0, 2)));
265                         code = code.Substring(2);
266                     }
267                 }
268                 else
269                 {
270                     if ((int)code[0] < 32 || (int)code[0] > 126) throw new Exception("字符串必须是数字或字母");
271                     if (type == 0) encoded.Add((int)Code128StartModes.CodeB); //加入码头
272                     else if (type != 2) encoded.Add((int)(Code128ChangeModes.CodeB)); //转义
273                     type = 2;
274                     encoded.Add((int)code[0] - 32);//字符串转为ASCII-32
275                     code = code.Substring(1);
276                 }
277             }
278             return encoded;
279         }
280         //2.校验码
281         private int CheckDigitCode128(List<int> encoded)
282         {
283             int check = encoded[0];
284             for (int i = 1; i < encoded.Count; i++)
285                 check = check + (encoded[i] * i);
286             return (check % 103);
287         }
288 
289         //2.编码(对应Code128Encoding数组)
290         private string EncodeString(List<int> encoded)
291         {
292             string encodedString = "";
293             for (int i = 0; i < encoded.Count; i++)
294             {
295                 encodedString += Code128Encoding[encoded[i]];
296             }
297             encodedString += Code128Stop + Code128End; // 加入结束码
298             return encodedString;
299         }
300 
301         //4.绘制条码(返回实际图像宽度)
302         private int DrawBarCode(System.Drawing.Graphics g, string encodeString, int x, int y, int width, int height)
303         {
304             int w = width / encodeString.Length;
305             for (int i = 0; i < encodeString.Length; i++)
306             {
307                 g.FillRectangle(encodeString[i] == '0' ? System.Drawing.Brushes.White : System.Drawing.Brushes.Black, x, y, w, height);
308                 x += w;
309             }
310             return w * (encodeString.Length + 2);
311         }
312         //检测是否连续偶个数字,返回连续数字的长度
313         private int isNumber(string code)
314         {
315             int k = 0;
316             for (int i = 0; i < code.Length; i++)
317             {
318                 if (char.IsNumber(code[i]))
319                     k++;
320                 else
321                     break;
322             }
323             if (k % 2 != 0) k--;
324             return k;
325         }
326 
327         /// <summary>
328         /// 绘制Code128码到图片
329         /// </summary>
330         public Image EncodeBarcode(string code, int width, int height, bool showText)
331         {
332             Bitmap image = new Bitmap(width, height);
333             using (Graphics g = Graphics.FromImage(image))
334             {
335                 g.Clear(Color.White);
336                 int w = EncodeBarcode(code, g, 0, 0, width, height, showText);
337 
338                 Bitmap image2 = new Bitmap(w, height); //剪切多余的空白;
339                 using (Graphics g2 = Graphics.FromImage(image2))
340                 {
341                     g2.DrawImage(image, 0, 0);
342                     return image2;
343                 }
344 
345             }
346 
347         }
348 
349         /// <summary>
350         /// 绘制Code128码到流
351         /// </summary>
352         public byte[] EncodeBarcodeByte(string code, int width, int height, bool showText)
353         {
354             Image image = EncodeBarcode(code, width, height, showText);
355             System.IO.MemoryStream ms = new System.IO.MemoryStream();
356             image.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
357             byte[] byteImage = ms.ToArray();
358             ms.Close();
359             image.Dispose();
360             return byteImage;
361 
362         }
363     }
364 }
View Code
 1 <div>
 2         <table>
 3             <tr>
 4                 <td>条码:</td>
 5                 <td>
 6                     <textarea id="barCode"></textarea><br />
 7                     <span style="color: #ccc;">动态生成条码,生成多条码使用“,”号分隔。</span>
 8                 </td>
 9             </tr>
10             <tr>
11                 <td></td>
12                 <td>
13                     <a id="btnCreate">生成</a>
14                 </td>
15             </tr>
16         </table>
17 </div>
View Code
 1 $("#btnCreate").click(function () {
 2             var barCode = $("#barCode").val();
 3             if (barCode != "" && barCode != null) {
 4                 $("#print").html("");
 5                 var imgStr = "";
 6                 if (barCode.indexOf(",") > -1) {
 7                     var code = barCode.split(",");
 8                     $.each(code, function (index, value) {
 9                         if (value != "" && value != null) {
10                             imgStr += "<div><img src='/BaseData/CreateBarCode?code=" + value + "'/></div>";
11                         }
12                     });
13                 }
14                 else {
15                     imgStr = "<div><img src='/BaseData/CreateBarCode?code=" + barCode + "'/></div>";
16                 }
17                 
18                 $("#print").append(imgStr);
19             }
20             else {
21                 alert("条码不能为空!");
22             }
23         });
View Code
 1 public ActionResult CreateBarCode(string code)
 2         {
 3             JXUtil.BarCode barcode = new JXUtil.BarCode();
 4             barcode.Text = code;
 5             barcode.Height = 80;
 6             barcode.Magnify = 1;
 7             barcode.ViewFont = new Font("宋体", 20);
 8             System.Drawing.Image codeImage = barcode.GetCodeImage(JXUtil.BarCode.Code39Model.Code39Normal, true);
 9 
10             System.IO.MemoryStream ms = new System.IO.MemoryStream();
11             codeImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
12 
13             Response.ContentType = "image/jpeg";
14             Response.Clear();
15             Response.BinaryWrite(ms.ToArray());
16 
17             return new EmptyResult();
18         }
View Code
原文地址:https://www.cnblogs.com/flywing/p/5641287.html