winform程序生成条形码并且并且保存到本地文件中。
今天公司让做一个输入数字、字母生成条形码并且可以以图片格式保存到本地。当看到这个需求时候感觉很搞笑,明明可以用文本框搞定的东西非得做个程序。哎,寄人篱下,不多说了,这就是养兵千日用兵一时。
我在网上找了很多资料,在最终得出的结论就是电脑必须安装有code39/code 128 字体。具体下载地址我就不说,网上很多。我们以code 128 为例开始操作。
首先我们创建一个winform工程,然后通过拖拽方式进行设计界面(第一次创建winform程序,不知道有没有人自己手敲界面,心好累)界面如下:

上下的控件就不解释了,中间我拖拽的是picturebox控件,这个控件用于显示生成的条形码。
代码部分,首先我先创建了一个类Code39,具体代码如下:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
public sealed class Code39
{
    #region private variables
    /// <summary> 
    /// The Space Between each of Title, BarCode, BarCodeString 
    /// </summary> 
    private const int SPACE_HEIGHT = 3;
    SizeF _sizeLabel = SizeF.Empty;
    SizeF _sizeBarCodeValue = SizeF.Empty;
    SizeF _sizeBarCodeString = SizeF.Empty;
    #endregion
    #region Label
    private string _label = null;
    private Font _labelFont = null;
    /// <summary> 
    /// BarCode Title (条码标签) 
    /// </summary> 
    public string Label
    {
        set { _label = value; }
    }
    /// <summary> 
    /// BarCode Title Font (条码标签使用的字体) 
    /// </summary> 
    public Font LabelFont
    {
        get
        {
            if (_labelFont == null)
                return new Font("Code 128", 10);
            return _labelFont;
        }
        set { _labelFont = value; }
    }
    #endregion
    private string _additionalInfo = null;
    private Font _addtionalInfoFont = null;
    /// <summary> 
    /// Additional Info Font (附加信息字体) 
    /// </summary> 
    public Font AdditionalInfoFont
    {
        set { _addtionalInfoFont = value; }
        get
        {
            if (_addtionalInfoFont == null) return new Font("Code 128", 10);
            return _addtionalInfoFont;
        }
    }
    /// <summary> 
    /// Additional Info Content, if "ShowBarCodeValue" is true, the info is unvisible 
    /// 附加信息,如果设置ShowBarCodeValue为true,则此项不显示 
    /// </summary> 
    public string AdditionalInfo
    {
        set { _additionalInfo = value; }
    }
    #region BarCode Value and Font
    private string _barCodeValue = null;
    /// <summary> 
    /// BarCode Value (条码值) 
    /// </summary> 
    public string BarCodeValue
    {
        get
        {
            if (string.IsNullOrEmpty(_barCodeValue))
                throw new NullReferenceException("这个条形码不能进行设置!");
            return _barCodeValue;
        }
        set { _barCodeValue = value.StartsWith("*") && value.EndsWith("*") ? value : "*" + value + "*"; }
    }
    private bool _showBarCodeValue = false;
    /// <summary> 
    /// whether to show the original string of barcode value bellow the barcode 
    /// 是否在条码下方显示条码值,默认为false 
    /// </summary> 
    public bool ShowBarCodeValue
    {
        set { _showBarCodeValue = value; }
    }
    private Font _barCodeValueFont = null;
    /// <summary> 
    /// the font of the codestring to show 
    /// 条码下方显示的条码值的字体 
    /// </summary> 
    public Font BarCodeValueFont
    {
        get
        {
            if (_barCodeValueFont == null)
                return new Font("Code 128", 50);
            return _barCodeValueFont;
        }
        set { _barCodeValueFont = value; }
    }
    private int _barCodeFontSize = 50;
    /// <summary> 
    /// the font size of the barcode value to draw 
    /// 条码绘制的大小,默认50 
    /// </summary> 
    public int BarCodeFontSzie
    {
        set { _barCodeFontSize = value; }
    }
    #endregion
    #region generate the barcode image
    private Bitmap BlankBackImage
    {
        get
        {
            int barCodeWidth = 0, barCodeHeight = 0;
            using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    if (!string.IsNullOrEmpty(_label))
                    {
                        _sizeLabel = g.MeasureString(_label, LabelFont);
                        barCodeWidth = (int)_sizeLabel.Width;
                        barCodeHeight = (int)_sizeLabel.Height + SPACE_HEIGHT;
                    }
                    _sizeBarCodeValue = g.MeasureString(BarCodeValue, new Font("Free 3 of 9 Extended", _barCodeFontSize));
                    barCodeWidth = Math.Max(barCodeWidth, (int)_sizeBarCodeValue.Width);
                    barCodeHeight += (int)_sizeBarCodeValue.Height;
                    if (_showBarCodeValue)
                    {
                        _sizeBarCodeString = g.MeasureString(_barCodeValue, BarCodeValueFont);
                        barCodeWidth = Math.Max(barCodeWidth, (int)_sizeBarCodeString.Width);
                        barCodeHeight += (int)_sizeBarCodeString.Height + SPACE_HEIGHT;
                    }
                    //else 
                    //{ 
                    // if (!string.IsNullOrEmpty(_additionalInfo)) 
                    // { 
                    // _sizeAdditionalInfo = g.MeasureString(_additionalInfo, AdditionalInfoFont); 
                    // barCodeWidth = Math.Max(barCodeWidth, (int)_sizeAdditionalInfo.Width); 
                    // barCodeHeight += (int)_sizeAdditionalInfo.Height + SPACE_HEIGHT; 
                    // } 
                    //} 
                }
            }
            return new Bitmap(barCodeWidth, barCodeHeight, PixelFormat.Format32bppArgb);
        }
    }
    #region 获取条形码的格式。
    /// <summary>
    /// 获取128B的条形码
    /// </summary>
    /// <param name="inputData"></param>
    public string GetCode128B(string inputData)
    {
        string result = "";
        int checksum = 104;
        for (int ii = 0; ii < inputData.Length; ii++)
        {
            if (inputData[ii] >= 32)
            {
                checksum += (inputData[ii] - 32) * (ii + 1);
            }
            else
            {
                checksum += (inputData[ii] + 64) * (ii + 1);
            }
        }
        checksum = checksum % 103;
        if (checksum < 95)
        {
            checksum += 32;
        }
        else
        {
            checksum += 100;
        }
        result = Convert.ToChar(204) + inputData.ToString() + Convert.ToChar(checksum) + Convert.ToChar(206);
        return result;
}
    /// <summary>
    /// 获取128A 的条形码
    /// </summary>
    /// <param name="inputData"></param>
    /// <returns></returns>
    public string GetCode128A(string inputData)
    {
        string result = "";
        int checksum = 103;
        int j = 1;
        for (int ii = 0; ii < inputData.Length; ii++)
        {
            if (inputData[ii] >= 32)
            {
                checksum += (inputData[ii] - 32) * (ii + 1);
            }
            else
            {
                checksum += (inputData[ii] + 64) * (ii + 1);
            }
        }
        checksum = checksum % 103;
        if (checksum < 95)
        {
            checksum += 32;
        }
        else
        {
            checksum += 100;
        }
        result = Convert.ToChar(203) + inputData.ToString() + Convert.ToChar(checksum) + Convert.ToChar(206);
        return result;
    }
    /// <summary>
    /// 获取128C的条形码
    /// </summary>
    /// <param name="inputData"></param>
    /// <returns></returns>
    public static string GetCode128C(string inputData)
    {
        string result = "";
        int checksum = 105;
        int j = 1;
        for (int ii = 0; ii < inputData.Length; ii++)
        {
            if (ii % 2 == 0)
            {
                checksum += Convert.ToInt32(inputData.Substring(ii, 2)) * j;
                if (Convert.ToInt32(inputData.Substring(ii, 2)) < 95)
                {
                    result += Convert.ToChar(Convert.ToInt32(inputData.Substring(ii, 2)) + 32);
                }
                else
                {
                    result += Convert.ToChar(Convert.ToInt32(inputData.Substring(ii, 2)) + 100);
                }
                j++;
            }
            ii++;
        }
        checksum = checksum % 103;
        if (checksum < 95)
        {
            checksum += 32;
        }
        else
        {
            checksum += 100;
        }
        result = Convert.ToChar(205) + result + Convert.ToChar(checksum) + Convert.ToChar(206);
        return result;
    }
