吉特倉庫管理系統-.NET列印問題總結

賀臣發表於2016-07-11

 

  在倉儲系統的是使用過程中避免不了的是列印單據,倉庫系統中包含很多單據:入庫單,出庫單,盤點單,調撥單,簽收單等等,而且還附帶著很多的條碼標籤的列印。本文在此記錄一下一個簡單的列印問題處理方式。處理問題環境如下:

在做標籤列印的時候,同事說要使用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

 

相關文章