View Full Version : Stampa di documenti in Java
neuromatrix
26-11-2002, 13:59
Ho bisogno di stampare un file html da un'applicazione Java.
Ho scritto questo programmino per provare e in fase di compilazione va tutto bene...
[B]
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import java.io.*;
class provaPrint{
private static FileInputStream psStream;
public static void main(String[] args){
try {
psStream = new FileInputStream(System.getProperty("user.dir") + File.separatorChar + "documento.html");
} catch (FileNotFoundException ffne) {
}
if (psStream == null) {
return;
}
DocFlavor psInFormat = DocFlavor.INPUT_STREAM.TEXT_HTML_HOST;
Doc myDoc = new SimpleDoc(psStream, psInFormat, null);
PrintRequestAttributeSet aset =
new HashPrintRequestAttributeSet();
aset.add(new Copies(2));
aset.add(Sides.ONE_SIDED);
PrintService services = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob job = services.createPrintJob();
try {
System.out.println("per stampare...");
job.print(myDoc, aset);
System.out.println("stampato");
} catch (PrintException pe) {
pe.printStackTrace();
}
}
} [/B]
il problema è a run time...:confused:
infatti mi da l'eccezione:
[B]
per stampare...
sun.print.PrintJobFlavorException: invalid flavor
at sun.print.Win32PrintJob.print(Win32PrintJob.java:290)
at provaPrint.main(provaPrint.java:31)
Process completed.
[/B]
Qualcuno puo aiutarmi?
Se conoscete un altro metodo per stampare un file html (e funziona:cool: ) fatemelo sapere...
;)
ciao
neuromatrix
26-11-2002, 14:06
ah, dimenticavo....:eek:
la riga dove da l'eccezione è quella con l'istruzione
job.print(myDoc, aset);
p.s. ma come mai quando scrivo il listato su quest'area di testo del forum non mi rispetta gli spazi iniziali (l'indentatura)??
Per rispettare l'indentatura devi mettere il codice fra i tag (code) ...(/code) con le quadre al posto delle tonde
neuromatrix
26-11-2002, 16:08
Originariamente inviato da cn73
[B]Per rispettare l'indentatura devi mettere il codice fra i tag (code) ...(/code) con le quadre al posto delle tonde
ok, ho imparato a indentare...;)
è a stampare che non riesco...:rolleyes:
E' la tua stampante a non supportare il formato TEXT_HTML.
La cosa non è strana perchè non sono poi tante le stampanti che supportano un ponte diretto tra un tipo di file e "il foglio".
In genere i formati accettati sono JPEG, GIF e PNG.
Per vedere come sei messo puoi provare ad interrogare la stampante del tuo sistema:
PrintService p=PrintServiceLookup.lookupDefaultPrintService();
DocFlavor[] d=p.getSupportedDocFlavors();
for (int i=0;i<d.length;i++)
{
System.out.println("Mime found: "+d.getMimeType());
}
Se non sbaglio (e sbaglio spesso :D ) non è possibile effettuare la conversione da TEXT_HTML ad altri formati perché Java non la implementa.
Se proprio sei deciso a stampare c'è un modo per aggirare l'ostacolo ma non è proprio il massimo dell'eleganza.
Fammi sapere.
Ciao.
neuromatrix
26-11-2002, 18:51
Ho provato a fare quello che mi hai detto tu, ho scritto un programmino di prova
import javax.print.*;
class stampa{
public static void main(String[] args){
PrintService p=PrintServiceLookup.lookupDefaultPrintService();
DocFlavor[] d=p.getSupportedDocFlavors();
for (int i=0;i<d.length;i++) {
System.out.println("Mime found: "+d.getMimeType());
}
}
}
in fase di compilazione mi da l'errore
C:\Documenti\Java\Various\stampa.java:8: cannot resolve symbol
symbol : method getMimeType ()
location: class javax.print.DocFlavor[]
System.out.println("Mime found: "+d.getMimeType());
^
1 error
Process completed.
e non capisco perchè, dato che nelle api c'è getMimeType() come metodo.:confused:
ho provato anche gli altri metodi come
getMediaType()
etc.
ma niente da fare...
non capisco il perchè..
comunque sbaglio o Java sulla stampa è un po' indietro..:mad:
Ho dimenticato un paio di parentesi!
:D
"d" è un array, la riga giusta è:
System.out.println("Mime found: "+d[i].getMimeType());
Fra l'altro questo metodo di segnalare gli errori nei nuovi compilatori fa veramente schifo
symbol : method getMimeType ()
vuol dire tutto e niente!! nel jre 1.1.8 e 1.2 i messaggi erano molto più significativi!
neuromatrix
27-11-2002, 18:20
Originariamente inviato da PGI
[b]Ho dimenticato un paio di parentesi!
:D
"d" è un array, la riga giusta è:
System.out.println("Mime found: "+d[i].getMimeType());
Già...;)
anch'io non me ne sono accorto:)
In effetti concordo con cn73 per quanto riguarda la significatività dei messaggi...
il compilatore avrebbe dovuto segnalare l'errore riguardo all'array e non al metodo...:mad:
comunque l'output del prog è
Mime found: image/gif
Mime found: image/gif
Mime found: image/gif
Mime found: image/jpeg
Mime found: image/jpeg
Mime found: image/jpeg
Mime found: image/png
Mime found: image/png
Mime found: image/png
Mime found: application/x-java-jvm-local-objectref
Mime found: application/x-java-jvm-local-objectref
Mime found: application/octet-stream
Mime found: application/octet-stream
Mime found: application/octet-stream
Process completed.
quindi di stampare html direttamente non se ne parla...
mi dicevi che c'era un altro metodo (non troppo elegante), potresti accennarmi qualcosa?
grazie
:)
L'altro metodo richiede di barare spudoratamente ;)
Crei una classe estensione di JEditorPane che implementi l'interfaccia Printable, carichi la pagina html nel pannello e poi lo stampi come oggetto.
I due tipi MIME "application/x-java...bla bla" indicano che la stampante supporta la stampa di oggetti java.
Per stampare il contenuto del pannello devi però prima visualizzarlo incorporandolo in un Frame (altrimenti l'oggetto Graphics che rappresenta l'immagine del pannello resta vuoto).
Ci sarebbe anche una terza via che è la conversione del formato HTML in GIF o JPEG con la classe StreamPrintService ma la conversione del formato HTML non è supportata nativamente dal JSP quindi dovresti prima cercare in rete se qualcuno ha sviluppato il supporto (sul forum java developer di Sun sembra che ancora non ci sia, ma è un forum poco frequentato).
Se trovi una quarta via fammi sapere!
Ciao.
neuromatrix
27-11-2002, 23:02
avevo già provato con il tuo metodo B con scarsi risultati...
Non che sia migliorato, anzi...
Ho scritto 2 classi di prova:
la prima estende JEditorPane e visualizza il file html
import javax.swing.*;
import java.awt.*;
import java.net.*;
class stampaJeditHTML extends JEditorPane{
public stampaJeditHTML(){
try{
/*
* va a cercare il file nella cartella corrente e lo assegna alla stringa
*/
String htmlHelpFileName = null;
htmlHelpFileName = "file:" + System.getProperty("user.dir")
+ System.getProperty("file.separator")
+ "fatt2002n10pag1.html";
/*
* crea un nuovo URL in base al nome del file
*/
URL url = new URL(htmlHelpFileName);
/*
* visualizza la pagina
*/
this.setPage(url);
}catch (Exception e){
/*
* gestione delle eccezioni
*/
System.out.println("Impossibile caricare la pagina. \n Errore:"
+ e.getMessage());
}
}
}
la seconda implementa Printable e visualizza nel frame il JPanel con il file html
import javax.swing.*;
import java.awt.*;
import java.awt.print.*;
import javax.print.*;
class pannelloStampa extends JPanel implements Printable{
public pannelloStampa(){
this.add(new stampaJeditHTML());
}
public int print(Graphics g, PageFormat pg, int pi) throws PrinterException{
if (pi >= 1) {
return Printable.NO_SUCH_PAGE;
}
return Printable.PAGE_EXISTS;
}
public void stampa(){
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintable(this);
if (printJob.printDialog()) {
try {
printJob.print();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args){
JFrame f = new JFrame();
pannelloStampa p = new pannelloStampa();
f.getContentPane().add(BorderLayout.CENTER, p);
f.setSize(580, 500);
f.show();
p.stampa();
}
}
il problema è che mi stampa pagine VUOTE:confused: :confused:
sicuramente ho dimenticato o sbagliato qualcosa...
probabilmete manca qualcosa nell'override del metodo print dell'interfaccia Printable...
se ti va di dare un'occhiata per vedere se manca qualcosa mi faresti un bel favore:)
grazie comunque di tutto
ciao:) :)
prima il codice
import javax.swing.*;
import java.awt.*;
import java.awt.print.*;
import javax.print.*;
class pannelloStampa extends JPanel {
stampaJEditHTML jedit=new stampaJEditHTML();
public pannelloStampa(){
this.add(jedit);
}
public void stampa(){
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintable(jedit);
if (printJob.printDialog()) {
try {
printJob.print();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args){
JFrame f = new JFrame();
pannelloStampa p = new pannelloStampa();
f.getContentPane().add(BorderLayout.CENTER, p);
f.setSize(580, 500);
f.show();
p.stampa();
System.out.println(System.getProperty("user.dir"));
}
}
Seconda parte...
import javax.swing.*;
import java.awt.*;
import java.net.*;
import java.awt.print.*;
class stampaJEditHTML extends JEditorPane implements Printable{
public stampaJEditHTML(){
try{
/*
* va a cercare il file nella cartella corrente e lo assegna alla stringa
*/
String htmlHelpFileName = null;
htmlHelpFileName = "file:" + System.getProperty("user.dir")
+ System.getProperty("file.separator")
+ "doc.html";
/*
* crea un nuovo URL in base al nome del file
*/
URL url = new URL(htmlHelpFileName);
/*
* visualizza la pagina
*/
this.setPage(url);
}catch (Exception e){
/*
* gestione delle eccezioni
*/
System.out.println("Impossibile caricare la pagina. \n Errore:"
+ e.getMessage());
}
}
public int print(Graphics g, PageFormat pg, int pi) throws PrinterException{
int x = (int)pg.getImageableX();
int y = (int)pg.getImageableY();
g.translate(x, y);
paint(g);
return PAGE_EXISTS;
}
}
Il metodo print(bla bla) effettua una traslazione del contenuto dell'oggetto graphics in modo che corrisponda all'area stampabile della pagina.
L'oggetto "printable" è diventato direttamente il JEditorPane, per evitare la stampa di altri elementi che eventualmente inserirai nel pannello.
Ho provato e funziona, a parte il fatto che mi chiede se voglio stampare 9999 pagine :D .
Ciao.
neuromatrix
28-11-2002, 18:47
grande PGI!!:) :)
il tuo metodo funziona, però ho un'altro problema, a parte il fatto che anche a me cerca di stamparmi 9999 pagine (ho provato anche a modificare il metodo stampa in questo modo
public void stampa(){
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintable(jedit);
PrintRequestAttributeSet aset =
new HashPrintRequestAttributeSet();
aset.add(new Copies(1));
aset.add(MediaSizeName.ISO_A4);
aset.add(Sides.ONE_SIDED);
if (printJob.printDialog()) {
try {
printJob.print(aset);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
ma niente da fare:mad:
l'altro problema che ho è che della pagina html me ne stampa solamente una parte, solo l'angolo nord-ovest della pagina,:confused:
probabilmente è troppo larga la pagina e poichè la vede come oggetto grafico e non come pagina html mi stampa solo la parte che ci sta nella pagina
...
vorrà dire che rinuncierò a stampare dall'applicazione e stamperò dal browser...:mad:
ti ringrazio comunque di tutto;)
sei stato di grande aiuto
ciao:)
neuromatrix
28-11-2002, 19:03
ho scoperto come far stampare una pagina sola:)
bisogna inserire un if all'override di print
public int print(Graphics g, PageFormat pg, int pi) throws PrinterException{
if (pi >= 1) {
return Printable.NO_SUCH_PAGE;
}
int x = (int)pg.getImageableX();
int y = (int)pg.getImageableY();
g.translate(x, y);
paint(g);
return PAGE_EXISTS;
}
però non ho ancora scoperto come far stampare la pagina intera...:(
se ci riesco ti faccio sapere
ciao
Se il tuo problema è che la dimensione della pagina HTML da stampare è maggiore del foglio A4 e pertanto te ne stampa solo una parte allora devi ridimensionare l'oggetto graphics in modo che stia in una pagina.
public int print(Graphics g, PageFormat pg, int pi) throws PrinterException{
int x = (int)pg.getImageableX();
int y = (int)pg.getImageableY();
g.translate(x, y);
double gWidth=this.getWidth();
double gHeight=this.getHeight();
double pgWidth=pg.getImageableWidth();
double pgHeight=pg.getImageableHeight();
double scaleX=1;
double scaleY=1;
if(gWidth>pgWidth) {
scaleX=pgWidth/gWidth;
scaleY=scaleX;
}
Graphics2D g2d=(Graphics2D)g;
AffineTransform tr=g2d.getTransform();
tr.scale(scaleX,scaleY);
g2d.setTransform(tr);
paint(g2d);
return PAGE_EXISTS;
}
Il casting da Graphics a Graphics2D serve perchè Graphics non supporta le trasformazioni.
Ciao.
L'override del metodo print con un condizionale di quel tipo dovrebbe stampare solo la prima pagina di ogni oggetto printable.
Se vuoi stampare un numero imprecisato di pagine di conviene passare agli oggetti Book, decisamente più evoluti della prima versione della stampa per Java. Usarli e molto semplice, sono oggetti Printable che possono essere passati ad un PrinterJob.
public void stampa(){
PrinterJob printJob = PrinterJob.getPrinterJob();
Book book=new Book();
PageFormat pg=new PageFormat();
book.append(jedit, pg);
printJob.setPageable(book);
try {
printJob.print();
} catch (Exception ex) {
ex.printStackTrace();
}
}
Così puoi saltare la visualizzazione del pannello di controllo della stampante (anche se forse non è una buona idea, ma dipende dalla tua applicazione).
Ciao
neuromatrix
29-11-2002, 21:07
grandissimo PGI
sei troppo forte! :cool:
ho modificato come mi hai detto tu l'override di print e ho visto che funziona alla perfezione;)
mi ridimensiona esattamente il documento facendolo stare in una pagina.
per quanto riguarda invece quella cosa che "dimenticavi" riguardo al Book da inserire nel metodo stampa, beh..ho provato e ho visto che non va, mi parte la stampante ma stampa una pagina vuota (non stampa niente...)
comunque l'ho lasciato come prima...
avevo un altro problema, mi venivano dei margini troppo grandi e la pagina sembrava minuscola, ho risolto aggiungendo un attributo al metodo stampa
public void stampa(){
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintable(jedit);
PrintRequestAttributeSet aset =
new HashPrintRequestAttributeSet();
aset.add(new Copies(1));
aset.add(MediaSizeName.ISO_A4);
aset.add(Sides.ONE_SIDED);
// questo di sotto
aset.add(new MediaPrintableArea(0,0,210,297,MediaPrintableArea.MM));
//
if (printJob.printDialog()) {
try {
printJob.print(aset);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
in questo modo l'area di stampa è tutto il foglio A4
;) :)
ora, ennesimo problema non credo facilmente risolvibile è che Java, sia a stampa che nel frame, mi visualizza la pagina html con un layout un po' diverso da quello di internet explorer, questo perchè (presumo) Java supporta sì l'html 3.2 ma essendo l'html stesso un linguaggio da "interpretare" alcune cose mi vengono diverse come ad esempio i bordi della tabella, il simbolo € che non c'è (mi appare &euro al posto di €) il carattere più piccolo etc.
insomma che anche con tutto lo sforzo fatto sia da me che soprattutto da te per riuscire a stampare questa diavolo di pagina html alla fine sono sempre condannato a stampare le pagine create dall'applicazione tramite browser...:(
comunque devo dire che è stato molto istruttivo per me (e spero anche per qualcun altro che visiterà questo thread) e che senz'altro mi servirà per qualche altra applicazione.
grazie di tutto;)
alla prossima
gianluca
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.