#endregion
/// <summary> 
    /// Draw the barcode value to the blank back image and output it to the browser 
    /// 绘制WebForm形式的条码 
    /// </summary> 
    /// <param name="ms">Recommand the "Response.OutputStream" 使用 Response.OutputStream</param> 
    /// <param name="imageFormat">The Image format to the Browser 输出到浏览器到图片格式,建议GIF</param> 
    public Bitmap CreateWebForm(Stream ms, ImageFormat imageFormat)
    {
        int barCodeWidth, barCodeHeight;
        using (Bitmap bmp = this.BlankBackImage)
        {
            barCodeHeight = bmp.Height;
            barCodeWidth = bmp.Width;
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(Color.White);
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                int vPos = 0;
                ////Draw Label String 
                if (!string.IsNullOrEmpty(_label))
                {
                    g.DrawString(_label, LabelFont, new SolidBrush(Color.Black),
                    XCenter((int)_sizeLabel.Width, barCodeWidth), vPos);
                    vPos += (int)_sizeLabel.Height + SPACE_HEIGHT;
                }
                else { vPos = SPACE_HEIGHT; }
                ////Draw The Bar Value 
                g.DrawString(_barCodeValue, new Font("Free 3 of 9 Extended", _barCodeFontSize), new SolidBrush(Color.Black),
                XCenter((int)_sizeBarCodeValue.Width, barCodeWidth), vPos);
                ////Draw the BarValue String 
                if (_showBarCodeValue)
                {
                    g.DrawString(_barCodeValue, BarCodeValueFont, new SolidBrush(Color.Black),
                    XCenter((int)_sizeBarCodeString.Width, barCodeWidth),
                    vPos + (int)_sizeBarCodeValue.Height);
                }
                //else 
                //{ 
                // if (!string.IsNullOrEmpty(_additionalInfo)) 
                // { 
                // g.DrawString(_additionalInfo, AdditionalInfoFont, new SolidBrush(Color.Black), 
                // XCenter((int)_sizeAdditionalInfo.Width, barCodeWidth), 
                // vPos + (int)_sizeBarCodeValue.Height); 
                // } 
                //} 
            }
            bmp.Save(ms, imageFormat);
            return bmp;
        }
    }
    /// <summary> 
    /// 生成winform格式的条码 
    /// </summary> 
    /// <param name="imageFormat">图片格式,建议GIF</param> 
    /// <returns>Stream类型</returns> 
    public Stream CreateWinForm(ImageFormat imageFormat)
    {
        int barCodeWidth, barCodeHeight;
        using (Bitmap bmp = this.BlankBackImage)
        {
            barCodeHeight = bmp.Height;
            barCodeWidth = bmp.Width;
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(Color.White);
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                int vPos = 0;
                ////Draw Label String 
                if (!string.IsNullOrEmpty(_label))
                {
                    g.DrawString(_label, LabelFont, new SolidBrush(Color.Black),
                    XCenter((int)_sizeLabel.Width, barCodeWidth), vPos);
                    vPos += (int)_sizeLabel.Height + SPACE_HEIGHT;
                }
                else { vPos = SPACE_HEIGHT; }
                ////Draw The Bar Value 
                g.DrawString(_barCodeValue, new Font("Free 3 of 9 Extended", _barCodeFontSize), new SolidBrush(Color.Black),
                XCenter((int)_sizeBarCodeValue.Width, barCodeWidth), vPos);
                ////Draw the BarValue String 
                if (_showBarCodeValue)
                {
                    g.DrawString(_barCodeValue, BarCodeValueFont, new SolidBrush(Color.Black),
                    XCenter((int)_sizeBarCodeString.Width, barCodeWidth),
                    vPos + (int)_sizeBarCodeValue.Height);
                }
                //else 
                //{ 
                // //if (!string.IsNullOrEmpty(_additionalInfo)) 
                // //{ 
                // // g.DrawString(_additionalInfo, AdditionalInfoFont, new SolidBrush(Color.Black), 
                // // //XCenter((int)_sizeAdditionalInfo.Width, barCodeWidth), 
                // // vPos + (int)_sizeBarCodeValue.Height); 
                // //} 
                //} 
            }
            Stream ms = new MemoryStream();
            bmp.Save(ms, imageFormat);
            return ms;
        }
    }
    #endregion
    private static int XCenter(int subWidth, int globalWidth)
    {
        return (globalWidth - subWidth) / 2;
    }
}
#endregion
这是从网上找的一段代码,感觉挺高大上,而且比我之前写的简易的调整起来方便 简易代码也张贴一下,但是我不建议用它,因为个人感觉不方便没上边的那段代码好用,因为上边的还可以在web段进行调用,专门有web段调用的方法。我写的这个可以直接在程序中使用,不需要重新创建类。
Bitmap b=new Bitmap(,);
Graphics g = Graphics.FromImage(b);
Font font = new Font("Code39AzaleaRegular2", );
g.DrawString("", font, Brushes.Black, new PointF(,));
pictureBox1.BackgroundImage = b;
pictureBox1.BackgroundImageLayout = ImageLayout.Zoom
对了说到web端调用生成条形码方法,顺便张贴一下web调用的方法:
// 新建一个.aspx文件
protected void Page_Load(object sender, EventArgs e)
{
Code39 code39 = new Code39();
code39.BarCodeValue = "LDSO-001";
code39.BarCodeFontSzie = ;
// code39.Label = "39码,底部显示码值";
code39.ShowBarCodeValue = true;
Response.Write(code39.CreateWebForm(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif));
code39 = null;
}
生成条形码按钮的click事件代码如下:
// 获取文本框内容
string barCode = tb_barcode.Text;
Code39 code39 = new Code39();
barCode = code39.GetCode128B(barCode);
code39.BarCodeValue = barCode;
code39.BarCodeFontSzie = 10;
// code39.Label = barCode; 
            code39.ShowBarCodeValue = true;
            // 将生成的条形码存放到picturebox控件的image中
            pic_show.Image = Image.FromStream(code39.CreateWinForm(System.Drawing.Imaging.ImageFormat.Gif));
