Print PDF labels - specific printer and page size

Im hoping someone has an idea what (stupid thing) I've done wrong here.

We are trying to print labels from a PDF file. The file is generated using SkiaSharp PDF canvas. Each page is the same size and it validates and is displayed correctly in Adobe Reader etc. However, we cannot get the correct page size set when printing. Ive seen several examples here but none of them work. The only thing that sets the correct paper size on the thermal printer is using the Paginator method that prints each page as a bitmap, but the quality of the output is rubbish - ie, barcodes are fuzzy. It looks like it's resizing and dithering and/or expecting lots of colours. Labels are typically b/w only.

Sample code below from my last attempt. See attached pdf and image of printed output. Label is 80mm x 180mm (~ 3x7 inches). Printer is a TEC 245 Thermal, no ribbon, with 203 pixel resolution.


You can see from the image that the page size is clipping the content. I've experimented with various calculations for the page size. Im using my own unit converter. The measurements at all DPI are correctly calculated. At 203 DPI I get 1438 x 639 pixels, which is correct, but the image is much the same as the sample - the barcode is truncated and the corner blocks are not printed.

Cheers


  public class WindowsGenericPrinterDriver 
  {
    public float DPI => 96;

    public override void PrintDocument(string documentFile)
    {
      using var t = StartSTATask(() =>
      {
        PrintPDFFile(documentFile);
        return Task.CompletedTask;
      });
      t.Wait();
      if (t.Exception != null)
      {
        throw t.Exception;
      }
    }

    Task StartSTATask(Func func)
    {
      var tcs = new TaskCompletionSource();
      Thread thread = new Thread(() =>
      {
        try
        {
          tcs.SetResult(func());
        }
        catch (Exception e)
        {
          tcs.SetException(e);
        }
      });
      thread.SetApartmentState(ApartmentState.STA);
      thread.Start();
      return tcs.Task;
    }

    private bool PrintPDFFile(string pdfFile)
    {
      using var localPrintServer = new LocalPrintServer();
      using var printQueue = localPrintServer.GetPrintQueue(PrintRequest.Printer.Name);
      if (printQueue == null)
      {
        throw new Exception($"No printer called ${PrintRequest.Printer.Name} found");
      }

      var pdfViewer = new PdfDocumentView();
      pdfViewer.Load(pdfFile);
      var doc = pdfViewer.PrintDocument;

      var ticket = GetPrintTicket(printQueue);
      var @object = new PrintDlgPrintTicketEventHandler(ticket);

      var xpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue);
      xpsDocumentWriter.WritingPrintTicketRequired += @object.SetPrintTicket;

      xpsDocumentWriter.Write(doc, ticket);

      return true;
    }

    private PrintTicket GetPrintTicket(PrintQueue printQueue)
    {
      var ticket = printQueue.DefaultPrintTicket.Clone();
      ticket.Collation = PrintRequest.Collate ? Collation.Collated : Collation.Uncollated;
      ticket.CopyCount = PrintRequest.Copies;
      ticket.PageBorderless = PageBorderless.Borderless;
      ticket.OutputQuality = OutputQuality.High;

      var pageSize = UnitConverter.ToPixels(PrintRequest.Label.Media.PageOuterSize, PrintRequest.Label.Media.DefaultMeasure, DPI);

      if (PrintRequest.Label.Media.Landscape)
      {
        // landscape we need to flip height and width
        ticket.PageOrientation = System.Printing.PageOrientation.Landscape;
        ticket.PageMediaSize = new PageMediaSize(PageMediaSizeName.Unknown, pageSize.Height, pageSize.Width);
      }
      else
      {
        ticket.PageOrientation = System.Printing.PageOrientation.Portrait;
        ticket.PageMediaSize = new PageMediaSize(PageMediaSizeName.Unknown, pageSize.Width, pageSize.Height);

      }

      return ticket;
    }
  }

  internal class PrintDlgPrintTicketEventHandler
  {
    private readonly PrintTicket _printTicket;

    public PrintDlgPrintTicketEventHandler(PrintTicket printTicket)
    {
      _printTicket = printTicket;
    }

    public void SetPrintTicket(object sender, WritingPrintTicketRequiredEventArgs args)
    {
      // if (args.CurrentPrintTicketLevel == PrintTicketLevel.FixedDocumentSequencePrintTicket)
      {
        args.CurrentPrintTicket = _printTicket;
      }
    }
  }



Attachment: sample_9a07ef16.zip


5 Replies

SS Sathish Shankar Syncfusion Team July 20, 2021 03:53 PM UTC

Hi Peter, 
 
Sorry for the delay. 
 
We have tried to reproduce the reported issue “Printed output cutting off when using the PdfDocumentView PrintDocument ” in our side by using PdfDocumentView Print method. But it can’t to be reproduced in our end, It prints as expected without cutting off the original contents. Since you have referred sample level class objects, which we can’t use the previously shared code snippets. We suspect you need to print the document, which will need to be stretched based on the selected paper size.  
 
PDF Viewer Print size Fit option enlarges or reduces each page to fit the printable area of the selected paper size. This will maintain the aspect ratio based on the selected paper and PDF document actual size. You can find the further details about printing in below link. 
 
 
We have created the sample for your reference.  
 
 
You can download the sample from the above link. Please let us know whether the information is helpful of not. This will help us to analyze more on this and provide you a better solution.  
  
Regards, 
Sathish Shankar 
 



PE Peter July 20, 2021 08:35 PM UTC

Hi

I can confirm your method does indeed work, thank you for the sample, but it only works if I set the paper size in the printer settings first.

We would like to be able to set the paper / media size from code and there doesnt seem to be a way to do this with PDFViewer, hence our attempt to use the print document.  Maybe we need to set the printer defaults before printing or there is some other trick but I think this is outside of the control of the PDFViewer.


In the end, customers will not often change the label sizes and asking them to do this in the printer settings outside of our app is not great, but acceptable.


Thanks





DD Divya Dhayalan Syncfusion Team July 21, 2021 11:06 AM UTC

Hi Peter, 
 
In our PDF Viewer the silent printing Print method will use the default printer and its properties to print. We can set the important options by using the PDF Viewer PrinterSettings. As you have mentioned we need to set some of the printer properties present in the machine which are not available in the PrinterSettings property. 
 
Based on your update, we understand that your requirement is to select the paper size in application level. Since, we didn’t provide the support to select the paper size yet, so we request you to set it from the printer defaults before printing. 
 
Please confirm as whether providing the PaperSize collection option as in the below link to choose PaperSize will be helpful for you to achieve your requirement.  
 
Also, kindly share is there any other printer settings you want to set in the application level, this information will be helpful for us to analyze better on this and provide you a better solution. 
 
Regards, 
Divya 



PE Peter July 21, 2021 10:24 PM UTC

Hi

Thanks for the followup. 

I need to spend a lot more time on this than I have available right now but mostly we just need to be able to specify any paper size without having to create this in the printer driver settings manually.  If we can do that via the PDFViewer printer settings this would be better, but using the DefaultPrinterSettings on the print queue will probably works - as long as that doesnt create a permanent change.

I'll add more detail next week probably.


Thanks again




DD Divya Dhayalan Syncfusion Team July 22, 2021 01:26 PM UTC

Hi Peter, 
 
Thank you for the update. We will wait till next week to hear the further details on this from your side. 
 
Regards, 
Divya

Loader.
Up arrow icon