Probleme beim Drucken auf einen PDF-Drucker

inflamer

Bekanntes Mitglied
Hallo zusammen,

damit PDF-Drucker im Allgemeinen das gedruckte Dokument mit korrekten Seitenmaßen erzeugen, muss man anscheinend im Code dem PrinterJob ein PageFormat-Objekt mitteilen, welches die korrekten Abmessungen enthält:

Java:
double pageWidthMM = 100, pageHeightMM = 600;

Paper paper = new Paper();
paper.setSize(pageWidthMM * 72.0 / 25.4, pageHeightMM * 72.0 / 25.4);
PageFormat pageFormat = new PageFormat();
pageFormat.setPaper(paper);

...

printerJob.setPrintable(printable, pageFormat);

Sonst wird standardmäßig eine PDF im DIN A4 Format erzeugt.

Nun kommt aber eine Merkwürdigkeit ins Spiel, die ich mir noch nicht so recht erklären kann: Das Ganze funktioniert bestens bei bestimmten Seitenabmessungen, wie etwa jenen aus obigem Code (100 x 600 mm). Bei anderen Abmessungen funktioniert es jedoch gar nicht. Ersetzt man im Code die beiden Variablen z.B. durch 33 x 50 mm und schaut sich anschließend unter Adobe Reader die Eigenschaften der erzeugten PDF an, so wird dort 37,0 x 52,2 mm angezeigt. 😳

Zu erwähnen ist noch, dass ich mit 2 verschiedenen PDF-Druckern teste - 7-PDF und PDFCreator, bei beiden kommt stets jeweils das gleiche Ergebnis heraus.

Ich kann mir leider auch keinen Reim darauf machen, WANN die Abmessungen korrekt übernommen werden und wann nicht, welche "Gesetzmäßigkeit" also überhaupt dahintersteckt. Manche Zahlen (Abmessungen) werden korrekt in die PDF übernommen, andere nicht - warum auch immer.

Wäre dankbar für eure Ideen!
 
Zuletzt bearbeitet:
Bist du dir sicher dass die PDF-Drucker eigene/"schraege" Papiergroeszen annehmen, und diese nicht auf konfigurierte zurueckfallen? Also dass du dem PDF-Drucker erst beibringen musst dass es Papier in diesen Groeszen gibt.
 
Danke für die Antwort!

Ja, schon. Adobe Reader zeigt die Abmessungen (z.B. 100x600) dann auch exakt an. Ich habe es auch mit diversen anderen "schrägen" Abmessungen versucht. Teilweise klappt's auch damit, aber eben nur mit manchen, was ja mein eigentliches Problem ist...

Unbenannt - 1.png
 
Hier noch mal ein funktionierendes Schnapszahlen-Beispiel:

Unbenannt - 1.png

Mittlerweile habe ich die leise Vermutung, dass das Format vor allem dann nicht übernommen wird, wenn die Abmessungen (grob) kleiner als A5 sind...
 
Hab das gerade mal unter Linux ausprobiert und ein Beispiel von Oracle angepasst (Spoiler wg. Oracle-Copyright-Notice):
Java:
/*
 * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle or the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.print.*;
 
public class HelloWorldPrinter implements Printable, ActionListener {
 
 
    public int print(Graphics g, PageFormat pf, int page) throws
                                                        PrinterException {
 
        if (page > 0) { /* We have only one page, and 'page' is zero-based */
            return NO_SUCH_PAGE;
        }
 
        /* User (0,0) is typically outside the imageable area, so we must
         * translate by the X and Y values in the PageFormat to avoid clipping
         */
        Graphics2D g2d = (Graphics2D)g;
        g2d.translate(pf.getImageableX(), pf.getImageableY());
 
        /* Now we perform our rendering */
        g.drawString("Hello world!", 100, 100);
 
        /* tell the caller that this page is part of the printed document */
        return PAGE_EXISTS;
    }
 
    public void actionPerformed(ActionEvent e) {
         double pageWidthMM = 33, pageHeightMM = 50;
         Paper paper = new Paper();
         paper.setSize(pageWidthMM * 72.0 / 25.4, pageHeightMM * 72.0 / 25.4);
         PageFormat pageFormat = new PageFormat();
         pageFormat.setPaper(paper);

         PrinterJob job = PrinterJob.getPrinterJob();
         job.setPrintable(this, pageFormat);
         boolean ok = job.printDialog();
         if (ok) {
             try {
                  job.print();
             } catch (PrinterException ex) {
              /* The job did not successfully complete */
             }
         }
    }
 
    public static void main(String args[]) {
 
        UIManager.put("swing.boldMetal", Boolean.FALSE);
        JFrame f = new JFrame("Hello World Printer");
        f.addWindowListener(new WindowAdapter() {
           public void windowClosing(WindowEvent e) {System.exit(0);}
        });
        JButton printButton = new JButton("Print Hello World");
        printButton.addActionListener(new HelloWorldPrinter());
        f.add("Center", printButton);
        f.pack();
        f.setVisible(true);
    }
}

