View Full Version : da email a csv/tsv/xls
Axembled
28-02-2019, 16:45
Buongiorno a tutti,
sono un neofita in tema di programmazione e avrei bisogno di qualche dritta su come progettare un programmino su java (possibilmente) per trasformare una sorgente mail in un file csv.
il mio file sorgente è una mail con delle righe predefinite; con questo voglio dire che il programmino dovrà prendere da alcune righe determinati dati (che sono le risposte di un questionario) e inserirle in file csv o excel; quindi, ad esempio, dalla riga n. 4 prendi gli ultimi 3 valori e inseriscigli nella riga 1 del file csv.
praticamente dovrei creare un dataset da una mail.
che soluzione potrei adottare per una roba di questo tipo?
grazie in anticipo! :) :)
sottovento
28-02-2019, 17:37
La libreria in dotazione di Java ti permette di leggere un file di testo, riga per riga mediante la BufferedReader. In questo modo potresti leggere il file di ingresso.
Nel caso invece che tu voglia leggere direttamente dalla tua mailbox, potresti usare la libreria gratuita javamail.
Per quanto riguarda l'output: se vuoi scrivere un file csv ti basta la libreria standard di Java (la class PrintWriter fa per te); nel caso voglia invece scrivere direttamente un file Excel, puoi utilizzare la libreria gratuita Apache POI (che fa anche mille altre cose)
Axembled
28-02-2019, 21:05
grazie mille sottovento!!!! comincio a recuperare info su quanto da te consigliato...
sottovento
28-02-2019, 22:09
Se posso permettermi, vorrei darti un consiglio: comincia a risolvere il problema piu' semplice, vale a dire leggere un file di testo (la mail) e scrivere un file di testo (in formato csv).
Una volta che hai fatto questo, potresti pensare di leggere direttamente la email tramite javamail, quindi puoi evitare di creare il file di ingresso ed automatizzare questo processo.
Infine, se hai tempo a disposizione (e voglia) potresti usare anche apache poi per generare il file Excel invece del formato csv. Attenzione, apache poi non e' semplicissima; tuttavia ci sono parecchi esempi sul sito e su stackoverflow, e scommetto che uno di questi fa al caso tuo
Axembled
28-02-2019, 22:15
si stavo cominciando così, ma essendo la prima volta che metto mani in java devo andare a micropassi :mc: :mc: :rolleyes: nel caso ti posso contattare via mp o qua sopra per qualche dritta ulteriore? ne so davvero zero di java :D
sottovento
28-02-2019, 22:53
Non ho tanto tempo ma non credo ne serva molto. Faro' del mio meglio :)
Axembled
28-02-2019, 22:59
pensi che in 20 giorni riuscirò a tirar via qualcosa? :confused: :confused: :rolleyes:
sottovento
28-02-2019, 23:04
Certo, anche meno. Dai che ce la fai!
Poi ti posso aiutare in privato e qui c'e' anche altra gente che passa ed esamina il tuo codice.
Axembled
28-02-2019, 23:08
speriamo bene... ti faccio sapere se ho grosse difficoltà
Axembled
11-03-2019, 13:25
Certo, anche meno. Dai che ce la fai!
Poi ti posso aiutare in privato e qui c'e' anche altra gente che passa ed esamina il tuo codice.
ciao sottovento,
in effetti avevi ragione, ho quasi completato il codice e funziona... ora ciò che mi resta e sul quale sto trovando un sacco di difficoltà è la conversione di una stringa in un numero; spiegato in breve:
se variabile1 contiene la parola X allora variabile 2 = 100.
come posso fare? sto trovando davvero poco in giro o forse non sto focalizzando il problema...
sottovento
11-03-2019, 14:10
Non sono sicuro di aver capito.
Intendi qualcosa cosi'?
if (variable1.contains("X"))
variable2 = 100;
o cosi'?
if (variable1.equals("X"))
variable2 = 100;
Axembled
11-03-2019, 16:54
grazie mille sottovento! era la prima :D
ma come posso inserire una if dentro un'altra if?
ho una struttura di questo genere ma mi sballa il risultato ultimo:
if (lines==(scores[i]){
if (lines==70 && sCurrentLine.contains("ParolaX"))
System.out.println("ciaociao_"); }
System.out.println("Risultato originale");}
se commento le due righe centrali il risultato va bene.
se lo lancio così mi sballa il System.out.println finale :mc: :mc: :mc: :mc: :mbe: :mbe:
Axembled
11-03-2019, 16:58
Risolto sottovento :D era questione di graffe
Axembled
12-03-2019, 12:30
ciao sottovento!
mi servirebbe una dritta per richiamare una classe (emailcheck) da un'altra (Prova2);
ho utilizzato questo codice inserito nel main di Prova2:
Runtime rt = Runtime.getRuntime();
Process ps = rt.exec("java Emailcheck args");
OutputStream os = ps.getOutputStream();
InputStream is = ps.getInputStream();
ora però ho un problemone:
se il file della classe chiamante (Prova2) è inserito nella directory della classe chiamata (Emailcheck) quest'ultimo funziona ma non funziona la classe chiamante... Dove sto sbagliando?
so 4 ore che sbatto la testa ma non ne vengo fuori :muro: :muro: :muro: :muro: :muro: :muro: :confused: :confused: :mc: :mc: :muro: :muro: :muro:
L'esito delle due classi è quello di creare un file nel loro classpath solo che:
- se lancio Prova2 inserendo il file Prova2.java nella dir di Emailcheck non mi crea il file
- stessa cosa se lancio Emailcheck.java nella dir di Prova2.
Quindi immagino che ci sia un problema di path......
Hai provato ad aggiungere al progetto come libreria la cartella dell'altro file e poi importarlo con "import com.example.ecc " ?
sottovento
12-03-2019, 14:28
Ciao
puoi provare a pubblicare il codice qui? In alternativa, se ci sono parti private o con dati sensibili, puoi spedirlo con la messaggeria privata (ma valuta prima di postarlo qui, cosi' puoi ottenere aiuto da piu' persone).
Una domanda: se sicuro di dover utilizzare due programmi separati, entrambi scritti in Java? Non e' che magari i due programmi separati possono diventare uno solo, evitando il problema?
Axembled
12-03-2019, 16:16
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Prova2 {
public static void main(String[] args) throws IOException {
Runtime rt = Runtime.getRuntime();
Process ps = rt.exec("java Emailcheck args");
OutputStream os = ps.getOutputStream();
InputStream is = ps.getInputStream();
System.out.println("Codice mail eseguito; controlla il file eml");
FileWriter writer = new FileWriter("test.csv");
writer.append("ID");
writer.append(',');
writer.append("name");
writer.append(',');
writer.append("ss_x_gruppo");
writer.append('\n');
writer.flush();
writer.close();
}}
x Kaya: la cartella l'ho aggiunta al progetto ma non capisco come fare l'import....... con import Emailcheck.Prova2 ma ritorna errore.
x sottovento: no, in realtà posso inserire tutto in uno, ma il prof mi ha suggerito di inserire il codice su script separati e collegarli tra loro...:confused:
sottovento
12-03-2019, 16:45
Ciao
alcune cose per cominciare: usa i tag CODE per inserire il codice, cosi' risulta indentato e piu' facile da capire. Inoltre, cerca di catturare le eccezioni, tutte.
In realta' sarebbe un errore catturare TUTTE le eccezioni (comprese quelle generate da errori di programmazione) ma e' un discorso lungo e la filosofia non ci interessa.
Esempio:
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Prova2 {
public static void main(String[] args) {
try
{
Runtime rt = Runtime.getRuntime();
Process ps = rt.exec("java Emailcheck args");
OutputStream os = ps.getOutputStream();
InputStream is = ps.getInputStream();
System.out.println("Codice mail eseguito; controlla il file eml");
FileWriter writer = new FileWriter("test.csv");
writer.append("ID");
writer.append(',');
writer.append("name");
writer.append(',');
writer.append("ss_x_gruppo");
writer.append('\n');
writer.flush();
writer.close();
}
catch (SecurityException | IOException | IllegalArgumentException e)
{
System.out.println("Eccezione: " + e);
e.printStackTrace(System.out);
}
catch (Exception e)
{ // Questa parte va a catturare anche le eccezioni che NON dovrebbero essere catturate
// quali il null pointer exception. Ma per ora siamo in analisi degli errori
System.out.println("Eccezione generale: " + e);
e.printStackTrace(System.out);
}
}
}
Attenzione ad una cosa:
Runtime rt = Runtime.getRuntime();
Process ps = rt.exec("java Emailcheck args");
Qui vai ad eseguire un programma java il quale deve essere nella directory corrente. E' quello che vuoi fare?
Inoltre come argomenti passi "args". Passi proprio la stringa "args", non degli argomenti. Immagino non sia quello che vuoi fare.
Un'altra cosa importante che devi ricordare e' nel momento che esegui quell'istruzione, hai creato un nuovo processo! Questo significa che i due processi (i.e. il tuo programma Prova 2 e Emailcheck) saranno eseguiti in parallelo: non resterai bloccato li' fino al termine dell'esecuzione di Emailcheck, pertanto se hai bisogno di ottenere dei risultati da Emailcheck, dovrai essere sicuro di aspettare che la sua esecuzione sia completata.
Suggerimento: invece di usare FileWriter per scrivere il file csv, potrebbe essere piu' agevole usare la PrintWriter, per esempio:
PrintWriter pw = new PrintWriter("test.csv");
pw.println("a,b,x,v");
Inoltre puoi trarre vantaggio dal try-with-resource introdotto dalla versione 8, cosi' non devi ricordarti di chiudere il file:
try (PrintWriter pw = new PrintWriter("test.csv"))
{
pw.println("Il vincitore e': " + vincitore);
}
// Una volta arrivati qui, il file e' automaticamente chiuso.
Quale ambiente di sviluppo stai usando? Gli ambienti di sviluppo piu' comuni generano automaticamente codice all'interno di un package mentre il tuo non lo e'. Inoltre generano automaticamente un file .jar mentre sembra di capire dalla tua exec() che non e' il tuo caso; stai usando direttamente il compilatore javac ed un editor di testo?
Axembled
12-03-2019, 19:03
riparto dalle basi perché mi rendo conto di avere delle lacune importanti:
- la struttura è quella nell'immagine allegata;
- lancio Prova3.java con questo codice:
package pack2;
import java.io.IOException;
public class prova3 {
public static void main(String[] args) throws IOException {
System.out.println( "ESITO_PROVA_3" );
}
}
Risultato A :
run:
ESITO_PROVA_3
BUILD SUCCESSFUL (total time: 0 seconds)
- lancio Prova4.java con questo codice:
package pack2;
import java.io.IOException;
public class prova4 {
public static void main(String[] args) throws IOException {
System.out.println( "ESITO_PROVA_4" ) ;
}
}
Risultato:
run:
ESITO_PROVA_3
BUILD SUCCESSFUL (total time: 0 seconds) :mbe: :mbe: :mbe:
Che.Diavolo.Gli.Prende? :muro: :muro: :muro:
sottovento
12-03-2019, 19:09
No, quello e' il tuo ambiente di sviluppo che probabilmente ha scritto da qualche parte che la classe di partenza (i.e. la classe dalla quale invocare il main() ) e' prova3.
Immagino che l'ambiente sia Netbeans. Se fai right-click sull'icona della classe prova4 e selezioni "Debug" dovrebbe andare.
Se hai tempo, puoi provare a rispondere alle domande del mio posto precedente?
Non scoraggiarti, mi raccomando! Stai andando bene
Axembled
12-03-2019, 19:27
sottovento, ho analizzato il problema di cui ti parlavo prima e alla fine era proprio questo...
mi continuava a lanciare sempre il primo codice, quello riferito all'email check, e non lo script comprensivo dell'invocazione di emailcheck + il filewriter (secondo codice)...
per provare su un progetto pulito ho ridotto il tutto ai minimi termini e il problema è quanto riportato nel post precedente.
ho fatto il debug e funziona ma una volta rilanciato normalmente non funziona di nuovo;...
:mc: :mc: :mc:
grazie mille per tutti questi aiuti!!
sottovento
12-03-2019, 20:12
Scusa, c'e' bisogno di chiarirsi:
- usi un ambiente di sviluppo oppure usi il compilatore javac direttamente? Sembrerebbe che tu stia usando Netbeans, ma c'e' bisogno di una conferma;
- l'ambiente di sviluppo ti genera un file .jar? Oppure usi il compilatore ed hai un insieme di file .class?
- come fai a lanciare l'applicazione? Da prompt del sistema operativo? Con quale comando?
Axembled
12-03-2019, 20:42
forse ho dato per scontato diverse cose :D :D
allora, uso netbeans e l'ambiente mi genera un file .java dentro a varie sottocartelle (quelle in foto).
per lanciare l'applicazione uso il tasto "run" di netbeans.
tieni conto, inoltre, che quando creo un nuovo progetto faccio "nuovo progetto" >> Java Application
scusami ma, come vedi, sono proprio alle prime armi... :rolleyes: :rolleyes:
sottovento
12-03-2019, 21:23
Non c'e' bisogno di scusarsi! Non credo di esser tanto meglio, e poi ho fatto le stesse domande anch'io, tempo addietro :D
Ecco cosa succede: quando hai generato il progetto, Netbeans ti ha anche generato la "class principale", vale a dire quella il cui metodo main() verra' invocato alla pressione del tasto run/debug/... (o alla pressione di CTRL-F5 e cosi' via).
Puoi vedere il nome della classe in questione facendo right-click sull'icona del progetto, selezionando "Properties" -> "Run" : fra le varie opzioni ci sara' "Main Class:" e a seguire il nome della classe il cui main() verra' lanciato.
Quindi non importa quanti main() scrivi, verra' sempre lanciato quello.
Tuttavia, se guardi le icone dei file .java che hai scritto, ti accorgerai che hanno un triangolino verde: significa che anche loro sono "eseguibili" in quanto contengono il metodo statico main().
Per poterle eseguire, ti basta fare right-click sull'icona del file col triangolino e selezionare "run file" o "debug file", a tuo piacimento. L'esecuzione partira' da li'.
Quando esegui cosi', Netbeans si preoccupa di fare le varie verifiche, compilare ("al volo", diciamo) ed eseguire.
Una volta che pero' hai finito, vorresti avere un "eseguibile" da poter usare senza dover caricare l'ambiente Netbeans.
Per ottenerlo, occorre fare right-click sul nodo del progetto e selezionare "Clean and Build". Nella directory del progetto verra' creata una directory "dist" contenente il tuo jar (e la directory "lib" nel caso abbia bisogno di ulteriori librerie).
Per eseguire il software senza l'ambiente NetBeans, una volta che hai il .jar, scriverai da prompt di sistema:
java -jar <nome del tuo file .jar>
il software andra' in esecuzione. Se il tuo software ha un'interfaccia grafica puoi anche semplicemente fare doppio click sul file .jar (attenzione pero': se non hai interfaccia grafica non vedrai nulla).
Ovviamente quando esegui il file .jar, java mandera' in esecuzione il main() contenuto nella Main Class. Ti risparmio i dettagli.
Se invece vuoi eseguire un altro main() contenuto in un'altra classe, dovrai scrivere qualcosa del tipo
java -cp <nome del file file jar> <nome della classe>
dove <nome della classe> e' il nome cosi' come lo hai scritto nel tuo file (quindi senza estensioni) preceduto dal nome del package, per esempio:
java -cp mioprogetto.jar pack2.prova3
(Ricorda le convenzioni java sui nomi, le rispettano tutti: i nomi delle classi devono avere l'iniziale maiuscola)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.