Print pdf bytes / local file to printer in vision?

Have a report section of a project where users finish a process and then accept a report. This then prints multiple grades of a report, where there is some analysis done in a script data key of the report so each grade ends up having slightly different data, and this analysis does take a lets say 1 second of time, point being it’s not a lot but its not nothing either. It can be up to 8 grades. I don’t necessarily have to print all the grades calculated (the user gets to select that before accepting).

I do have to save each grade to the database though regardless of if it is printed so I do have the bytes of the pdf handy. So I would like to try to print from the bytes directly or indirectly if possible. I was having zero luck printing the bytes so here is an attempt at saving to a local file and then printing that but

import os
from javax.print import DocFlavor, SimpleDoc, PrintServiceLookup
from javax.print.attribute import HashPrintRequestAttributeSet, HashDocAttributeSet
from javax.print.attribute.standard import Copies
from java.io import FileInputStream, File

path = 'myReport'
parameters = {
    'recordId':85076,
    'schema':"[Somewhere]",
    'language':1,
    'ReportSource':1
}
action = 'print'
actionSettings = {
    "copies":1
}
pdfBytes = system.report.executeReport(path, project='TFDCS_STAGING', parameters=parameters)
def printPDFReport(pdfBytes, copies):
    """
    Due to various issues about sending bytes directly to the printer and some
    models accepting and other models not accepting this sort of format, the 
    safest thing to do here imo is to save the report to a file, print the
    file, then delete the file after the fact.  Not my favorite, but I still
    consider it easier and more managingthan handling the report compnent race
    conditions on changing parameters/reportLoading on gui directly.
    Args:
        pdfBytes: byes, the raw data
        copies: int, min 1
    Returns:
        None, saves to local temp file and prints
    """
    if copies < 1:
        return
    homeFolder = system.tag.readBlocking(['[System]Client/User/HomeFolder'])[0].value
    tempReportFolder = os.path.join(homeFolder, 'TempReport')
    if not os.path.exists(tempReportFolder):
        print 'making folder'
        os.makedirs(tempReportFolder)
    fileName = "Report_{}.pdf".format(system.date.format(system.date.now(), "yyyyMMddHHmmss"))
    filePath = os.path.join(tempReportFolder, fileName)
    print filePath 
    system.file.writeFile(filePath, pdfBytes)
    # Now that we have our file we can print it
    printService = PrintServiceLookup.lookupDefaultPrintService()
    flavor = DocFlavor.INPUT_STREAM.AUTOSENSE
    fileInputStream = FileInputStream(filePath)
    
    printJobAttributeSet = HashPrintRequestAttributeSet()
    printJobAttributeSet.add(Copies(copies))
    docAttributeSet = HashDocAttributeSet()
    doc = SimpleDoc(fileInputStream, flavor, docAttributeSet)
    job = printService.createPrintJob()
    job.print(doc, printJobAttributeSet)

printPDFReport(pdfBytes, 1)
   

This does not work for me though. On my computer in my printer queue I do see it gets “sent to printer” but it never passes that point/never prints.

My question is - is it possible to make the above work, to print to the printer local to the vision client directly from bytes/file in a generic way safely? Or is it safer to work with the ReportViewer.print function and I need to go one at a time, monitoring reportLoading as my trigger to move on to the next grade.

Either use the report viewer, or launch a local executable that can print a PDF. In linux, lp is typically smart enough to filter PDFs through the actual print driver properly. You would use - as the filename to stream the bytes to it via stdin. (Use ProcessBuilder.)

1 Like

Unfortunately windows but good to know my two ways forward are finding a command I can use ProcessBuilder with or just iterating through and monitoring reportviewer/reportLoading. Thanks

Sigh. You should point your bosses/clients at my rants here on the topic.

4 Likes