Comment lire et importer un fichier .csv en groovy sur grails. J'ai un fichier .csv avec des données et
besoin d'importer dans la base de données à l'aide de l'interface utilisateur.
Comme toujours, il existe différentes possibilités de travailler avec des fichiers CSV dans Groovy.
Groovy étant totalement interopérable avec Java, vous pouvez utiliser l’une des librairies CSV existantes, par exemple. OpenCSV .
En fonction de la complexité du fichier CSV que vous utilisez, vous pouvez également utiliser les possibilités de traitement de fichier/chaîne standard de Groovy:
def sql = Sql.newInstance("jdbc:mysql://localhost:3306/mydb",
"user", "pswd", "com.mysql.jdbc.Driver")
def people = sql.dataSet("PERSON")
new File("users.csv").splitEachLine(",") {fields ->
people.add(
first_name: fields[0],
last_name: fields[1],
email: fields[2]
)
}
EDIT: Kelly Robinson vient de rédiger un article de Nice blog sur les différentes possibilités offertes pour travailler avec des fichiers CSV dans Groovy.
EDIT # 2: Comme Leonard Axelsson a récemment publié la version 1.0 de sa bibliothèque GroovyCVS, j’ai pensé que je devrais absolument l’ajouter à la liste des options.
Utiliser xlson's GroovyCSV :
@Grab('com.xlson.groovycsv:groovycsv:1.1')
import static com.xlson.groovycsv.CsvParser.parseCsv
for(line in parseCsv(new FileReader('countries.csv'), separator: ';')) {
println "Country=$line.COUNTRY, Capital=$line.CAPITAL"
}
Les noms de champs proviennent de l'en-tête du fichier CSV.
Si le fichier CSV n'a pas d'en-tête, vous pouvez spécifier les noms de champs par programme.
Exemple utilisant opencsv
@Grab('com.opencsv:opencsv:4.0')
import com.opencsv.CSVReader
import com.opencsv.CSVWriter
class TestCsvReader {
static main(args) {
def csv = '''"a","b","c"
"d","e","f"
'''
def Reader csvFileReader = new StringReader(csv)
def Writer csvFileWriter = new PrintWriter(System.out)
def CSVReader reader = new CSVReader(csvFileReader)
def CSVWriter writer = new CSVWriter(csvFileWriter)
reader.iterator().each { fields ->
writer.writeNext(fields)
}
reader.close()
writer.close()
}
}
Avec Apache Commons-CSV :
@Grab('org.Apache.commons:commons-csv:1.2')
import org.Apache.commons.csv.CSVParser
import static org.Apache.commons.csv.CSVFormat.*
import Java.nio.file.Paths
Paths.get('countryInfo.txt').withReader { reader ->
CSVParser csv = new CSVParser(reader, DEFAULT.withHeader())
for (record in csv.iterator()) {
println record.dump()
}
}
Commons-CSV a une API Nice et je le recommande.
Avec GroovyCSV :
@Grab('com.xlson.groovycsv:groovycsv:0.2')
import com.xlson.groovycsv.CsvParser
def csv = '''Name,Lastname
Mark,Andersson
Pete,Hansen'''
def data = new CsvParser().parse(csv)
for(line in data) {
println "$line.Name $line.Lastname"
}
(Tiré de ses échantillons)
Dernier recours: expression régulière.
Voici comment j'ai analysé un fichier qui pourrait contenir une chaîne d'échappement citée dans sa quatrième colonne :
File detailedStatsFile = new File("stats.csv");
detailedStatsFile.eachLine { line, number ->
// Number Of Executions, Total Milliseconds, Milliseconds per execution, "Type"
def match = line =~ /([^,]*?),\s*([^,]*?),\s*([^,]*?),\s*(?:([^",]+)|(?:"((?:[^\\"]++(?:\\")?)++)"))$/; //"
if (!match.matches())
continue;
def numberOfExecs = Integer.valueOf(match.group(1));
def totalMillis = Integer.valueOf(match.group(2));
def detailedStatName = match.group(4);
if (detailedStatName == null)
detailedStatName = match.group(5).replaceAll('\\"','"');
Je préfère un léger tweak sur la réponse acceptée: compresser les colonnes et les valeurs ensemble, au lieu d'indexer chacune par un numéro. Le résultat est un code légèrement plus court.
def sql = Sql.newInstance("jdbc:mysql://localhost:3306/mydb", "user", "pswd", "com.mysql.jdbc.Driver")
def people = sql.dataSet("PERSON")
def columns = ['first_name', 'last_name', 'email']
new File("users.csv").splitEachLine(",") {values ->
people.add([columns, values].transpose().collectEntries())
}