倉儲物流的程序中往往少不了一些使用熱敏列印機或者碳帶列印機列印一些條碼、資訊貼在實物或者包裹上
最好的實作方式不過于直接使用熱敏代碼形成文本直接輸出到列印機做列印
但是熱敏代碼也是一門需要特殊的語言,需要學習
故為了更快更方便的實作,就用到了畫布繪制后形成image輸出到列印機
而image也是有要求的,比如輸出的格式、大小直接影響列印的質量
這里介紹下使用微軟的報表布局系結資料轉image輸出到列印機的方式
1、nuget上搜索Microsoft.ReportViewer.Common、Microsoft.ReportViewer.WebForms安裝
2、創建rdlc報表,繪制指定列印輸出的模板大小,對rdlc添加資料集,可以為物件,這里使用物件系結(后臺查詢資料映射給物件)
可以為界面每個項的屬性進行設定:字體、大小、資料系結、對齊等,也可以動態使用運算式(資料源傳入指定值)

3、列印入口,為報表系結資料
DeviceInfo的詳細說明見:
https://docs.microsoft.com/zh-cn/sql/reporting-services/image-device-information-settings?redirectedfrom=MSDN&view=sql-server-ver15
LocalReport.Render使用見
https://docs.microsoft.com/zh-cn/previous-versions/dd468075(v=vs.140)
注意:OutputFormat為EMF
PageWidth、PageHeight為rdlc的大小
如果需要使用到條碼資訊,則需要宣告byte[] 接收使用BarcodeLib.Barcode相關條碼類生成條碼圖片
rdlc模板上添加影像控制元件欄位指向byte[]欄位,mime選擇image/png,大小顯示為:調整為合適大小
測驗時可以保存為圖片,預覽效果圖
public string PrintOutPackage(string Consignee, string ContractCode,string ConsigneeAddress, int count, int cur, string printName, int type=1) { if (string.IsNullOrWhiteSpace(printName)) { return "沒有選擇列印機"; } using (LocalReport report = new LocalReport()) { report.ReportPath = System.Windows.Forms.Application.StartupPath + "/Content/OutPackage.rdlc"; report.DataSources.Clear(); var printModel = new OutPackagePrintModel() { Consignee = Consignee, ContractCode = ContractCode, ConsigneeAddress = ConsigneeAddress, PackageCount = count, CurPackageCount = cur, ConsigneeFontSize = Consignee.Length <= 3 ? "28pt" : Consignee.Length <= 12 ? "16pt" : "12px" }; var list = new List<OutPackagePrintModel>(); list.Add(printModel); ReportDataSource ds = new ReportDataSource("OutPackage", list);//系結資料源 report.DataSources.Add(ds); report.Refresh(); string deviceInfo = "<DeviceInfo>" + " <OutputFormat>EMF</OutputFormat>" + " <PageWidth>8cm</PageWidth>" + " <PageHeight>5cm</PageHeight>" + "<PrintDpiX>300</PrintDpiX>" + "<PrintDpiY>300</PrintDpiY>" + " <MarginTop>0pt</MarginTop>" + " <MarginLeft>0pt</MarginLeft>" + " <MarginRight>0pt</MarginRight>" + " <MarginBottom>0pt</MarginBottom>" + "</DeviceInfo>"; Warning[] warnings; m_streams = new List<Stream>(); //將報表的內容按照deviceInfo指定的格式輸出到CreateStream函式提供的Stream中, report.Render("Image", deviceInfo, CreateStream, out warnings); } foreach (Stream stream in m_streams) { stream.Position = 0; } Image pageImage = Image.FromStream(m_streams[0]); if (type == 2) { //測驗時保存圖片 pageImage.Save(@"d:\" + $"{cur}_{count}" + ".emf", ImageFormat.Tiff); return "已保存圖片"; } //正式時呼叫列印機列印 var r = Printer.PrintImageData(pageImage, printName, "0", "0"); if (!r.IsSuccess) return r.Message; return ""; } private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) { //如果需要將報表輸出的資料保存為檔案,請使用FileStream物件, Stream stream = new MemoryStream(); BillPrintSteam = stream; m_streams.Add(stream); return stream; }
4、生成的圖片輸出到列印機列印:
將生成的image在列印機端
可使用PrinterSettings.StringCollection listPrint = PrinterSettings.InstalledPrinters;獲取所有列印機名稱
public static PrintModel PrintImageData(Image pageImage,string PrinterName,string PaperSizeWidth,string PaperSizeHeight) { bool PrintIsSuccess=false; Exception PrintException=null; //宣告PrintDocument物件用于資料的列印 PrintDocument printDoc = new PrintDocument(); printDoc.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0); //指定需要使用的列印機的名稱,使用空字串""來指定默認列印機 //傳入列印機名稱 則使用傳入的,否則使用當前服務賬戶(登錄為)的默認列印機 if (!string.IsNullOrWhiteSpace(PrinterName)) { printDoc.PrinterSettings.PrinterName = PrinterName; } //判斷指定的列印機是否可用 if (!printDoc.PrinterSettings.IsValid) { return PrintModel.CreateFailedResult("未能找到默認的列印機!"); } if (!string.IsNullOrWhiteSpace(PaperSizeWidth) && PaperSizeWidth != "0" && !string.IsNullOrWhiteSpace(PaperSizeHeight) && PaperSizeHeight != "0") { var ps = new PaperSize("Your Paper Name", int.Parse(PaperSizeWidth), int.Parse(PaperSizeHeight)) { RawKind = 120 };//自定義紙張 printDoc.DefaultPageSettings.PaperSize = ps; } printDoc.PrintPage += new PrintPageEventHandler(delegate (object sender, PrintPageEventArgs ev) { try { ev.Graphics.PageUnit = GraphicsUnit.Document; //ev.Graphics.CompositingQuality = CompositingQuality.HighQuality; //ev.Graphics.PageScale = 1; if (pageImage == null) return; // Adjust rectangular area with printer margins. Rectangle adjustedRect = new Rectangle( ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX, ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY, ev.PageBounds.Width, ev.PageBounds.Height); Rectangle srcRect = new Rectangle(0, 0, pageImage.Width, pageImage.Height); // Draw a white background for the report //ev.Graphics.FillRectangle(Brushes.White, adjustedRect); // Draw the report content ev.Graphics.DrawImage(pageImage, srcRect);//, srcRect, GraphicsUnit.Pixel); ev.HasMorePages = false; } catch (Exception ex) { PrintException = ex; PrintIsSuccess = false; } }); try { if (pageImage == null) { PrintIsSuccess = false; } else { printDoc.Print(); PrintIsSuccess = true; } } catch (Exception ex) { PrintException = ex; PrintIsSuccess = false; } return PrintModel.Create(PrintIsSuccess, PrintIsSuccess ? "Print Success!" : "Print Fail!", PrintException); }
public static List<PrinterModel> GetPrinterList() { PrinterSettings ps = new PrinterSettings(); PrinterSettings.StringCollection listPrint = PrinterSettings.InstalledPrinters; List<PrinterModel> pList = new List<PrinterModel>(); for (int i = 0; i < listPrint.Count; i++) { PrinterModel pm = new PrinterModel(); ps.PrinterName = listPrint[i]; pm.PrinterName = ps.PrinterName; pm.IsDefaultPrinter = ps.IsDefaultPrinter; pm.OrderBy = pm.IsDefaultPrinter ? -1 : i; pList.Add(pm); } return pList.OrderBy(x => x.OrderBy).ToList(); }
以上cs結構下不需要特殊權限
如果為bs結構下或者需要ajax調取列印機的(電子稱重同理可借鑒):
1、可以將列印圖片的方法作為介面宿主到windowsservice上開放埠,安裝在需要列印的電腦上,
接收的不是image改為圖片的url,得到url后進行download后輸出到列印機
可以增加介面判斷列印服務是否可用
在app.config增加
<services>
<service behaviorConfiguration="EnableMetadataBehaviors" name="Shangpin.Logistic.WindowsService.ClientPrintService.ServiceLibrary.PrintService">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="WebScriptBehavior" bindingConfiguration="HttpJsonpBinding" contract="Shangpin.Logistic.WindowsService.ClientPrintService.ServiceLibrary.IPrintService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:41943/PrintService" />
</baseAddresses>
</host>
</service>
2、形成圖片的方法作為服務端介面可得到圖片,介面url可匿名給列印服務獲取圖片
在網頁的按鈕上實作ajax跨域請求:
$.ajax({ url: "http://localhost:41943/PrintService/Print?jsoncallback=?", dataType: 'jsonp', data: { url: imageUrl, printerName: $("#PrinterList").find("option:selected").val(), paperSizeWidth: paperSizeWidth, paperSizeHeight: paperSizeHeight }, success: function (data) { if (!data.IsSuccess) { LG.showError("明細編號" + printArr[i] + "列印失敗:" + data.Message, function () { JudgePrintAgain(printArr, i, url, paperSizeWidth, paperSizeHeight);//回圈列印 }); } else { JudgePrintAgain(printArr, i, url, paperSizeWidth, paperSizeHeight); } }, error: function (result) { LG.tip('發現系統錯誤 <br />錯誤碼:' + result.status); } });
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/36085.html
標籤:C#