此时当我们运行程序,并输入正规生成条形码的字段(具体要求请参考度娘所说的),点击生成条形码按钮(之前图片是确定按钮,怕误导大家所以就在粘贴图片时候又更改了名字)时候我们就可以看到这样的情形,如图所示:
  看到这一步的时候我就觉得很叼了,然后就是保存图片功能了,保存图片时候就是大神们常常强调的要注重客户体验,所以我们需要让图片保存时候可以让用户进行选择存放位置,代码如下:
if (pic_show.Image != null)
{
// 点击保存时候弹出本地窗口进行图片保存 SaveFileDialog sfd = new SaveFileDialog();
// 设置文件数据类型
sfd.Filter = "数据保存文件(*.jpg)|*.jpg|数据保存文件(*.png)|*.png|数据保存文件(*.bmp)|*.bmp";
// 设置默认文件类型顺序
sfd.FilterIndex = ; // 保存对话框是否记忆上一次打开的路径
sfd.RestoreDirectory = true;
//
if (sfd.ShowDialog() == DialogResult.OK)
{
string localFilePath = sfd.FileName.ToString(); //获得文件路径 string fileNameExt = localFilePath.Substring(localFilePath.LastIndexOf("//") + ); //获取文件名,不带路径 Bitmap bmp = new Bitmap(pic_show.Image);
// 保存文件到指定流
bmp.Save(localFilePath); }
}
相信上边的代码基本上不用有过多的解释,已经那么多注释了,另外我真心需要强调一下注释,哎。。。被这家新公司弄的心好累,那么大的项目里边居然只有寥寥无几的注释,而且写这个项目的大神已经离职了。。。心中策马奔腾。。。。直接上图,


