精华内容
下载资源
问答
  • 恒博进销存管理系统是一款专业的进销存管理软件,这款软件专为中小企业以及贸易管理企业精心打造,为用户提供产品管理、客户管理、月结管理、数据分析、图表分析等功能。  恒博进销存管理系统是2020年最新实用、...
  • 百惠仓库管理系统是以库存管理为中心,集销售送货、退货、采购、进出库管理,财务收款付款、应收应付统计和现金记账管理,产品资料、客户资料、客户对账,标签打印等
  • 一彩仓库管理系统,本软件根据市场需要结合企业自身特点量身定做的操作方便、功能完善功能强大个性化极强的仓库管理系统系统集送货管理,采购入库,生产入库,销售退货,采购退货,生产领料,财务管理等多种工作...
  • 在仓储系统的是使用过程中避免不了的是打印单据,仓库系统中包含很多单据:入库,出库,盘点,调拨,签收等等,而且还附带着很多的条码标签的打印。本文在此记录一下一个简单的打印问题处理方式。处理问题环境...

     

      在仓储系统的是使用过程中避免不了的是打印单据,仓库系统中包含很多单据:入库单,出库单,盘点单,调拨单,签收单等等,而且还附带着很多的条码标签的打印。本文在此记录一下一个简单的打印问题处理方式。处理问题环境如下:

    在做标签打印的时候,同事说要使用OPOS指令来打印小单据标签,但是后面送过来的打印机却是斑马打印机,不支持OPOS指令打印,于是很无奈。当时自己提出过另外一种解决方案,那就是使用第三方打印软件,然后使用.NET来调用这个软件打印,这个也是本人之前一直使用的打印方式,比较有名的第三方打印软件bartender. 但是的确这个实施不方便。于是自己使用了最原始用.NET PrintDocument 来打印输出。

     

      一. 打印需求

        1. 能够打印Logo,也就是打印图片

        2. 打印固定文字,并且能够控制文字大小

        3. 打印变量信息

        4. 打印列表信息

        5. 打印条码 二维码

        6. 打印纸张大小的控制

     

        以上是个人总结出来做单据打印的一些常用功能,也是比较实用的一些要求,相信做过打印单据的同学应该都遇到过。 在以上几点的需求上有几个比较麻烦的是打印列表,相对比较复杂。对于条码以及二维码的打印其实就是打印图片,使用相应的组件来生成图片打印即可。

     

      二. GDI+绘图打印

        不用多说,这个肯定是PrintDocument 打印的重点,可能一般做Web开发的同学对打印关注的较少,这里先说WinForm 客户端程序的打印,后续讲解Web上的打印问题。在博客园中搜索了一篇不错的文章介绍GDI画图

        《GDI+绘图》  可以查看了解一下GDI+绘图的基本知识

      

        PrintDocument 文档打印类中有一个Print()打印方法,用于触发打印,PrintPage 事件则在打印命令执行时触发,我们可以在这个事件的方法中绘图,用于实现要打印的内容。先看看一个简单的案例

    private void Print(object sender, System.Drawing.Printing.PrintPageEventArgs e)
            {
                int top = 5;
                int left = 4;
    
                Brush bru = Brushes.Black;
                Graphics g = e.Graphics;
    
                for (int i = 0; i < listResult.Count; i++)
                {
                    BarCodeEntity entity = listResult[i];
                    if (entity != null)
                    {
                        int xMo = i % 4;
                        int yMo = i / 4;
    
                        int width = 90;
                        int height = 79;
    
                        g.DrawString("合格证", new Font("黑体", 8, FontStyle.Bold), bru, new PointF(left + width * xMo + 22, height * yMo + top));
    
                        g.DrawString("本产品经检验合格准予出厂", new Font("黑体", 4.7f, FontStyle.Bold), bru, new PointF(left + width * xMo, height * yMo + 13 + top + 5));
                        g.DrawString("检验员:" + entity.Number + "号  保质期:三年", new Font("黑体", 4.7f, FontStyle.Bold), bru, new PointF(left + width * xMo, height * yMo + 26 + top + 5));
                        g.DrawString("生产日期:" + entity.Time, new Font("黑体", 4.7f, FontStyle.Bold), bru, new PointF(left + width * xMo, height * yMo + 39 + top + 5));
    
                        float length = 7f;
                        float fontWidth = entity.CompanyName.IsEmpty() ? 0 : length * (entity.CompanyName.Length * 1.0f);
    
                        float fontSize = 4.4f;
                        int marginLeft = 0;
                        if (entity.CompanyName.Length > 13)
                        {
                            fontSize = 4.0f;
                        }
                        else
                        {
                            marginLeft = (int)((91 - fontWidth) / 2);
                        }
                        g.DrawString(entity.CompanyName, new Font("黑体", fontSize, FontStyle.Bold), bru, new PointF(left + width * xMo + marginLeft, height * yMo + 52 + top + 5));
                    }
                }
    
            }
    打印绘图简单案例

         Brush bru = Brushes.Black;

         Graphics g = e.Graphics;

        以上两个是绘图的重点,定义了画笔以及绘图对象。在PrintPage事件中可以获得绘图对象,我们利用此对象来绘制图片,文字,条码,二维码等

    public void DrawImage(Image image, PointF point);
    
    public void DrawImageUnscaled(Image image, Point point);
    
    public void DrawLine(Pen pen, Point pt1, Point pt2);
    
    public void DrawPie(Pen pen, Rectangle rect, float startAngle, float sweepAngle);
    
    public void DrawRectangle(Pen pen, Rectangle rect);
    
    public void DrawString(string s, Font font, Brush brush, RectangleF layoutRectangle);

        以上是常用的一些绘图方法,绘制图片,直线,圆,方框,字符串等等。可以到微软MSDN官网查看更多的绘图方法

        

        以上是一个简单的打印示例,画图方式比较原始,但是包含了不同的文字,二维码图片等。

     

      三. PrintDocument使用的缺点

        以上代码打印出来,貌似效果还不错,在小标签纸上效果也挺漂亮.但是问题来了,有一天客户提出需求说,我现在要换打标签纸了,而且文字的排版方式也要稍微做修改。从上面的一段示例代码来看,打印无非就是输出内容(文字,线框,图片等). 然后就是定义响应的坐标即可,也就是点阵类型的打印。将标签纸作为一个画布,然后计算好坐标在相应的位置输出内容即可。 如果标签纸大小变了(排版),那么意味着坐标点也要重新计算,一下子是欲哭无泪。

     

        当时他们要求使用OPOS指令,ZPL指定也就是因为可以自定义模板.但是不同的打印机支持指令性质不一样,那就只能自己定义一套模板规则来满足要求,并且摆脱不同打印机厂商的限制。

    <?xml version="1.0" encoding="utf-8" ?>
    <Page Width="200" Heigth="700" DefaultPrinter="ZDesigner GK888t (EPL)">
      <Line Height="72">
        <Image Left="20" Top="30">{{Logo}}</Image>
      </Line>
      <Line Height="50">
        <Text Left="50" Top="2" FontSize="15">预定凭条</Text>
      </Line>
      <Line Height="30">
        <Text Left="15" Top="2" FontSize="16">保税区1店</Text>
      </Line>
      <Line Height="20">
        <Text Left="70" Top="2" FontSize="8">No.150 page.1</Text>
      </Line>
      <Line Height="70">
        <QRCode Left="20" Top="2" >{{OrderCode}}</QRCode>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="10">单据号:{{OrderCode}}</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="10">提货时间:{{DtReceive}}</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="10">提货点:{{ReceiveAddress}}</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="10">联系人:{{ReceiveUser}}</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="10">联系电话:{{ReceiverPhone}}</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="10">时间:{{DtCreate}}</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="18">-------------</Text>
      </Line>
      <Line Height="30">
        <Text Left="2" Top="2" FontSize="7">序号</Text>
        <Text Left="30" Top="2" FontSize="7">货号</Text>
        <Text Left="70" Top="2" FontSize="7">品名</Text>
    
        <Text Left="30" Top="17" FontSize="7">数量</Text>
        <Text Left="70" Top="17" FontSize="7">单价</Text>
        <Text Left="150" Top="17" FontSize="7">金额</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="18">-------------</Text>
      </Line>
    
      <Loop Values="Detials">
        <Line Height="30">
          <Text Left="2" Top="2" FontSize="7">{{Index}}</Text>
          <Text Left="30" Top="2" FontSize="7">{{StrID}}</Text>
          <Text Left="70" Top="2" FontSize="7">{{StrName}}</Text>
    
          <Text Left="30" Top="17" FontSize="7">{{DCount}}</Text>
          <Text Left="60" Top="17" FontSize="7">*</Text>
          <Text Left="70" Top="17" FontSize="7">{{DPrice}}</Text>
          <Text Left="140" Top="17" FontSize="7">=</Text>
          <Text Left="150" Top="17" FontSize="7">{{DAmount}}</Text>
        </Line>
      </Loop>
    
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="18">-------------</Text>
      </Line>
    
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="7">联机刷卡</Text>
        <Text Left="100" Top="2" FontSize="7">人民币{{DAmount}}</Text>
      </Line>
    
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="18">--------------</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="7">商品数:{{DCount}}</Text>
        <Text Left="100" Top="2" FontSize="7">总金额:{{DAmount}}</Text>
      </Line>
      <Line Height="70">
        <BarCode Left="20" Top="2" Width="100" Height="60">{{OrderCode}}</BarCode>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="18">--------------</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="7">谢谢惠顾,欢迎再次光临</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="7">提货凭据,请妥善保管</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="7">客服热线:*******</Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="7"></Text>
      </Line>
      <Line Height="20">
        <Text Left="2" Top="2" FontSize="7"></Text>
      </Line>
    </Page>
    模板定义预览

     

        为了尽快应付工作问题,在短时间仓促定义了如上模板,用于设置定义指令。以上模板主要内容是控制坐标点以及打印内容的动态体会:

        Page标签: 用于定义打印纸张, 属性:Width 纸张宽度, Heigth 纸张高度, DefaultPrinter 默认使用打印机的名称

        Line标签: 在打印过程中预定都是以行来打印,只是打印行坐标不一样(这样可以控制交叉的情况) 。 定义打印一行, Height 打印行的高度

        Image标签: 用于打印图片 Left 用于设置距离Line 左边的距离 Top 用于设置距离Line 顶部的距离,Image 必须包含到Line标签中。

        Text标签:用于打印文本信息  Left 用于设置距离Line 左边的距离 Top 用于设置距离Line 顶部的距离,FontSize 用于设置打印字体大小, Text必须包含到Line标签中。

        QRCode标签:用于打印二维码图片, Left 用于设置距离Line 左边的距离 Top 用于设置距离Line 顶部的距离

        BarCode标签:用于打印条码图片,Left 用于设置距离Line 左边的距离 Top 用于设置距离Line 顶部的距离.Width 设置条码的长度,Height 设置条码的高度

        Loop标签:用于循环打印,必须包含Line标签,也就是循环打印Line标签。Values 设置数据源的Key值

        {{}}指令:用于替换的变量占位符

     

        

        画了一个草图理解标签中的属性Left,Top. Line都是以纸张横坐标为0的前提下打印的,也就是说Left是以坐标X=0的情况为计算标准, 而Top 是以Line的内聚为标准,如果有多个Line 则需要先计算上层所有Line的高度总和才能定义Top的Y轴的值。

     

      四. 数据源的定义

        在上面的设计中利用到了占位符,这个也是比较合理的一种做法,在打印的过程中替换占位符中的内容。 在系统启动的时候回检测模板中的所有占位符。

        数据源的定义是以Dictionary<string, object> 为基础类型,为什么什么这么做,我在占位符 比如{{Logo}} 定义如上,我们就在Dictionary 查找LogoKey的值。然后将其中的内容值替换即可

        

        如果是Loop标签的数据源如何处理: 在Loop标签中定义了Values的属性,其属性值也就是Dictionary 中的key,查找得到之后仍然是一个List<Dictionary<string,object>>的数据值,这边便于循环和Key值得查找。

         

    dic = new Dictionary<string, object>();
                dic.Add("Logo", @"D:\222.jpg");
                dic.Add("OrderNO", "V3454596546565");
                dic.Add("Cashier", "菜霞");
                dic.Add("EndPoint", "634");
                dic.Add("Number", "120457");
                dic.Add("CreateTime", DateTime.Now.ToString("yyyy-MM0dd HH:mm:ss"));
                dic.Add("Amount", "65223.00");
                dic.Add("QRCode", "V3454596546565");
    
                List<Dictionary<string, object>> Info = new List<Dictionary<string, object>>()
                {
                    new Dictionary<string, object>() { { "No", "1"},{ "ProductNum", "120223"},{ "ProductName", "中华烟"},{ "Qty", "2"},{ "Price", "49"},{ "Amount", "98"} },
                    new Dictionary<string, object>() { { "No", "2"},{ "ProductNum", "565666"},{ "ProductName", "玻璃杯"},{ "Qty", "7"},{ "Price", "45"},{ "Amount", "45545"} },
                    new Dictionary<string, object>() { { "No", "3"},{ "ProductNum", "897845"},{ "ProductName", "烟灰缸"},{ "Qty", "5"},{ "Price", "2435"},{ "Amount", "67767"} },
                    new Dictionary<string, object>() { { "No", "4"},{ "ProductNum", "904395"},{ "ProductName", "茶几"},{ "Qty", "3"},{ "Price", "45245"},{ "Amount", "6767"} },
                };
                dic.Add("Qty", "5");
                dic.Add("TotalAmount", "1045.00");
                dic.Add("DiscountQty", "1");
                dic.Add("DiscountAmount", "40.00");
                dic.Add("Discount", "47.5");
                dic.Add("DiscountMon", "1958.00");
                dic.Add("List", Info);
    数据源基本格式

     

    public partial class DocumentPrintControl
        {
            public DocumentPrintControl() { }
    
            public DocumentPrintControl(string printName,string filePath,Dictionary<string,object> dataSource,bool isAutoHeigth)
            {
                this.PrintName = printName;
                this.FilePath = filePath;
                this.DataSource = dataSource;
                this.IsAutoHeigth = isAutoHeigth;
            }
    
            /// <summary>
            /// 打印机名称
            /// </summary>
            public string PrintName { get; set; }
    
            /// <summary>
            /// 打印模板路径
            /// </summary>
            public string FilePath { get; set; }
    
            /// <summary>
            /// 打印数据源
            /// </summary>
            public Dictionary<string, object> DataSource { get; set; }
    
            /// <summary>
            /// 是否自适应高度
            /// </summary>
            public bool IsAutoHeigth { get; set; }
    
            /// <summary>
            /// 打印Document
            /// </summary>
            private PrintDocument printDocument;
    
            /// <summary>
            /// 打印对话框
            /// </summary>
            private PrintDialog printDialog;
    
            /// <summary>
            /// XML解析文档
            /// </summary>
            private XDocument root;
    
            /// <summary>
            /// 初始化
            /// </summary>
            /// <returns></returns>
            public DocumentPrintControl Init()
            {
                this.printDialog = new PrintDialog();
                this.printDocument = new PrintDocument();
                this.printDialog.Document = this.printDocument;
                this.printDocument.PrintPage += PrintDocument_PrintPage;
    
                return this;
            }
    
            /// <summary>
            /// 设置数据源
            /// </summary>
            /// <param name="dataSource"></param>
            /// <returns></returns>
            public DocumentPrintControl SetDataSource(string fileName)
            {
                string line = string.Empty;
                this.DataSource = new Dictionary<string, object>();
                using (StreamReader reader = new StreamReader(fileName,Encoding.Default))
                {
                    List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
                    while ((line = reader.ReadLine()) != null)
                    {
                        Dictionary<string, object> dic = new Dictionary<string, object>();
                        dic.Add("Line", line);
                        list.Add(dic);
                    }
                    this.DataSource.Add("List", list);
                }
                return this;
            }
    
            /// <summary>
            /// 开始命令
            /// </summary>
            /// <returns></returns>
            public DocumentPrintControl Begin()
            {
                //打印模板
                if (!File.Exists(this.FilePath))
                {
                    throw new Exception("打印模板文件不存在");
                }
    
                this.root = XDocument.Load(this.FilePath);
    
                string strWidth = root.Element("Page").Attribute("Width").Value;
                string strHeigth = root.Element("Page").Attribute("Heigth").Value;
                strWidth = string.IsNullOrWhiteSpace(strWidth) ? "0" : strWidth;
                strHeigth = string.IsNullOrWhiteSpace(strHeigth) ? "0" : strHeigth;
                string DefaultPrinter = root.Element("Page").Attribute("DefaultPrinter").Value;
    
                //计算文档高度
                if (this.IsAutoHeigth)
                {
                    float PageHeith = 0;
                    foreach (XElement item in root.Element("Page").Elements())
                    {
                        if (item.Name == "Line")
                        {
                            float LineHeigth = string.IsNullOrWhiteSpace(item.Attribute("Height").Value) ? 0 : Convert.ToSingle(item.Attribute("Height").Value);
                            PageHeith += LineHeigth;
                        }
                        else if (item.Name == "Loop")
                        {
                            string Values = item.Attribute("Values").Value;
                            List<Dictionary<string, object>> listValues = this.DataSource[Values] as List<Dictionary<string, object>>;
                            if (listValues != null)
                            {
                                XElement lineItem = item.Element("Line");
                                float LineHeigth = string.IsNullOrWhiteSpace(lineItem.Attribute("Height").Value) ? 0 : Convert.ToSingle(lineItem.Attribute("Height").Value);
                                PageHeith += LineHeigth * listValues.Count();
                            }
                        }
                    }
                    strHeigth = (PageHeith + 10).ToString();
                }
    
                this.printDocument.DefaultPageSettings.PaperSize = new System.Drawing.Printing.PaperSize(string.Format("{0}*{1}", strWidth, strHeigth), Convert.ToInt32(strWidth), (int)Math.Ceiling(Convert.ToSingle(strHeigth)));
                this.printDocument.PrinterSettings.PrinterName = string.IsNullOrWhiteSpace(this.PrintName) ? DefaultPrinter : this.PrintName;
    
                return this;
            }
    
            /// <summary>
            /// 触发打印
            /// </summary>
            /// <returns></returns>
            public bool Print()
            {
                this.printDocument.Print();
                return true;
            }
    
            /// <summary>
            /// 打印触发事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
            {
                PrintTemplate(sender, e);
            }
    
    
            /// <summary>
            /// 打印模板 
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            /// <returns></returns>
            private void PrintTemplate(object sender, PrintPageEventArgs e)
            {
                Brush bru = Brushes.Black;
                Graphics g = e.Graphics;
    
                float totalHeight = 0;
                int rowIndex = 0;
    
                foreach (XElement item in root.Element("Page").Elements())
                {
                    if (item.Name == "Line")
                    {
                        float LineHeigth = string.IsNullOrWhiteSpace(item.Attribute("Height").Value) ? 0 : Convert.ToSingle(item.Attribute("Height").Value);
    
                        foreach (XElement child in item.Elements())
                        {
                            if (child.Name == "Text")
                            {
                                float Left = string.IsNullOrWhiteSpace(child.Attribute("Left").Value) ? 0 : Convert.ToSingle(child.Attribute("Left").Value);
                                float Top = string.IsNullOrWhiteSpace(child.Attribute("Top").Value) ? 0 : Convert.ToSingle(child.Attribute("Top").Value);
                                float FontSize = string.IsNullOrWhiteSpace(child.Attribute("FontSize").Value) ? 0 : Convert.ToSingle(child.Attribute("FontSize").Value);
    
                                Top = totalHeight + Top;
                                string content = child.Value;
                                if (content.Contains("{{") && content.Contains("}}"))
                                {
                                    int beginIndex = content.IndexOf("{{");
                                    int endIndex = content.LastIndexOf("}}");
                                    string key = content.Substring(beginIndex + 2, endIndex - beginIndex - 2);
                                    g.DrawString(content.Replace("{{" + key + "}}", this.DataSource[key].ToString()), new Font("宋体", FontSize, FontStyle.Bold), bru, new PointF(Left, Top));
                                }
                                else
                                {
                                    g.DrawString(content, new Font("宋体", FontSize, FontStyle.Bold), bru, new PointF(Left, Top));
                                }
                            }
                            else if (child.Name == "Image")
                            {
                                float Left = string.IsNullOrWhiteSpace(child.Attribute("Left").Value) ? 0 : Convert.ToSingle(child.Attribute("Left").Value);
                                float Top = string.IsNullOrWhiteSpace(child.Attribute("Top").Value) ? 0 : Convert.ToSingle(child.Attribute("Top").Value);
                                Top = totalHeight + Top;
                                string content = child.Value;
                                if (content.Contains("{{") && content.Contains("}}"))
                                {
                                    int beginIndex = content.IndexOf("{{");
                                    int endIndex = content.LastIndexOf("}}");
                                    string key = content.Substring(beginIndex + 2, endIndex - beginIndex - 2);
                                    Image image = Image.FromFile(this.DataSource[key].ToString());
    
                                    g.DrawImage(image, new PointF(Left, Top));
                                }
                            }
                            else if (child.Name == "QRCode")
                            {
                                string content = string.Empty;
    
                                float Left = string.IsNullOrWhiteSpace(child.Attribute("Left").Value) ? 0 : Convert.ToSingle(child.Attribute("Left").Value);
                                float Top = string.IsNullOrWhiteSpace(child.Attribute("Top").Value) ? 0 : Convert.ToSingle(child.Attribute("Top").Value);
    
                                Top = totalHeight + Top;
                                content = child.Value;
                                if (content.Contains("{{") && content.Contains("}}"))
                                {
                                    int beginIndex = content.IndexOf("{{");
                                    int endIndex = content.LastIndexOf("}}");
                                    string key = content.Substring(beginIndex + 2, endIndex - beginIndex - 2);
                                    content = content.Replace("{{" + key + "}}", this.DataSource[key].ToString());
    
                                }
    
                                QrEncoder qrEncoder = new QrEncoder(ErrorCorrectionLevel.H);
                                QrCode qrCode = new QrCode();
                                qrEncoder.TryEncode(content, out qrCode);
                                using (MemoryStream ms = new MemoryStream())
                                {
                                    var renderer = new GraphicsRenderer(new FixedModuleSize(2, QuietZoneModules.Two));
                                    renderer.WriteToStream(qrCode.Matrix, ImageFormat.Jpeg, ms);
                                    Image image = Image.FromStream(ms);
                                    g.DrawImage(image, new PointF(Left, Top));
                                }
    
                            }
                            else if (child.Name == "BarCode")
                            {
                                string content = string.Empty;
    
                                float Left = string.IsNullOrWhiteSpace(child.Attribute("Left").Value) ? 0 : Convert.ToSingle(child.Attribute("Left").Value);
                                float Top = string.IsNullOrWhiteSpace(child.Attribute("Top").Value) ? 0 : Convert.ToSingle(child.Attribute("Top").Value);
    
                                float Width = string.IsNullOrWhiteSpace(child.Attribute("Width").Value) ? 0 : Convert.ToSingle(child.Attribute("Width").Value);
                                float Height = string.IsNullOrWhiteSpace(child.Attribute("Height").Value) ? 0 : Convert.ToSingle(child.Attribute("Height").Value);
    
    
                                Top = totalHeight + Top;
                                content = child.Value;
                                if (content.Contains("{{") && content.Contains("}}"))
                                {
                                    int beginIndex = content.IndexOf("{{");
                                    int endIndex = content.LastIndexOf("}}");
                                    string key = content.Substring(beginIndex + 2, endIndex - beginIndex - 2);
                                    content = content.Replace("{{" + key + "}}", this.DataSource[key].ToString());
    
                                }
    
                                QrCodeEncodingOptions options = new QrCodeEncodingOptions
                                {
                                    DisableECI = true,
                                    CharacterSet = "UTF-8",
                                    Width = (int)Math.Ceiling(Width),
                                    Height = (int)Math.Ceiling(Height),
                                };
                                BarcodeWriter writer = new BarcodeWriter();
                                writer.Format = BarcodeFormat.CODE_128;
                                writer.Options = options;
                                Bitmap bitmap = writer.Write(content);
                                g.DrawImage(bitmap, new PointF(Left, Top));
                            }
                        }
    
                        totalHeight += LineHeigth;
                        rowIndex++;
                    }
                    else if (item.Name == "Loop")
                    {
                        string Values = item.Attribute("Values").Value;
                        List<Dictionary<string, object>> listValues = this.DataSource[Values] as List<Dictionary<string, object>>;
                        if (listValues != null)
                        {
                            XElement lineItem = item.Element("Line");
                            float LineHeigth = string.IsNullOrWhiteSpace(lineItem.Attribute("Height").Value) ? 0 : Convert.ToSingle(lineItem.Attribute("Height").Value);
    
                            for (int i = 0; i < listValues.Count(); i++)
                            {
                                Dictionary<string, object> dicRow = listValues[i];
    
                                foreach (XElement child in lineItem.Elements())
                                {
                                    if (child.Name == "Text")
                                    {
                                        float Left = string.IsNullOrWhiteSpace(child.Attribute("Left").Value) ? 0 : Convert.ToSingle(child.Attribute("Left").Value);
                                        float Top = string.IsNullOrWhiteSpace(child.Attribute("Top").Value) ? 0 : Convert.ToSingle(child.Attribute("Top").Value);
                                        float FontSize = string.IsNullOrWhiteSpace(child.Attribute("FontSize").Value) ? 0 : Convert.ToSingle(child.Attribute("FontSize").Value);
    
                                        Top = totalHeight + Top;
                                        string content = child.Value;
                                        if (content.Contains("{{") && content.Contains("}}"))
                                        {
                                            int beginIndex = content.IndexOf("{{");
                                            int endIndex = content.LastIndexOf("}}");
                                            string key = content.Substring(beginIndex + 2, endIndex - beginIndex - 2);
                                            g.DrawString(content.Replace("{{" + key + "}}", dicRow[key].ToString()), new Font("宋体", FontSize, FontStyle.Bold), bru, new PointF(Left, Top));
                                        }
                                        else
                                        {
                                            g.DrawString(content, new Font("宋体", FontSize, FontStyle.Bold), bru, new PointF(Left, Top));
                                        }
                                    }
                                    else if (child.Name == "Image")
                                    {
                                        float Left = string.IsNullOrWhiteSpace(child.Attribute("Left").Value) ? 0 : Convert.ToSingle(child.Attribute("Left").Value);
                                        float Top = string.IsNullOrWhiteSpace(child.Attribute("Top").Value) ? 0 : Convert.ToSingle(child.Attribute("Top").Value);
                                        Top = totalHeight + Top;
                                        string content = child.Value;
                                        if (content.Contains("{{") && content.Contains("}}"))
                                        {
                                            int beginIndex = content.IndexOf("{{");
                                            int endIndex = content.LastIndexOf("}}");
                                            string key = content.Substring(beginIndex + 2, endIndex - beginIndex - 2);
                                            Image image = Image.FromFile(dicRow[key].ToString());
    
                                            g.DrawImage(image, new PointF(Left, Top));
                                        }
                                    }
                                    else if (child.Name == "QRCode")
                                    {
                                        string content = string.Empty;
    
                                        float Left = string.IsNullOrWhiteSpace(child.Attribute("Left").Value) ? 0 : Convert.ToSingle(child.Attribute("Left").Value);
                                        float Top = string.IsNullOrWhiteSpace(child.Attribute("Top").Value) ? 0 : Convert.ToSingle(child.Attribute("Top").Value);
    
                                        Top = totalHeight + Top;
                                        content = child.Value;
                                        if (content.Contains("{{") && content.Contains("}}"))
                                        {
                                            int beginIndex = content.IndexOf("{{");
                                            int endIndex = content.LastIndexOf("}}");
                                            string key = content.Substring(beginIndex + 2, endIndex - beginIndex - 2);
                                            content = content.Replace("{{" + key + "}}", dicRow[key].ToString());
    
                                        }
    
                                        QrEncoder qrEncoder = new QrEncoder(ErrorCorrectionLevel.H);
                                        QrCode qrCode = new QrCode();
                                        qrEncoder.TryEncode(content, out qrCode);
                                        using (MemoryStream ms = new MemoryStream())
                                        {
                                            var renderer = new GraphicsRenderer(new FixedModuleSize(2, QuietZoneModules.Two));
                                            renderer.WriteToStream(qrCode.Matrix, ImageFormat.Jpeg, ms);
                                            Image image = Image.FromStream(ms);
                                            g.DrawImage(image, new PointF(Left, Top));
                                        }
                                    }
                                    else if (child.Name == "BarCode")
                                    {
                                        string content = string.Empty;
    
                                        float Left = string.IsNullOrWhiteSpace(child.Attribute("Left").Value) ? 0 : Convert.ToSingle(child.Attribute("Left").Value);
                                        float Top = string.IsNullOrWhiteSpace(child.Attribute("Top").Value) ? 0 : Convert.ToSingle(child.Attribute("Top").Value);
    
                                        float Width = string.IsNullOrWhiteSpace(child.Attribute("Width").Value) ? 0 : Convert.ToSingle(child.Attribute("Width").Value);
                                        float Height = string.IsNullOrWhiteSpace(child.Attribute("Height").Value) ? 0 : Convert.ToSingle(child.Attribute("Height").Value);
    
    
                                        Top = totalHeight + Top;
                                        content = child.Value;
                                        if (content.Contains("{{") && content.Contains("}}"))
                                        {
                                            int beginIndex = content.IndexOf("{{");
                                            int endIndex = content.LastIndexOf("}}");
                                            string key = content.Substring(beginIndex + 2, endIndex - beginIndex - 2);
                                            content = content.Replace("{{" + key + "}}", dicRow[key].ToString());
                                        }
                                        QrCodeEncodingOptions options = new QrCodeEncodingOptions
                                        {
                                            DisableECI = true,
                                            CharacterSet = "UTF-8",
                                            Width = (int)Math.Ceiling(Width),
                                            Height = (int)Math.Ceiling(Height),
                                        };
                                        BarcodeWriter writer = new BarcodeWriter();
                                        writer.Format = BarcodeFormat.CODE_128;
                                        writer.Options = options;
                                        Bitmap bitmap = writer.Write(content);
                                        g.DrawImage(bitmap, new PointF(Left, Top));
                                    }
                                }
    
                                totalHeight += LineHeigth;
                                rowIndex++;
                            }
                        }
                    }
                }
            }
    
        }
    打印类设置代码

     

          

          以上是模板打印出来的效果,也避免的打印机指令的相关问题,同时可以自定义标签纸张的大小以及打印的内容边距等等问题。

     

        五. 代码管理

         由于代码还未完全整理出来,后期整理好之后会托管到GitHub上,暂时有个简单的案例,如有需求可以QQ 821865130 联系我,  群号:88718955

         吉特仓储管理系统中涉及到打印的打印功能,也尝试过各种方式的打印,后面会一一总结分享。如果对吉特仓储系统想要有一定了解可以加群:  88718955  或 142050808

         吉特仓储管理系统有有开源代码: https://github.com/hechenqingyuan/gitwms   有兴趣的可以下载共同探讨

          


    作者:情缘
    出处:http://www.cnblogs.com/qingyuan/
    关于作者:从事仓库,生产软件方面的开发,在项目管理以及企业经营方面寻求发展之路
    版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
    联系方式: 个人QQ  821865130 ; 仓储技术QQ群 88718955,142050808 ;
    吉特仓储管理系统 开源地址: https://github.com/hechenqingyuan/gitwms

     

    转载于:https://www.cnblogs.com/qingyuan/p/5659980.html

    展开全文
  • 仓库管理系统

    2015-05-28 22:05:36
    系统的设汁模拟一般仓库的管理内容,包括物资管理、仓库管理、入库操作、入库查询统计、出库操作、出库查询统计、库存查询统计等处理情况,系统需要管理的主要内容如下: ⑴ 能分类管理物资信息。 ⑵ 系统能管理多...
  • 易顺佳仓库管理系统标准版适用于中小型企业、批发部、服装、工厂等进行商品采购、销售、入库、出库等管理。主要功能包括商品信息、往来单位信息(包括供应商、客户等信息)、采购申请、采购订单、采购进货、采购退货、...
  • 仓库管理系统阳光版

    2021-04-05 07:17:50
    仓库管理系统1.0 简介 仓库管理软件,能够处理企业级的仓库管理事务.   使用说明 登记信息 货物信息: 可以进行货物管理,可以增加货物类别,增加货物种类,对货物基本信息可以进行编辑,除了"货物编号"外,对...
  • 波次任务 WMS系统根据提前设置好的波次规则以及接收到的销售出库,自动生成波次任务,仓管员通过PDA领取波次任务,根据PDA指引进行分拣。 播种作业 一多品商品进行播种作业,仓管员持待播种商品以及PDA至播种墙...
    5ad375b187f98afb349869d4f2adcad5.png

    了解更多WMS请关注我们

    销售订单

    WMS系统同erp系统获取销售订单,在wms系统中可以查询销售订单,也可以手动新增销售订单。

    波次任务

    WMS系统根据提前设置好的波次规则以及接收到的销售出库单,自动生成波次任务,仓管员通过PDA领取波次任务,根据PDA指引进行分拣。

    b08955412c577b9b29940a8d92006496.png

    播种作业

    一单多品商品进行播种作业,仓管员持待播种商品以及PDA至播种墙,扫描商品条码,PDA指引播种仓位,仓管员完成投放。

    打包作业

    完成播种的仓位商品以及一单一品商品进行打包作业。

    一单多品打包:打包员扫描仓位,获取订单信息,自动打印快递面单(若ERP提供快递单号,则获取快递单号,ERP无快递单号WMS系统自动生成快递单号),完成贴快递单。

    一单一品打包:打包员扫描商品条码,获取订单信息,自动打印快递面单(若ERP提供快递单号,则获取快递单号,ERP无快递单号WMS系统自动生成快递单号),完成贴快递单。

    称重发运

    打包贴快递单后,将打包好的包裹放至电子秤上,系统记录本次订单的重量,同时改变销售单状态为已发运,仓库库位减少。

    装箱称重

    将打包发运的包裹装箱,完成销售订单和箱子的绑定,进行整箱称重,wms保存称重结果。

    仓储管理知识分享平台

    仓储智能化管理平台尽在DeerWMS.

    ------END-----

    业务咨询WMS解决方案

    请联系郭经理:13685133739

    公司官网:http://www.wmswcs.com

    更多仓储前沿知识请关注微信公众号

    b73c1dac365ac16104bb661939a64c44.png

    高效|灵活|便捷

    让您的仓储管理更简单

    南京大鹿智造科技有限公司

    展开全文
  • 新源仓库管理系统单机版一款通用性好的仓库及货物管理系统系统适用于食品、五金、保健品、电子、贸易、物资、化妆品、电器等工业、商业、贸易领域的企业。是一款不可多得的库房管理系统,仓储管理系统. 系统具有...
  • 采购审核完成就可以采购商品,商品采购完成后就可以送入库房,库房等着收货,采购到达仓库的第一步骤是确认到货,确认到货有两个操作,第一是更改采购状态,第二是打印到货

                       采购单审核完成就可以采购商品,商品采购完成后就可以送入库房,库房等着收货,采购单到达仓库的第一步骤是确认到货,确认到货有两个操作,第一是更改采购单状态,第二是打印到货单。

              1.确认到货

                  确认到货要记录到货时间,确认到货后就可以进行入库操作了

                          

              2.打印到货单

                       

                     

    展开全文
  • PHP语言开发的ERP进销存管理系统仓库全开源无限制优化版,扫描入库+库存预警+仓库管理+商品管理+供应商管理。有购货,销货,仓库管理,商品管理,供应商管理,职员管理等非常多的功能。 本系统开发 ...
  • 简单仓库管理系统,本软件根据市场需要结合企业自身特点量身定做的操作方便、功能完善功能强大个性化极强的仓库管理系统系统集送货管理,采购入库,生产入库,销售退货,采购退货,生产领料,财务管理等多种...
  • 易用仓库管理软件免费版是一款通用性极强的仓库及货物管理软件(仓库软件,仓库管理系统,库房管理系统,仓储管理系统),易用仓库软件免费版适用于食品、五金、保健品、电子、贸易、物资、化妆品、电器等工业、商业...
  • 仓库管理系统.zip

    2020-07-14 11:07:42
    系统中每个操作人员都可以作为用户,当一个用户权限修改时,不会影响其他用户;可以对每个用户单独授予某个程序的执行权,也可以收回其执行权,而不影响其他用户的权限; 1.用户登录程序,名称用以“班级+座号+...
  • 一彩仓库管理系统,本软件根据市场需要结合企业自身特点量身定做的操作方便、功能完善功能强大个性化极强的仓库管理系统系统集送货管理,采购入库,生产入库,销售退货,采购退货,生产领料,财务管理等多种...
  • 支持批量打单。  4. 支持批量签回单功能。  5. 支持扫描枪读取单号功能。  6. 单据编号规则自己定义。  7. 系统所有报表都可以轻松的导出Excel Word 以及JPG图片。  8. 系统部份报表用户可以自己完成修改,...
  • 为您提供速拓仓库管理系统下载,速拓仓库管理系统是一款非常实用的仓库管理软件,它的功能非常齐全,能支持单仓库和多仓库管理体系,可以管理任意仓库、任意品种的库存;支持货品价签打印等。软件特色 ◆ 可以为货品...
  • 易用仓库管理系统7

    2011-11-08 17:28:36
    6、软件提供了完备的帐务系统,可以随时查询或打印月记帐、日记帐。多方位为企业经营决策提供服务; 7、货品和来往单位资料支持树形分类管理; 8、支持自定义单据打印格式,可以任意更换打印机及纸张类型,支持单据套...
  • 一彩仓库管理系统,本软件根据市场需要结合企业自身特点量身定做的操作方便、功能完善功能强大个性化极强的仓库管理系统系统集送货管理,采购入库,生产入库,销售退货,采购退货,生产领料,财务管理等多种工作...
  • 支持批量打单。  4. 支持批量签回单功能。  5. 支持扫描枪读取单号功能。  6. 单据编号规则自己定义。  7. 系统所有报表都可以轻松的导出Excel Word 以及JPG图片。  8. 系统部份报表用户可以自己完成修改,...
  • 一彩仓库管理系统,本软件根据市场需要结合企业自身特点量身定做的操作方便、功能完善功能强大个性化极强的仓库管理系统系统集送货管理,采购入库,生产入库,销售退货,采购退货,生产领料,财务管理等多种...
  • 6、软件提供了完备的帐务系统,可以随时查询或打印月记帐、日记帐。多方位为企业经营决策提供服务; 7、货品和来往单位资料支持树形分类管理; 8、支持自定义单据打印格式,可以任意更换打印机及纸张类型,支持单据套...
  • 仓库管理系统源代码 VB ACCESS

    千次下载 热门讨论 2009-01-08 19:48:30
    仓库之间的调拔,同"入库"一样,不过没有"金额",不没有退出.对原仓库和目标仓库均会进行库存限量的统计. 报损: 同"入库"一样,只不过没有"金额". 月盘点: 仓库进行月盘点,会将本月该仓库的货物出入信息...
  • vb+access仓库管理系统

    2010-01-05 09:54:47
    仓库之间的调拔,同"入库"一样,不过没有"金额",不没有退出.对原仓库和目标仓库均会进行库存限量的统计. 报损: 同"入库"一样,只不过没有"金额". 月盘点: 仓库进行月盘点,会将本月该仓库的货物出入信息...
  • delphi仓库管理系统

    2010-01-19 12:40:40
    系统中每个操作人员都可以作为用户,当一个用户权限修改时,不会影响其他用户;可以对每个用户单独授予某个程序的执行权,也可以收回其执行权,而不影响其他用户的权限; 1. 用户登录程序,名称用以“班级+座号+...
  • (3)出库信息管理模块:为仓库员工提供查询、添加、修改和删除出库(包括:产品出库、部件出库、礼品出库)的操作,其中添加和删除操作后的出库要交由仓库主管审核。 (4)入库信息管理模块:为仓库员工...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 598
精华内容 239
关键字:

仓库打单系统