吉特仓库管理系统-.NET打印问题总结
?
在倉儲系統的是使用過程中避免不了的是打印單據,倉庫系統中包含很多單據:入庫單,出庫單,盤點單,調撥單,簽收單等等,而且還附帶著很多的條碼標簽的打印。本文在此記錄一下一個簡單的打印問題處理方式。處理問題環境如下:
在做標簽打印的時候,同事說要使用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
?
總結
以上是生活随笔為你收集整理的吉特仓库管理系统-.NET打印问题总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 博奥智源公司,图书馆管理软件开发功能详解
- 下一篇: mysql checksum原理_pt-