winform程序生成条形码并且并且保存到本地文件中。的更多相关文章
- Python3.4 获取百度网页源码并保存在本地文件中
		
最近学习python 版本 3.4 抓取网页源码并且保存在本地文件中 import urllib.request url='http://www.baidu.com' #上面的url一定要写明确,如果 ...
 - 爬虫任务二:爬取(用到htmlunit和jsoup)通过百度搜索引擎关键字搜取到的新闻标题和url,并保存在本地文件中(主体借鉴了网上的资料)
		
采用maven工程,免着到处找依赖jar包 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&quo ...
 - 性能测试,如何得到大量token,并保存在本地文件中
		
需求:性能测试需要大量的token,模拟登陆 设计思路: 1.使用语言:python +request+正则匹配+写入本地 2.jmeter+函数助手+正则或者json/yaml+后置处理器beans ...
 - 如何将Python对象保存在本地文件中?
		
Python对象的永久存储 1.使用Python的pickle模块 import pickle class A: def __init__(self,name,a): self.name=name s ...
 - Python3读取网页HTML代码,并保存在本地文件中
		
旧版Python中urllib模块内有一个urlopen方法可打开网页,但新版python中没有了,新版的urllib模块里面只有4个子模块(error,request,response,parse) ...
 - Java序列化bean保存到本地文件中
		
