Java impression PDF avec des options (agrafe, duplex, etc)


J'ai un programme java qui imprime des PDF. Il utilise Apache PDFBox pour créer un objet PDDocument (à partir d'un document pdf ou d'un flux dans certains cas) puis l'envoie à l'imprimante en utilisant l'API javax.print:

private boolean print(File pdf, String printer)
{
    boolean success = false;

    try (PDDocument document = PDDocument.load(pdf))
    {
        PrintService[] printServices = PrinterJob.lookupPrintServices();
        PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
        PrinterJob job = PrinterJob.getPrinterJob();
        job.setPageable(new PDFPageable(document));

        // set printer
        if (printer != null)
        {
            for (PrintService selected : printServices)
            {
                if (selected.getName().equals(printer))
                {
                    printService = selected;
                    break;
                }
            }
        }
        job.setPrintService(printService);
        job.print();
        success = true;
    }
    catch (Exception e)
    {
        myLog.error("Printer error.", e);
    }
    return success;
}

Maintenant, je dois pouvoir dire à l'imprimante d'agrafer la chose...


Je connais le javax.imprimer.attributs API et utilisez-le avec succès pour spécifier le bac ou définir le duplex, par exemple:

// this works fine
if (duplex != null)
{               
    if (duplex.equalsIgnoreCase("short"))
    {
        myLog.debug("Setting double-sided: Short");
        attr.add(Sides.TWO_SIDED_SHORT_EDGE);
    }
    else
    {
        myLog.debug("Setting double-sided: Long");
        attr.add(Sides.TWO_SIDED_LONG_EDGE);
    }
}

Je sais qu'il y a un attribut pour agrafage:

attr.add(javax.print.attribute.standard.Finishings.STAPLE);

J'ai un Xerox Versalink B7035 avec une pièce jointe Finisher XL qui prend pleinement en charge l'agrafage (c'est-à-dire qu'il fonctionne à partir des paramètres du document MS Office), mais l'imprimante ne tient pas compte du jeu d'attributs d'AGRAFE de Java. J'ai essayé toutes les autres variantes d'attributs de base, mais j'ai rapidement constaté que l'imprimante ne prenait en charge aucun attribut de finition Java.

Ou pour le mettre dans le code, ce qui suit n'imprime AUCUN résultat:

DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
Object finishings = myPrinter.getSupportedAttributeValues(Finishings.class, flavor, null);
if (finishings != null && o.getClass().isArray())
{
    for (Finishings finishing : (Finishings[]) finishings)
    {
        System.out.println(finishing.getValue() + " : " + finishing);
    }
}

Après avoir lu ce et essayé quelques différentes choses que j'ai conclues, l'imprimante n'acceptera pas l'attribut STAPLE parce que le finisseur est une pièce jointe ou simplement parce que Xerox n'aime pas Java ou quelque chose comme ça. Alors maintenant, j'essaie de résoudre ce problème en ajoutant des commandes PJL au pdf avant de l'envoyer, comme indiqué ici. *PJL = Langue du travail d'impression

Par exemple:

<ESC>%-12345X@PJL<CR><LF>
@PJL SET STAPLE=LEFTTOP<CR><LF>
@PJL ENTER LANGUAGE = PDF<CR><LF>
[... all bytes of the PDF file, starting with '%PDF-1.' ...]
[... all bytes of the PDF file ............................]
[... all bytes of the PDF file ............................]
[... all bytes of the PDF file, ending with '%%EOF' .......]
<ESC>%-12345X

Au début, j'ai supposé qu'il y aurait juste une méthode dans la bibliothèque Apache PDFBox pour faire exactement cela, mais pas de chance. Ensuite, j'ai vérifié l'API pour Ghost4J et n'a rien vu pour le préfixe. Quelqu'un d'autre a résolu ce déjà?

Author: egerardus, 2019-04-20

1 answers

Revenir à l'impression de socket Java fait de PJL une chose:

// this works, it also printed faster than javax.print when tested
private static void print(File document, String printerIpAddress, boolean staple)
{
    try (Socket socket = new Socket(printerIpAddress, 9100))
    {
        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
        byte[] bytes = Files.readAllBytes(document.toPath());

        out.write(27); //esc
        out.write("%-12345X@PJL\n".getBytes());
        out.write("@PJL SET DUPLEX=ON\n".getBytes());

        if (staple) 
        {
            out.write("@PJL SET STAPLEOPTION=ONE\n".getBytes());
        }
        out.write("@PJL ENTER LANGUAGE=PDF\n".getBytes());
        out.write(bytes);
        out.write(27); //esc
        out.write("%-12345X".getBytes());
        out.flush();
        out.close();
    }
    catch (Exception e)
    {
        System.out.println(e);
    }
}

Les commandes PJL nécessaires provenaient de cette Fiche technique Xerox.

Il convient de noter que les mêmes commandes PJL fonctionnaient pour deux modèles Xerox différents et une imprimante Lexmark, c'est tout ce que j'avais à portée de main pour tester avec. Je ne sais pas si d'autres modèles voudront quelque chose de différent.

Vous n'avez plus besoin de la bibliothèque Apache PDFBox. Ou des bibliothèques externes du tout.

Cela peut fonctionner pour d'autres types de documents, de côté à partir de fichiers Pdf.

 0
Author: egerardus, 2019-04-21 06:58:18