Ergebnis: im Druckerdialog ist erstmal A4 ausgewählt, dort "Custom" ausgewählt, die Seitenränder auf 0 gestellt und erhalte:
Bildschirmfoto von »2021-10-28 13:53:49«.png
 
@mihe

Wenn du im Druckdialog nichts änderst, was ist dann das Ergebnis?

Hab' das Ganze nochmal mit dem Win10-eigenen PDF-Drucker ausprobiert. Der scheint sich um das richtige Format noch weniger zu scheren, sondern bäckt ohne wenn und aber einfach A4-Seiten.
 
[CODE lang="java" title="Ausweis mit Format 85,7 * 54 mm" highlight="17"] try (PDDocument doc = new PDDocument()) {
// Page 1
PDFont font = PDType1Font.HELVETICA;
// PDFont font2 = PDType1Font.TIMES_BOLD_ITALIC;

String ordnerfont = "C:/xx";
PDFont fontCondensedBold = PDType0Font.load(doc, new File(ordnerfont + "d-din.condensed-bold.ttf"));


String ordner = "C:/xx";
String outfile = ordner + ausweisnr + "/Ausweis-" + ausweisnr + "-" + System.currentTimeMillis() + ".pdf";

// ----------------------------------------------------------------------------------------------
// Page Definitionen
// ----------------------------------------------------------------------------------------------

PDPage page = new PDPage(new PDRectangle(243f, 153f));
// PDPage page = new PDPage(PDRectangle.A4); //

doc.addPage(page);
PDRectangle pageSize = page.getMediaBox();
Float hoch = pageSize.getHeight();

float hochRest = hoch;

PDPageContentStream contentStream = new PDPageContentStream(doc, page, AppendMode.APPEND, false);

contentStream.setFont(font, fontSize);[/CODE]

Ich habe Ausweise zu drucken, die ein spezielles Format benötigen. Ich habe dies in der Zeile 17 im Pixelformat angegeben und bekomme in Adobe Reader das gewünschte Format 85,7 * 54 mm heraus.
Bitte beachte, wenn du im Pixelformat die Zeilen oder Logos ausgibst. Die Pixel werden von page.getHeight() bis 0 abgearbeitet.

Ich verwende

[CODE lang="java" title="POM"] <dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox-app -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-app</artifactId>
<version>2.0.20</version>
</dependency>[/CODE]

Java:
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
import org.apache.pdfbox.pdmodel.graphics.image.JPEGFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.tools.PrintPDF;
import org.apache.pdfbox.util.Matrix;
 
Zuletzt bearbeitet:
(Bin der Thread-Ersteller, sorry für die späte Antwort.)

Aaalso, mein Fazit nach langer Fummelei: Der jeweilige PDF-Drucker entscheidet offenbar selbst, in welchem Fall er die per Java übergebene Seitengröße übernimmt und in welchem nicht (es sei denn, man greift in den Druckvorgang wie von @mihe7 beschrieben aktiv ein). Für Letzteres entscheidet er sich vor allem wohl dann gern, wenn ihm die Seitengröße zu klein erscheint - was auch immer "zu klein" auch sein soll...

Gruß
 

Neue Themen


Zurück
Oben