File file = new File("D:\\softTemp\\student.out"); ObjectOutputStream objectOutputStream = ...
 - Java读取oracle数据库中blob字段数据文件保存到本地文件(转载)
		
转自:https://www.cnblogs.com/forever2698/p/4747349.html package com.bo.test; import java.io.FileOutput ...
 - 【Jmeter】jmeter提取response中的返回值,并保存到本地文件--BeanShell后置处理器
		
有个需求,需要在压测环境中,创建几十万的账号数据,然后再根据创建结果,查询到某些账号信息. 按照之前我的做法,直接Python调用API,然后再数据库查询: 但是近期所有开发人员的数据库访问权限被限制 ...
 - .NET 扩展 官方 Logger 实现将日志保存到本地文件
		
.NET 项目默认情况下 日志是使用的 ILogger 接口,默认提供一下四种日志记录程序: 控制台 调试 EventSource EventLog 这四种记录程序都是默认包含在 .NET 运行时库中 ...
 
随机推荐
- Luogu4609 FJOI2016建筑师(斯特林数)
			
显然排列中的最大值会将排列分成所能看到的建筑不相关的两部分.对于某一边,将所能看到的建筑和其遮挡的建筑看成一个集合.显然这个集合内最高的要排在第一个,而剩下的建筑可以随便排列,这相当于一个圆排列.同时 ...
 - day 变量的赋值原理 变量的命名规则
			
print(3*4*5*6/2) #简单的计算输出 x=3 y=4 print("x乘以y=",x*y) #运行5分钟 = 12 print(x*y) #在运行5分钟 = 12 ' ...
 - LOJ #2540. 「PKUWC 2018」随机算法(概率dp)
			
题意 LOJ #2540. 「PKUWC 2018」随机算法 题解 朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 ...
 - 自学工业控制网络之路2.2-PROFINET
			
返回 自学工业控制网络之路 自学工业控制网络之路2.2-PROFINET PROFINET由PROFIBUS国际组织(PROFIBUS International,PI)推出,是新一代基于工业以太网技 ...
 - 学习Spring Boot:(二十八)Spring Security 权限认证
			
前言 主要实现 Spring Security 的安全认证,结合 RESTful API 的风格,使用无状态的环境. 主要实现是通过请求的 URL ,通过过滤器来做不同的授权策略操作,为该请求提供某个 ...
 - 【洛谷P1858】多人背包
			
题目大意:求解 0-1 背包前 K 优解的和. 题解:首先,可知对于状态 \(dp[j]\) 来说,能够转移到该状态的只有 \(dp[j],dp[j-w[i]]\).对于 K 优解来说,只需对状态额外 ...
 - 再次膜拜IE的超强兼容性
			
今天用firefox和chrome打开几年前写的一个网页,突然发现复选框的“全选”功能失效了. 然后用ie试了一下,竟然正常. 到firefox的错误控制台查看,提示错误: TypeError: id ...
 - 多线程状态下调用SimpleDateFormat.format()抛出 ArrayIndexOutOfBoundsException 异常
			
本来想在类的顶部设置一个 静态的SimpleDateFormat常量 public final static DateFormat dateFormatGMT = new SimpleDateForm ...
 - 智能指针unique_ptr
			
转自:https://www.cnblogs.com/DswCnblog/p/5628195.html 成员函数 (1) get 获得内部对象的指针, 由于已经重载了()方法, 因此和直接使用对象是一 ...
 - 有趣的electron(一)
			
跟我一起实现一个基于electron的hello-world吧- Come with me to implement an electron-based project hello-world. 先看 ...