# Drucken+Papiergröße



## Nova (1. Aug 2006)

Hallo,

Ich möchte Paketscheine drucken:
-die Paketscheine haben ziemlich annähernd DinA6 Format
-die Paketscheine sind wie Endlospapier verbunden, allerdings sind die "breiten" Seiten verbunden und nicht die schmalen wie normalerweise bei Endlospapier
-die Paketscheine müssen mit einem Nadeldrucker gedruckt werden wegen den Durchschlägen

Problem:
Der Drucker kann standardmäßig nur A4, A5, B5, Letter, Legal, Endlospapier A4
Der Versuch die Papiergröße manuell zu setzen mit

```
PrinterJob printJob = PrinterJob.getPrinterJob();
      Paper paper = new Paper();
      paper.setSize(446.0,288.0); // ca.157x105mm
      paper.setImageableArea(10.0,10.0,180.0,180.0);
      PageFormat pf = new PageFormat();
      pf.setPaper(paper);
      printJob.setPrintable(this,pf);

      if (printJob.printDialog()){
	         try {
	            printJob.print();
	         } catch(PrinterException pe){
	            System.out.println("Error printing: " + pe);
	         }
```
scheitert, da das Papierformat nachträglich auf "Legal" (oder wars "Letter"?) gesetzt wird.
Scheinbar wird das vom Drucker unterstüzte Format gewählt das am ehesten zum angegebenen Format passt...
=> das ist aber nicht gewollt, es muss genau das von mir angegebene Format sein
Das Ergebnis ist das am Ende des Druckvorgangs das Papier noch einige Zentimeter "durchgeschoben" wird, sodass die Seite insgesamt ca. 15cm durchgeschoben wurde, da ein Paketschein nur 10,5cm lang ist wurde der nächste Paketschein schon zur Hälfte eingezogen und ich kann nicht weiter drucken sondern muss das zuerst korrigieren
=> inaktzeptabel da viel zu Zeitaufwändig


Wenn ich aber z.B. in OpenOffice die Seitengröße auf 15x10,5cm stelle spoolt der Drucken am Ende nur soweit das insgesamt genau 10,5cm gespoolt wurden
=> so könnte man beliebig viele Paketscheine nacheinander drucken


Es ist also prinzipiell möglich so zu drucken wie es für meinen Zweck nötig ist, die Frage ist aber:
Wie löse ich das mit Java?
Bin schon seit 2 Tagen dran, aber komme einfach nicht weiter...


mfg
Christian


----------



## Nova (1. Aug 2006)

Hab jetzt nach stundenlangen recherchen in der Javadoc eine Lösung für selbstdefinierte Papiergrößen gefunden, allerdings mit einer Einschränkung (siehe weiter unten):
1. Man braucht eine Klasse die von "Media Size" erbt:

```
private static class MyMediaSizeName extends MediaSizeName{
	   static MyMediaSizeName TEST = new MyMediaSizeName(100);
	   
	   public MyMediaSizeName(int value){
		   super(value);
	   }
  }
```
Da bei steht "TEST" für den Namen der neuen Papiergröße und "100" für die Nummer.
Da es schon 73 (0-72) vorgegebene Papiergrößen gibt sollte man eine Zahl >= 73 wählen.


2. Dann den neuen Namen einer Größe zuweisen:


> MediaSize mediaSize = new MediaSize(101.5f,101.5f,MediaSize.MM, MyMediaSizeName.TEST);


(In diesem Beispiel 101,5x101,5mm)


3. Jetzt die Papiergröße zuweisen:
*(Geht nur mit einem PrinterJob, einem PrintJob kann man scheinbar keine andere Papiergröße zuweisen, "printJob" ist in diesem Beispiel eine Instanz von PrintererJob, also etws unglückliche Namensgebung)*
Auszug aus altem Code:

```
if (printJob.printDialog()){
	         try {
	            printJob.print();
	         } catch(PrinterException pe){
	            System.out.println("Error printing: " + pe);
	         }
    	  }
```
neuer Code:

```
if (printJob.printDialog()){
	         try {
	        	 MediaSize mediaSize = new MediaSize(101.5f,101.5f,MediaSize.MM, MyMediaSizeName.TEST);
	        	 PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
	        	 	aset.add(MyMediaSizeName.TEST);
	        	    aset.add(new MediaPrintableArea(0,0,100,100,MediaPrintableArea.MM));
	            printJob.print(aset);
	         } catch(PrinterException pe){
	            System.out.println("Error printing: " + pe);
	         }
    	  }
```



*Problem:*
Der x-Wert muss kleiner oder gleich dem y-Wert sein, d.h. das Papier muss länger als breit sein.
Da mein Papier aber 156x101,5mm groß ist kann ich so nur 101,5x101,5mm angeben. sprich mir fehlen 5cm...
Prinzipiell brauche ich auch nur 100mm, da links auf dem Paketschein ein Strichcode und die Paketnummer steht, also nicht bedruckt werden kann, dadurch das ich die Papierführung am Drucker weiter nach links geschoben habe konnte ich den Druck um 2,5cm nach rechts verschieben, trotzdem fehlen mir noch 2,5cm...

Hat jemand eine Idee wie ich entweder 
a) das Papier breiter als lang bekomme oder 
b) noch 2,5cm weiter rechts anfangen kann zu drucken
?


mfg
Christian


----------



## Mario_H (2. Aug 2006)

Du könntest versuchen den Druck zu spiegeln (also oben -> unten) [oder mein ich drehen?], sodass du den Paketschein hinterher halt rumdrehen musst.
Dann ist rechts und links auch vertauscht...


----------



## SamHotte (2. Aug 2006)

