Self adhesive, thermal printing

Posted by gavinbsocom on Wed, 20 May 2020 09:43:00 +0200

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

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";

                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>();
                ReportDataSource ds = new ReportDataSource("OutPackage", list);//Bind data source
                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>" +
                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;
            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)
                    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,

                    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;

                if (pageImage == null)
                    PrintIsSuccess = false;
                    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;
            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

      <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" />
            <add baseAddress="http://localhost:41943/PrintService" />

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:

    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);

Topics: C# SQL Windows encoding