本文主要介绍.NET(C#)中,使用BarcodeLib生成条码图片,并通过GDI+绘图(Graphics)实现打印带有条码的小票,以及相关的示例代码。

1、BarcodeLib引用及示例代码

下面文档中是.NET Core中的,.NET中也是差不多的代码及引用方法。

文档:.NET Core(C#)使用BarcodeLib生成条码图片数据及示例代码

2、生成带条码小票及打印代码

        #region 打印
        /// <summary>
        /// 打印字符串内容
        /// </summary>
        /// <returns></returns>
        public string GetPrintStr()
        {
            StringBuilder sb = new StringBuilder();
            int intLenMax = 16;
            if (!isScan)
            {
                intLenMax = 28;
            }
            sb.Append("名称:" + AutomaticLine(printGoods.goodsName.Trim(), 1, intLenMax));
            sb.Append("价格:" + printGoods.retailPrice + "元\r\n");
            return sb.ToString();
        }
        /// <summary>
        /// 打印条形码图片
        /// 在生成条形码时,大小是不可以任意放大的,那么我们如果想任意改变条形码大小
        /// 思路:
        /// 1.把条形码生成为图片
        /// 2.改变条形码图片的大小就可以了
        /// </summary>
        /// <returns></returns>
        public System.Drawing.Image GetPrintImage()
        {
            BarcodeLib.Barcode b = new BarcodeLib.Barcode();
            //设置条形码宽度和高度
            int W = Convert.ToInt32(250);
            int H = Convert.ToInt32(80);
            //对齐方式:默认居中
            b.Alignment = BarcodeLib.AlignmentPositions.CENTER;
            //条码格式
            BarcodeLib.TYPE type = BarcodeLib.TYPE.CODE128;
            //显示生成条形码的内容
            b.IncludeLabel = true;
            b.RotateFlipType = RotateFlipType.RotateNoneFlipNone;
            //生成条形码内容的位置
            b.LabelPosition = BarcodeLib.LabelPositions.BOTTOMCENTER;
            System.Drawing.Font font = new System.Drawing.Font("verdana", 8f);//字体设置
            b.LabelFont = font;
            //b.Encode(条形码格式,要生成条形码的内容,条形码颜色,条形码背景色,宽度,高度)
            System.Drawing.Image image = b.Encode(type, printGoods.goodsShopId, System.Drawing.Color.Black, System.Drawing.Color.White, W, H);
            return image;
        }
        private void PrintStat()
        {
            PrintDocument pd = new PrintDocument();
            //设置去除打印提示
            PrintController printController = new StandardPrintController();
            pd.PrintController = printController;
            //设置默认打印机
            if (pd.PrinterSettings.PrinterName != PrinterName.BarCode)
                Printer.ChangeDefaultPrinter(PrinterName.BarCode);
            //设置边距
            Margins margin = new Margins(0, 3, 20, 10);
            pd.DefaultPageSettings.Margins = margin;
            //纸张设置默认
            PaperSize pageSize = new PaperSize("First custom size", getYc(104), 150);
            pd.DefaultPageSettings.PaperSize = pageSize;
            //打印事件设置           
            pd.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
            try
            {
                pd.Print();
            }
            catch (Exception ex)
            {
                InformaticaDialog information = new InformaticaDialog("打印失败", ex.Message);
                information.Owner = this;
                information.ShowDialog();
            }
        }
        private int getYc(double cm)
        {
            return (int)(cm / 25.4) * 203;
        }
        private void pd_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            SetInvoiceData(e.Graphics);
        }
        private void SetInvoiceData(Graphics g)
        {
            SolidBrush GrayBrush = new SolidBrush(System.Drawing.Color.Black);
            Font InvoiceFont = new Font("Arial", 8, System.Drawing.FontStyle.Regular);
            g.DrawString(GetPrintStr(), InvoiceFont, GrayBrush, 100, 10);
            //这个主要目的是要放到条形
            g.DrawImage(GetPrintImage(), 10, 60, 400, 80);
            g.Dispose();
        } 
        #endregion
        #region 打印字符串自动换行
        /// <summary>    
        /// 处理字符串自动换行问题。最短为intLenMin,最长为intLenMax。
        /// </summary>    
        /// <param name="strOldText">原字符串</param>    
        /// <param name="intLenMin">最短字节长度</param>    
        /// <param name="intLenMax">最长字节长度</param>    
        /// <returns>string</returns>    
        /// <remarks></remarks>    
        public static string AutomaticLine(string strOldText, int intLenMin, int intLenMax)
        {
            int intLength = 0;
            string strResult = "";
            //获取原字符串的字节长度    
            intLength = System.Text.Encoding.GetEncoding("gb2312").GetByteCount(strOldText);
            if (intLength > intLenMax)
            {
                //总字节数> 最长截取的最长字节数,    
                //则截取最长字节数, 然后对剩余字符串再处理
                //获取字符串的UCS2码    
                byte[] bytes = System.Text.Encoding.Unicode.GetBytes(strOldText);
                //获取字符的实际截取位置    
                int intCutPos = RealCutPos(bytes, intLenMax);
                //采用递归调用    
                strResult = System.Text.Encoding.Unicode.GetString(bytes, 0, intCutPos * 2) + "\r\n" + AutomaticLine(strOldText.Substring(intCutPos), intLenMin, intLenMax);
            }
            else if (intLength > intLenMin)
            {
                //如果 最长字节数 >总字节数 > 最短字节数,则 换行,并补齐空格到最短字节数位置    
                strResult = strOldText + "\r\n";// +"".PadRight(intLenMin);
            }
            else
            {
                //如果 总字节数 < 最短字节数,则直接补齐空格到最短字节数的位置    
                strResult = strOldText;// +"".PadRight(intLenMin - intLength);
            }
            return strResult;
        }
        /// <summary>    
        /// 返回字符的实际截取位置    
        /// </summary>    
        /// <param name="bytes">UCS2码</param>    
        /// <param name="intLength">要截取的字节长度</param>    
        /// <returns></returns>    
        /// <remarks></remarks>    
        private static int RealCutPos(byte[] bytes, int intLength)
        {
            //获取UCS2编码    
            int intCountB = 0;
            // 统计当前的字节数     
            int intCutPos = 0;
            //记录要截取字节的位置      
            while ((intCutPos < bytes.GetLength(0) && intCountB < intLength))
            {
                // 偶数位置,如0、2、4等,为UCS2编码中两个字节的第一个字节    
                if (intCutPos % 2 == 0)
                {
                    // 在UCS2第一个字节时,字节数加1    
                    intCountB += 1;
                }
                else
                {
                    // 当UCS2编码的第二个字节大于0时,该UCS2字符为汉字,一个汉字算两个字节    
                    if (bytes[intCutPos] > 0)
                    {
                        intCountB += 1;
                    }
                }
                intCutPos += 1;
            }
            // 如果intCutPos为奇数时,处理成偶数      
            if (intCutPos % 2 == 1)
            {
                // 该UCS2字符是汉字时,去掉这个截一半的汉字    
                if (bytes[intCutPos] > 0)
                {
                    intCutPos = intCutPos - 1;
                }
                else
                {
                    // 该UCS2字符是字母或数字,则保留该字符    
                    intCutPos = intCutPos + 1;
                }
            }
            return intCutPos / 2;
        }
        #endregion

参考文档https://www.cnblogs.com/WarBlog/p/11190228.html