Du könntest, wenn das mit OpenOffice funzt, versuchen, dieses von Java aus anzusprechen - also eine Office-Datei erstellen und über Runtime.exec() OOo aufrufen. Auch meine ich mich zu erinnern, dass OOo eine Java-Schnittstelle hat, evtl. geht das sogar direkt, dass du eine vorhandene Vorlage dort mit Daten befüllst wie einen Serienbrief.


----------



## Nova (2. Aug 2006)

An drehen des Paketscheins habe ich auch schon gedacht, aber
a) kommt er dann auch falschrum raus, sodass man ihn nicht sofort lesen kann (für Kontroll- und Zuordnungszwecken wichtig)
b) Sind immer mehrere hundert Paketscheine miteinander verbunden und wenn ich sie gedreht drucken will muss ich beim letzten Paketschein anfangen, sprich die Paketnummern laufen rückwärts


Ich frag mich warum es überhaupt diese Einschränkung y >= x gibt? Ich sehe da keinen sinnvollen Grund und wie gesagt: OpenOffice kanns ja auch, also keine technische Einschränkung...


mfg
Christian


----------



## Nova (2. Aug 2006)

SamHotte hat gesagt.:
			
		

> Du könntest, wenn das mit OpenOffice funzt, versuchen, dieses von Java aus anzusprechen - also eine Office-Datei erstellen und über Runtime.exec() OOo aufrufen. Auch meine ich mich zu erinnern, dass OOo eine Java-Schnittstelle hat, evtl. geht das sogar direkt, dass du eine vorhandene Vorlage dort mit Daten befüllst wie einen Serienbrief.



Sowas hab ich mir auch schon überlegt (externen Programm öffnen), aber da ich keine Ahnung hab wie das OpenOffice Format aufgebaut ist kann ich keine Open-Office Dateien erstellen (vermutlich ist das auch ziemlich komplex da in der Datei ja alle Dokumentspezifischen Einstellungen gespeichert werden müssen).
Java-Schnittstelle hört sich interessant an, da müsste ich mich mal informieren, danke für den Tipp! :toll: 

Das Problem ist aber das ich dann ein neues Fenster bekomme, da erst auf drucken gehen muss, Drucker wählen und drucken und zwar für jeden Paketschein einzeln... In Java muss ich den Paketscheindrucker nur einmal einstellen und kann später im Auftragsmenü einfach sagen "EINGABEFELD Paketscheine drucken", im Eingabefeld geb ich dann z.B. "5" ein und er druckt mir 5 Paketscheine. Oder ich wähle gleich 5 Bestellungen oder so gleichzeitig aus und sage "1 Paketschein drucken" und er druckt für jeden Auftrag einen Paketschein...


Drucken in Java ist wirklich eine Katastrophe...
Warum kann ich nicht einfach als Attribut "new MediaSize(156.0f,101.5f,MediaSize.MM)" übergeben und fertig?
Nein, erstmal muss ich einen Namen vergeben (wofür ich erstmal eine Klasse die von MediaSizeName erbt erstellen muss), denn eine Abbildung zwischen dem Namen und seiner Größe herstellen (wobei er mir vorschreibt das mein Papier länger als breit sein muss) und kann dann den Namen als Attribut übergeben *kopfschüttel*
Ein Witz ist auch das es laut javadoc nicht möglich ist gleichzeitig die Papiergröße und z.B. den Papierschacht zu wählen...


mfg
Christian


----------



## SamHotte (2. Aug 2006)

Das mit dem externen Programm finde ich nicht so schlimm, wenn dadurch der Rest einfacher wird; vielleicht kannst du ja deine veränderlichen Daten als Serienbriefdatei von deinem Java-Programm aus erstellen (hab' grad kein OOo hier, aber das müsste sogar mit CSV-Dateien gehen). Wenn du die Scheine nicht 50 mal am Tag druckst, sondern z.B. nur einmal morgens, ist die Lösung via OOo praktikabel, denke ich.

Und wenn du keine besonders schönen Schriften brauchst, kannst du einfach eine Textdatei erstellen, die du dann mit OOo öffnest. Ich hab sowas mal mit Delphi/Word gemacht, eigene Tags in die Datei und am Schluss ein Word-Makro aufgerufen, das dann die "verhübschung" vornimmt.


----------



## Nova (3. Aug 2006)

Wird leider mehrmals täglich ausgedruckt (für jeden Auftrag einzeln).

Hab jetzt mal ausprobiert was passiert wenn ich die MediaSize Klasse in der Java-API umschreibe, und siehe da: die Afrage auf x < y ist tatsächlich völlig unsinnig:

```
public MediaSize(float x, float y,int units, MediaSizeName media) {
	super (x, y, units);
	/*if (x > y) {
	    throw new IllegalArgumentException("X dimension > Y dimension");
	}*/
	mediaName = media;
	mediaMap.put(mediaName, this);
	sizeVector.add(this);
    }
```
Wie man sieht hab ich einfach nur in dem von mir benötigten Konstruktor die Abfrage auskommentiert.
Jetzt kann ich auch 156x101,5mm als Papiergröße eingeben und er druckt bis zum Rand  :toll: 


Eine saubere Lösung ist das natürlich nicht da ich ja auf jedem Rechner auf dem das Programm laufen soll das JRE ändern muss...


mfg
Christian


----------



## SamHotte (4. Aug 2006)

Und wenn du eine eigene von MediaSize erbende Klasse benutzt? Dann müssteste die JRE nicht verändern ...


----------



## Nova (4. Aug 2006)

Hm, jetzt überschneiden sich die Threads doch, siehe:
http://www.java-forum.org/de/viewtopic.php?t=35115


----------

