Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    [Java] Gestire un file .pdf aperto e avviare la stampa

    Salve a Tutti....
    Con l'aiuto delle librerie iText riesco a creare dei report
    in pdf, ma c'è un problema che non riesco a gestire.

    Se nel momento che creo il file pdf, che per eventualità
    dovute all'applicazione, può avere lo stesso nome di un altro
    pdf già creato, e quest'ultimo è aperto da Adobe Reader,
    il codice mi va in errore.

    Non so come procedere....
    codice:
    File file = new File("pdfs\\newpdf.pdf");
    if(file.canExecute()) .....
    L'unica cosa che riesco ad ottenere è se il file è in esecuzione,
    ma non so come chiuderlo!!!

    Altra cosa....
    come lancio la stampa di un determinato file.pdf
    senza sapere sul sistema che stampanti
    e la versione di AdobeReader installate?

    Grazie a tutti

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Se il file è aperto da un'applicazione esterna (come, appunto, Reader) non ci puoi fare assolutamente nulla: nemmeno chiuderlo, servono privilegi di amministrazione e, in ogni caso, è un'operazione che va fatta nell'ambito del sistema operativo (quindi, niente Java puro, eventualmente JNI).

    La stampa è un altro punto cruciale. Non esiste un modo pulito per farlo e gli unici a funzionare sono comunque legati al programma che si lancia per la stampa (Adobe Reader, ad esempio).

    Io mi sono trovato particolarmente bene con FoxIt (al posto di Adobe Reader che mi ha sempre dato parecchi problemi, quando invocato per la stampa, come ad esempio il fatto che si apre sempre la finestra di Reader, che poi va chiusa usando, appunto, JNI o un programma esterno che se ne occupi: troppo macchinoso).

    Il comando da dare per la stampa di un PDF (che ovviamente deve esistere come file fisico) con FoxIt è il seguente:

    codice:
    Percorso/Al/File/Eseguibile/Foxit nomeDelPdf /p
    Il percorso all'eseguibile di foxit è ovviamente il percorso completo del programma.
    Il parametro /p permette di stampare sulla stampante predefinita, in alternativa è possibile dare il comando /t seguito dal nome della stampante in cui stampare.

    Per Acrobat Reader è pressappoco uguale, ma purtroppo viene aperta la finestra del programma, su cui viene caricato il PDF e poi rimane lì (a differenza di Foxit che viene eseguito in background e si chiude automaticamente).


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Grazie LeleFT,
    avevo anche trovato un vecchio thread sul forum
    in cui parlavate proprio della stampa con Adobe Reader.

    Supponiamo che, per la stampa, mi stia bene che si apra la finestra di Adobe,
    per il percorso dell'eseguibile devo tener conto che sia sempre lo stesso in tutti i pc!!?
    Eventualmente posso mettere un controllo che se non trova l'eseguibile
    di Adobe mi apre il file .pdf e poi sarà l'utente a lanciare la stampa!!
    Che dici?

    Mentre per la questione di non poter chiudere Adobe Reader per poter
    leggere il file con iText o poterlo cancellare, il codice
    if(file.canExecute()) ..... è corretto per verificare se quel file
    è già in uso da un altro processo!? Perchè posso far comparire una finestra
    di avviso in cui chiedo all'utente di chiudere Adobe prima di procedere con
    le operazioni!!!

    Come sempre grazie per l'aiuto

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Originariamente inviato da Wolvy23
    Supponiamo che, per la stampa, mi stia bene che si apra la finestra di Adobe,
    per il percorso dell'eseguibile devo tener conto che sia sempre lo stesso in tutti i pc!!?
    Beh, metti il percorso dentro un file di configurazione dell'applicazione: la configurazione sarà fatta per ciascun PC dove, ovviamente, il Reader può essere installato ovunque.

    Eventualmente posso mettere un controllo che se non trova l'eseguibile
    di Adobe mi apre il file .pdf e poi sarà l'utente a lanciare la stampa!!
    Che dici?
    Certo... io preferisco mettere il percorso all'eseguibile come parametro di configurazione dell'applicazione, così da non dover "scomodare" l'utente per la stampa.

    Mentre per la questione di non poter chiudere Adobe Reader per poter
    leggere il file con iText o poterlo cancellare, il codice
    if(file.canExecute()) ..... è corretto per verificare se quel file
    è già in uso da un altro processo!? Perchè posso far comparire una finestra
    di avviso in cui chiedo all'utente di chiudere Adobe prima di procedere con
    le operazioni!!!
    No, canExecute() non va bene. Il canExecute() testa solo due cose:
    1) Che il file esista
    2) Che l'applicazione abbia i permessi per poterlo eseguire (permessi nel senso di credenziali dell'utente)

    Del resto è semplice: se provi ad eseguire un canExecute() su un PDF aperto da Adobe, il metodo ritorna true (perchè il file esiste e l'applicazione ha le credenziali per aprirlo... ma non ci riuscirà perchè in uso).

    L'unico modo sicuro per verificare di avere a disposizione il file è provare a "cancellarlo". Sembra una cosa assurda, ma non lo è così tanto: se la tua applicazione ha bisogno di modificare un file, la cosa più facile da fare per evitare che altri concorrano per il file è quella di spostarlo in una directory di lavoro. Lo spostamento si traduce in una copia + cancellazione (e la cosa è "atomica" se fatta usando l'apposito metodo "renameTo()"). Se lo spostamento va a buon fine, il file è tutto tuo ed è anche "al sicuro" dentro la tua cartella di lavoro... onere tuo spostarlo nuovamente al suo posto alla fine dell'elaborazione.

    codice:
    // Supponiamo che la directory di lavoro si chiami "work"
    File originalFile = new File("pippo.pdf");
    File workDir = new File("./work/");
    File workFile = new File(workDir, originalFile.getName());
    
    if ( originalFile.renameTo(workFile) ) {
       // Il file è tutto tuo e ora puoi lavorarci su
       // usando l'oggetto "workFile"
    } else {
       // Il file è in uso da altra applicazione
    }

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Grazie Lele,
    ho adattato il tuo codice e funziona bene.

    Non ho capito bene però il discorso della stampa!!
    Cosa intendi per "metti il percorso dentro un file di configurazione dell'applicazione" ?

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Originariamente inviato da Wolvy23
    Non ho capito bene però il discorso della stampa!!
    Cosa intendi per "metti il percorso dentro un file di configurazione dell'applicazione" ?
    Siccome hai parlato di "diversi PC", immagino che l'applicazione andrà installata su diversi PC. Bene, ciascuna installazione dovrebbe essere accompagnata dal suo file di configurazione (un file che l'applicazione dovrebbe leggere all'avvio) dentro al quale vai a settare le configurazioni di ciascun PC. Siccome su ciascun PC l'Adobe Reader può essere installato su un percorso diverso, nel file di configurazione ci andrai a scrivere il percorso dell'eseguibile del Reader che si trova su quel particolare PC.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  7. #7
    Il discorso dell'installazione capita proprio a fagiuolo

    Ti spiego come fin ora ho strutturato la mia applicazoine......

    Dal Project in Eclipse esporto tutto in un file "Runnable JAR File"
    con l'opzione "Extract required libraries into generated JAR"
    che non so se è l'opzione migliore.

    Nella cartella/dir dove deve girare l'applicazione,
    esempio PippoApp, quindi la cartella che dovrei distribuire/installare sui
    vari pc, inserisco le cartelle che servono all'applicazione....

    PippoApp
    |_ Pippo.jar
    |_ image\ .... contiene le immagini caricate dalla app
    |_ font\... contiene dei font usati dalla app
    |_ debug\... la app scrive dei file.txt di debug se viene lanciata con parametro "si" *
    |_ suoni\... contiene i suoni usati dalla app

    Nella app uso una Classe che ho chiamato DatiSystem(),
    una delle prime ad essere istanziata appena si lancia
    il main.... DatiSystem datiSys = new DatiSystem();
    codice:
    package utility;
    
    import java.awt.Dimension;
    import java.awt.Toolkit;
    
    public class DatiSystem {
    	
    	private Toolkit mioToolkit;
    	public Dimension risoluzioneSchermo;
    
    	public DatiSystem() {
    		mioToolkit = Toolkit.getDefaultToolkit();
    		setRisSchermo();
    		
    		System.out.println("\nDATI del SISTEMA: "+
    		"\n\t> file.separator= "+System.getProperty("file.separator")+
    		"\n\t> java.class.path= "+System.getProperty("java.class.path")+
    		"\n\t> java.class.version= "+System.getProperty("java.class.version")+
    		"\n\t> java.home= "+System.getProperty("java.home")+
    		"\n\t> java.version= "+System.getProperty("java.version")+
    		"\n\t> java.vendor= "+System.getProperty("java.vendor")+
    		"\n\t> java.vendor.url= "+System.getProperty("java.vendor.url")+
    		"\n\t> os.name= "+System.getProperty("os.name")+
    		"\n\t> os.arch= "+System.getProperty("os.arch")+
    		"\n\t> os.version= "+System.getProperty("os.version")+
    		"\n\t> path.separator= "+System.getProperty("path.separator")+
    		"\n\t> user.dir= "+System.getProperty("user.dir")+
    		"\n\t> user.home= "+System.getProperty("user.home")+
    		"\n\t> user.name= "+System.getProperty("user.name")+
    		"\n\t> risoluzione schermo (HEIGHT) = "+risoluzioneSchermo.getHeight()+
    		"\n\t> risoluzione schermo (WIDTH) = "+risoluzioneSchermo.getWidth());
    	} // FINE COSTRUTTORE
    
    	private void setRisSchermo() {
    		risoluzioneSchermo = mioToolkit.getScreenSize();
    	} // FINE METODO
    
    	public String userHP() {
    		return System.getProperty("user.home");
    	} // FINE METODO
    
    } // FINE CLASSE
    Da questa Classe acquisisco info sul pc in cui gira l'app,
    al momento uso solo la risoluzione dello schermo, per una questione
    garfica, e la "user.home" che sarebbe il percorso alla cartella documenti
    dell'user del pc, ove vado a crearvi una DIR che sfrutta la app
    per creare altre subDir e salvarci file .txt e .pdf, esempio......

    PippoDoc
    |_ txt\... contiene i file .txt creati
    |_ pdf\ .... contiene file .pdf creati dalla app
    |_temp\... che è una cartella che crea e cancella ogni volta che effettua
    l'operazione di verifica sul file .pdf che mi hai suggerito nel post precedente


    Premesso questo.....
    Proprio ieri ho verificato, provando la app su un altro pc,
    che questa non si avvia affatto se la versine di Java installata
    è ante 7.21, infatti c'era la 6.
    Quindi primo problema: come verificare la versione di Java
    installata e se ciò è possibile da parte della App, come può
    questa avvisare l'utente che deve aggiornare Java se la App
    stessa non può avviarsi!!? Capito che intendo?
    Perché avevo anche pensato di inserire un'altra subDir in PipoApp,
    ad esempio:

    PippoApp
    |_ Pippo.jar
    |_ .....\ ....
    |_ versione\.... dove inserire l'installer della versione aggiornata da avviare in caso serva

    Secondo problema: come faccio ad indicare il percorso all'eseguibile di AdobeReader se non conosco i vari pc!!?
    Comunque, volendo bypassare questa parte, cioè, se mi sta bene che per stampare
    un file.pdf si apra il Reader, è possibile inviare all'eseguibile un parametro per
    avviare direttamente la stampa? Aggiungendola al codice:
    Desktop.getDesktop().open(new File(filePdf.getAbsolutePath()));


    Infine.... sono ancora alla ricerca di un modo per creare l'installer;
    è vero che ho tutto l'occorente nella cartella PippoApp e basta mettere
    questa in un file autoestraente e il gioco è fatto, ma se volessi installare
    anche un collegamento al desktop o al menù di avvio di Windows ad esempio!?

    Grazie come sempre per l'attenzione.

    * Su questo punto avrei una domanda: come aggiungo il parametro quando avvio il file .jar!?
    Ho provato a rinominarlo tipo "Pippo si" ma non funziona!!!

  8. #8
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,315
    Originariamente inviato da Wolvy23
    Dal Project in Eclipse esporto tutto in un file "Runnable JAR File"
    con l'opzione "Extract required libraries into generated JAR"
    che non so se è l'opzione migliore.
    Io non uso Eclipse, ma non mi pare la scelta migliore: le librerie non andrebbero mai incorporate nel JAR dell'applicazione, ma tenute separate (generalmente in una directory "lib"), in modo da poter essere eventualmente aggiornate. Tieni presente, inoltre, che non tutti i produttori delle librerie consentono l'incorporazione, ed eventualmente è necessario verificare sulla licenza d'uso. Per ovviare a qualunque problema, quindi, meglio tenerle fuori.

    Proprio ieri ho verificato, provando la app su un altro pc,
    che questa non si avvia affatto se la versine di Java installata
    è ante 7.21, infatti c'era la 6.
    Quindi primo problema: come verificare la versione di Java
    installata e se ciò è possibile da parte della App, come può
    questa avvisare l'utente che deve aggiornare Java se la App
    stessa non può avviarsi!!? Capito che intendo?
    Non è compito nell'applicazione verificare che il sistema abbia i requisiti minimi (se non ce li ha non parte): è l'installatore (che può essere una persona fisica o un programma software esterno) che deve preoccuparsene. Se hai un installer esterno, dovrebbe essere questo a preoccuparsi della versione minima di Java. Se sei tu ad effettuare l'installazione a mano, sei tu che ti devi preoccupare dei requisiti minimi.

    Perché avevo anche pensato di inserire un'altra subDir in PipoApp,
    ad esempio:

    PippoApp
    |_ Pippo.jar
    |_ .....\ ....
    |_ versione\.... dove inserire l'installer della versione aggiornata da avviare in caso serva
    Esistono dei programmi che riescono a costruire degli installer "intelligenti", che sono in grado di verificare se il sistema è equipaggiato con una versione di Java sufficientemente aggiornata. Credo che potresti trovare questi programmi con una veloce ricerca in Google (io non ne conosco, non avendone bisogno).

    Secondo problema: come faccio ad indicare il percorso all'eseguibile di AdobeReader se non conosco i vari pc!!?
    Anceh qui: se l'installazione avviene a mano, si tratta semplicemente di scrivere nel file di configurazione a mano. Altrimenti si potrebbe pensare ad una cosa del genere:

    1) L'applicazione verifica che esista la configurazione del percorso ad Acrobat.
    2) Se non c'è questa configurazione, chiede all'utente il percorso ad Acrobat (la verifica della correttezza delle informazioni è un altro paio di maniche, ma può essere sufficiente verificare che esista l'eseguibile); una volta verificato che il percorso è corretto, salva questa informazione nel file di configurazione.

    Comunque, volendo bypassare questa parte, cioè, se mi sta bene che per stampare
    un file.pdf si apra il Reader, è possibile inviare all'eseguibile un parametro per
    avviare direttamente la stampa? Aggiungendola al codice:
    Desktop.getDesktop().open(new File(filePdf.getAbsolutePath()));
    No. Il comando open() dell'oggetto Desktop (come dice il nome stesso) serve solo ad "aprire" il file. Questo comando si traduce nella ricerca dell'eseguibile adatto al tipo di file, lancio dell'eseguibile con parametro il file da aprire. Ulteriori parametri non vengono aggiunti.

    Infine.... sono ancora alla ricerca di un modo per creare l'installer;
    è vero che ho tutto l'occorente nella cartella PippoApp e basta mettere
    questa in un file autoestraente e il gioco è fatto, ma se volessi installare
    anche un collegamento al desktop o al menù di avvio di Windows ad esempio!?
    Come detto prima, esistono dei programmi appositi che consentono di creare gli installer (e anche di verificare i requisiti minimi). Cerca con Google, perchè al momento non me ne vengono in mente.

    * Su questo punto avrei una domanda: come aggiungo il parametro quando avvio il file .jar!?
    Ho provato a rinominarlo tipo "Pippo si" ma non funziona!!!
    Eventuali parametri si passano normalmente dopo il comando:

    codice:
    java -jar NomeApplicazione.jar parametri

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  9. #9
    Ok, grazie dei consigli.
    Per le librerie ho già risolto usando una cartella
    apposita per queste.

    Cercherò un software per creare l'installer,
    sperando che di trovarne uno con licenza gratuita,
    altrimenti dovrò affidarmi al buon vecchio file txt "leggimi"

    Per quando riguarda l'eseguibile di Adobe, proverò anche qui
    a mettere in pratica i tuoi suggerimenti.

    Grazie, gentilissimo come sempre

  10. #10
    Originariamente inviato da Wolvy23
    Ok, grazie dei consigli.
    Per le librerie ho già risolto usando una cartella
    apposita per queste.

    Cercherò un software per creare l'installer,
    sperando che di trovarne uno con licenza gratuita,
    altrimenti dovrò affidarmi al buon vecchio file txt "leggimi"

    Per quando riguarda l'eseguibile di Adobe, proverò anche qui
    a mettere in pratica i tuoi suggerimenti.

    Grazie, gentilissimo come sempre
    Ma... Anche se non lo trovi free sei un programmatore scrivitelo....

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.