EN · DE · RU · FR · ES

#1877 : CSVWriter.java

projectforge-common/src/main/java/org/projectforge/common/CSVWriter.java Classe utilitaire — package org.projectforge.common, projectforge-common/src/main/java/org/projectforge/common/CSVWriter.java 176 lignes · 100 code · 54 commentaires · 22 vides
Générateur de sortie CSV qui formate les données en fichiers texte délimités par des points-virgules. Compagnon de CSVParser — fournit une API de construction fluide pour écrire des lignes CSV avec un guillemetage correct. Prend en charge des surcharges typées write() pour les chaînes (avec échappement des guillemets doubles), les entiers longs, les dates (format ISO 8601) et les objets génériques. Séparateur, fin de ligne et format de date configurables. Utilisé pour les exportations de données ProjectForge (listes d'adresses, exportations de feuilles de temps, rapports financiers).

Architecture

Importations

Configuration

ParamètreValeur par défautMéthode de définition
Séparateur CSV';' (point-virgule — convention européenne)setCsvSeparator(char)
Fin de ligne"\n" (saut de ligne Unix)setCr(String)
Format de date"yyyy-MM-dd HH:mm:ss.SSS"setDateFormat(DateFormat)
Fuseau horaire des datesUTCCodé en dur dans le constructeur

API de construction fluide

Toutes les méthodes write() retournent this (l'instance de CSVWriter), permettant le chaînage de méthodes :

csvWriter.write("Nom").write("Âge").write(42L).writeEndOfLine();

Surcharges d'écriture spécifiques aux types

MéthodeFormatageGuillemetage
write(String s)Chaîne brute avec " échappé en "" (doublement)Toujours encadré par "..." — suit les règles de guillemetage RFC 4180
write(long valeur)Sortie numérique directe via PrintWriter.print()Aucun — les nombres ne sont pas entre guillemets
write(Date valeur)Formaté via dateFormat.format() en UTCEntre guillemets — les dates peuvent contenir des espaces ou des caractères spéciaux
write(Object valeur)Solution de repli : String.valueOf(valeur)Aucun — les objets génériques ne sont pas entre guillemets (risqué pour les objets contenant des virgules/guillemets)

Algorithme de guillemetage (écriture de chaînes)

La méthode write(String) implémente l'échappement CSV correct selon la RFC 4180 :

  1. Produit le séparateur si ce n'est pas la première entrée de la ligne (géré par writeSeparator() avec le drapeau firstEntry)
  2. Produit un guillemet double ouvrant (")
  3. Parcourt chaque caractère de la chaîne
  4. Si le caractère est un guillemet double ("), le produit deux fois ("") — la séquence d'échappement CSV standard
  5. Produit tous les autres caractères tels quels
  6. Produit un guillemet double fermant (")

Écriture de lignes

Logique du séparateur (writeSeparator)

Le drapeau booléen firstEntry suit si nous sommes au début d'une ligne :

Il s'agit d'un modèle classique de suivi d'état pour la sortie délimitée.

Intégration avec CSVParser

CSVWriter définit DEFAULT_CSV_SEPARATOR_CHAR = ';' comme constante publique, que CSVParser référence pour garantir un séparateur par défaut cohérent entre le lecteur et l'écrivain.

Comparaison avec les bibliothèques CSV modernes

Cette implémentation est intentionnellement minimale par rapport à Apache Commons CSV ou OpenCSV :

La simplicité reflète son origine en tant qu'outil spécialisé pour l'exportation de données ProjectForge, et non une bibliothèque CSV à usage général.

La méthode write(Object) NE met PAS la sortie entre guillemets — elle appelle String.valueOf(valeur) et écrit directement. Si le toString() de l'objet retourne une chaîne contenant des virgules, des points-virgules ou des sauts de ligne, le CSV résultant sera mal formé. Cela est acceptable car les appelants sont censés utiliser les surcharges spécifiques aux types.
La sortie des dates utilise le fuseau horaire UTC — les dates sont normalisées en UTC avant le formatage. C'est un choix délibéré pour l'échange de données : cela évite l'ambiguïté du fuseau horaire dans les exportations. Le format "yyyy-MM-dd HH:mm:ss.SSS" est de type ISO 8601 mais utilise un espace comme séparateur au lieu de 'T'.

Historique Git

868d6abb7 2025 -> 2026
63081666f En-têtes des fichiers source : 2024 -> 2025.
a73905c14 Correction de fautes de frappe dans les répertoires projectforge*/ Trouvé via codespell
b6092df09 Copyright 2023 -> 2024
ab45d51fa Copyright 2001-2022 -> 2001-2023.
5f7ef41b8 Copyright 2021 -> 2022
ceb63e8a1 En-tête du code source : (C) 2001-2021.
7c79f1922 Copyright de l'en-tête source -> 2020.