In the process of warehousing and logistics, it is often necessary to use thermal printer or carbon tape printer to print some barcode and information and paste them on the physical object or package
The best way is not to directly use thermal code to form text and output it to printer for printing
But thermal code is also a special language to learn
So in order to realize faster and more convenient, we use canvas to draw and form image output to printer
image is also required. For example, the format and size of output directly affect the quality of printing
Here is how to use Microsoft's report layout binding data to transfer image output to printer
1. Search on nuget Microsoft.ReportViewer.Common , Microsoft.ReportViewer.WebForms install
2. Create rdlc report, draw template size of specified printout, add data set to rdlc, you can use object binding here (background query data mapping to object)
You can set the properties of each item in the interface: font, size, data binding, alignment, etc., or you can dynamically use expressions (data source passes in specified values)
3. Print entry, binding data for report
For details of DeviceInfo, see:
LocalReport.Render See
https://docs.microsoft.com/zh-cn/previous-versions/dd468075(v=vs.140)
Note: OutputFormat is EMF
PageWidth and PageHeight are the sizes of rdlc
If you need to use barcode information, you need to declare byte [] to receive and use BarcodeLib.Barcode Generate barcode image from related barcode classes
Add image control field on rdlc template to point to byte [] field, select image/png for mime, and the size is displayed as: adjust to appropriate size
During the test, you can save it as a picture and preview the effect picture
public string PrintOutPackage(string Consignee, string ContractCode,string ConsigneeAddress, int count, int cur, string printName, int type=1) { if (string.IsNullOrWhiteSpace(printName)) { return "No printer selected"; } 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);//Bind data source 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>(); //According to deviceInfo Specified format output to CreateStream Provided by function Stream Medium. 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) { //Save picture during test pageImage.Save(@"d:\" + $"{cur}_{count}" + ".emf", ImageFormat.Tiff); return "Saved picture"; } //Call printer to print in official time 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) { //If you need to save the report output data as a file, use the FileStream Object. Stream stream = new MemoryStream(); BillPrintSteam = stream; m_streams.Add(stream); return stream; }
4. Output the generated pictures to the printer for printing:
Put the generated image on the printer side
Available PrinterSettings.StringCollection listPrint = PrinterSettings.InstalledPrinters ; get all printer names
public static PrintModel PrintImageData(Image pageImage,string PrinterName,string PaperSizeWidth,string PaperSizeHeight) { bool PrintIsSuccess=false; Exception PrintException=null; //statement PrintDocument Object for data printing PrintDocument printDoc = new PrintDocument(); printDoc.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0); //Specifies the name of the printer to use, using an empty string""To specify the default printer //If the printer name is passed in, the default printer of the current service account (login as) will be used if (!string.IsNullOrWhiteSpace(PrinterName)) { printDoc.PrinterSettings.PrinterName = PrinterName; } //Determine whether the specified printer is available if (!printDoc.PrinterSettings.IsValid) { return PrintModel.CreateFailedResult("Could not find default printer!"); } 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 };//Custom paper 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(); }
No special permission is required under the above cs structure
If it is under bs structure or needs ajax to call the printer (the same can be used for reference for electronic weighing):
1. You can host the method of printing pictures as an interface to the windows service open port, and install it on the computer that needs to print.
The received url is not the url of the image changed to the image. After getting the url, download it and output it to the printer
Interface can be added to judge whether printing service is available
stay app.config increase
<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. The method of forming pictures can be used as the interface of the server to obtain pictures, and the interface url can obtain pictures anonymously for the printing service
Realize ajax cross domain request on the button of web page:
$.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("Detail No" + printArr[i] + "Printing failed:" + data.Message, function () { JudgePrintAgain(printArr, i, url, paperSizeWidth, paperSizeHeight);//Circular printing }); } else { JudgePrintAgain(printArr, i, url, paperSizeWidth, paperSizeHeight); } }, error: function (result) { LG.tip('System error found <br />Error code:' + result.status); } });