Tuesday, February 27, 2024

D365FO - ZPL Printer Emulation (labelary.com) directly within D365FO

It would appear that recently the Chrome ZPL printer emulator is no longer valid which is triggering some people to install a ZPL printer emulator in order to validate Dynamic ZPL code within D365FO. After much research it appears that all these extensions and printer emulators all use the free Label service https://labelary.com/

Because this API is being used throughout the industry why not create our own way to call this API directly within D365 vs installing a printer emulator which then requires a document routing agent to be installed.

The below code snippet shows you how to connect to their RESTful API service which can generate various types of images based on the ZPL codes. You could easily modularize the following logic in order to create something pretty powerful and dynamic based on any dataset.


Webservice to generate a label based on ZPL code: https://labelary.com/service.html

Online ZPL Viewer: https://labelary.com/viewer.html 


 

            System.Exception clrError;
            InteropPermission interopPermission;
            System.Net.HttpWebRequest request;
            System.IO.Stream stream;
            System.Byte[] zpl = System.Text.Encoding::UTF8.GetBytes("^xa^cfa,50^fo100,100^fdHello World^fs^xz"); //raw zpl code

            request = System.Net.WebRequest::Create("http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/") as System.Net.HttpWebRequest;
            request.Method = 'POST';
            request.Accept = "image/png";
            request.ContentType = 'application/x-www-form-urlencoded';
  
            try
            {
                interopPermission = new InteropPermission(InteropKind::ComInterop);
                interopPermission.assert();

                // send out the payload
                using (System.IO.Stream dataStream = request.GetRequestStream())
                {
                    dataStream.Write(zpl, 0, zpl.Length);
                }

                using (System.Net.HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse)
                {
                    stream = response.GetResponseStream();
                    System.IO.MemoryStream filestream = new System.IO.MemoryStream();
                    
                    //we need to convert the main stream to a memory stream in order to access the binary objects
                    stream.CopyTo(filestream);
     
                    //send the memory stream directly to the user which now contains a file object
                    File::SendFileToUser(filestream, "test.png");
                    
                    //convert the memory stream into an image object which can then be displayed to the user
		    BinData binData = new BinData();
                    container baseContainer;
                    Image image = new Image();
                    
                    baseContainer =  Binary::constructFromMemoryStream(fileStream).getContainer();

                    binData.setData(baseContainer);
                    image.setData(binData.getData());
                    //display the newly created image to the user
		    FormImageControl1.image(image);
                }
                Info("done");
            }
            catch (Exception::CLRError)
            {
                //catch any clr error
                clrError = CLRInterop::getLastException();
                if (clrError != null)
                {
                    clrError = clrError.InnerException;
                    throw error(clrError.ToString());
                }
            }
            finally
            {
                CodeAccessPermission::revertAssert();
            }	 





No comments:

Post a Comment