Je souhaite renvoyer un objet au format CSV avec en-tête et filtre multilignes en Java

1.Tout d'abord

Comme il était nécessaire de créer un format csv capable de filtrer les champs de sortie par en-tête multiligne et par nom de champ, décrivez le programme considéré comme la bibliothèque utilisée.

2.CsvMapper/CsvSchema

Vous pouvez facilement convertir un objet (json) en csv avec la bibliothèque Jackson (jackson-dataformat-csv). Je l'ai utilisé cette fois.

// getter/setter est obligatoire mais omis
class TestObj {
  private String field1 = "aaa";
  private String field2 = null;
  private String field3 = "ccc";
}
TestObj obj = new TestObj();
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(TestObj.class).withHeader();

try {
  System.out.println(mapper.writer(schema).writeValueAsString(obj));
} catch(JsonProcessingException e) {
  //Traitement des erreurs (provisoire)
  e.printStackTrace();
}

[production]

field1,field2,field3
aaa,,ccc

Vous pouvez également faire ce qui suit

CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(TestObj.class).withHeader().withNullValue("<empty>");

[production]

field1,field2,field3
aaa,<empty>,ccc
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(TestObj.class).withHeader().withLineSeparator("|");

[production]

"field1","field2","field3"|"aaa",,"ccc"|
List<TestObj> objs = new ArrayList<TestObj>() {
  {
    add(new TestObj());
    add(new TestObj());
    add(new TestObj());
  }
};
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(TestObj.class).withHeader();

[production]

field1,field2,field3
aaa,,ccc
aaa,,ccc
aaa,,ccc

Il convient de noter qu'il ne prend pas en charge les modifications suivantes apportées aux objets imbriqués.

//Peut être converti en csv
class TestObj {
  private String field1 = "aaa";
  private String field2 = "bbb";
  private String field3 = "ccc";
}

//Ne peut pas être converti en csv
class TestObj2 {
  TestObj obj = new TestObj();
  private String field4 = "aaa";
}

3. Filtrer par en-tête et champ multilignes et sortie

Créez quelque chose qui affiche le nom du champ et le nom du type de l'objet sous forme d'en-têtes (2 lignes).

Malheureusement, jackson ne prend pas en charge plusieurs en-têtes et filtres, je l'ai donc créé moi-même.


public static void main(String[] args) {
	TestObj obj = new TestObj();
	List<Field> fields = Arrays.asList(obj.getClass().getDeclaredFields());
	CsvMapper mapper = new CsvMapper();
	CsvSchema schema = mapper.schemaFor(TestObj.class);
	
	//Champ à filtrer (entrée externe à l'origine)
	List<String> filterParam = new ArrayList<String>() {
		{
			add("field1");
			add("field3");
		}
	};
	//Créer plusieurs en-têtes et filtres
	String header = createHeader(obj, filterParam, fields);
	List<String> bodies = new ArrayList<>();
	try {
		bodies = Arrays.asList(mapper.writer(schema).writeValueAsString(obj).split(","));
	} catch (JsonProcessingException e) {
		//Traitement des erreurs (provisoire)
		e.printStackTrace();
	}
	String body = filter(bodies, filterParam, fields);
	
	//Initialement connecté et retourné
	System.out.println(header);
	System.out.println(body);
}

private static String createHeader(TestObj obj, List<String> param, List<Field> fields) {
	String fieldHeader = fields.stream().filter(o -> param.contains(o.getName())).map(o -> o.getName
)
			.collect(Collectors.joining(","));
	String typeHeader = fields.stream().filter(o -> param.contains(o.getName())).map(o -> {
		String typeName = o.getType().getName();
		return typeName.substring(typeName.lastIndexOf(".") + 1, typeName.length());
	}).collect(Collectors.joining(","));
	return fieldHeader + "\n" + typeHeader;
}

private static String filter(List<String> bodies, List<String> param, List<Field> fields) {
	if (param == null || param.isEmpty()) {
		return bodies.stream().collect(Collectors.joining(","));
	}
	List<String> res = new ArrayList<>();
	for (int i = 0; i < fields.size(); i++) {
		String fieldName = fields.get(i).getName();
		if (param.contains(fieldName)) {
			res.add(bodies.get(i));
		}
	}
	return res.stream().collect(Collectors.joining(","));
}

[Résultat de sortie]

field1,field3
String,String
aaa,ccc

Site de référence

CsvSchema http://fasterxml.github.io/jackson-dataformat-csv/javadoc/2.8/com/fasterxml/jackson/dataformat/csv/CsvSchema.html#withoutColumns()

Plusieurs façons de concaténer des chaînes séparées par des virgules en Java https://qiita.com/shisama/items/b27d16b3aeb1baf055b1

Concaténation de chaînes dans Java 8 https://qiita.com/lonerydeveloper/items/9f7c977c039ad4d24d30

Recommended Posts

Je souhaite renvoyer un objet au format CSV avec en-tête et filtre multilignes en Java
Je souhaite envoyer un e-mail en Java.
Je veux ForEach un tableau avec une expression Lambda en Java
Je veux revenir à l'écran précédent avec kotlin et java!
Même en Java, je veux afficher true avec un == 1 && a == 2 && a == 3 (édition PowerMockito)
Je veux utiliser java8 forEach avec index
rsync4j --Je veux toucher rsync en Java.
Même en Java, je veux afficher true avec un == 1 && a == 2 && a == 3 (Black Magic)
Je veux faire quelque chose comme "cls" en Java
Je veux faire des transitions d'écran avec kotlin et java!
Je souhaite créer une applet Java sans utiliser d'IDE
Je veux pousser une application créée avec Rails 6 vers GitHub
Je souhaite envoyer manuellement un e-mail d'autorisation avec Devise
Je veux implémenter diverses fonctions avec kotlin et java!
Convertir un tableau bidimensionnel au format csv avec l'API Java 8 Stream
[Java] Je souhaite tester l'entrée standard et la sortie standard avec JUnit
Je souhaite simplifier l'instruction if-else de la branche conditionnelle en Java
Après avoir publié un article avec Rails Simple Calendar, je souhaite le refléter dans le calendrier.
Je veux écrire une boucle qui fait référence à un index avec l'API Stream de Java 8
Je veux renvoyer un type différent de l'élément d'entrée avec Java8 StreamAPI Reduce ()
J'ai envoyé un e-mail en Java
J'ai essayé d'interagir avec Java
J'ai essayé de créer une application Android avec MVC maintenant (Java)
J'ai fait une annotation en Java.
[Java] Affiche le résultat de ffprobe -show_streams dans JSON et mappe-le à un objet dans Jackson
Je veux afficher des images avec REST Controller de Java et Spring!
Je souhaite sélectionner plusieurs éléments avec une disposition personnalisée dans la boîte de dialogue
(Limité à Java 7 ou version ultérieure) Je souhaite que vous compariez des objets dans Objects.equals
[Note] Je veux obtenir dans l'ordre inverse en utilisant afterLast avec JdbcTemplate
Je souhaite créer un SNS Web sombre avec Jakarta EE 8 avec Java 11
Je souhaite afficher un PDF chinois (coréen) avec des rapports fins
Je souhaite obtenir l'adresse IP lors de la connexion au Wi-Fi avec Java
Je souhaite afficher un message d'erreur lors de l'inscription dans la base de données
[Java Spring MVC] Je souhaite utiliser DI dans ma propre classe
Je veux créer une application ios.android
Je souhaite utiliser DBViewer avec Eclipse 2018-12! !!
spring-data-jpa @Query renvoie un objet personnalisé
Je veux arrêter complètement les mises à jour Java
Je veux utiliser @Autowired dans Servlet
Faisons une application TODO avec Java 2 Je veux créer un modèle avec Spring Initializr et créer Hello world
Comment stocker des objets dans PostgreSQL au format JSON avec MyBatis (Mapper XML)
Rails6 Je veux créer un tableau de valeurs avec une case à cocher
Exécuter R à partir de Java Je veux exécuter rJava
J'ai essayé de faire une authentification de base avec Java
Même en Java, je veux sortir vrai avec un == 1 && a == 2 && a == 3 (magie grise qui n'est pas tant que magie noire)
Désérialiser le CSV en Java en fonction du nom de l'en-tête
Je souhaite transmettre APP_HOME pour me connecter à Gradle
Je voulais que (a == 1 && a == 2 && a == 3) vrai en Java
Même si je souhaite convertir le contenu d'un objet de données en JSON en Java, il existe une référence circulaire ...
J'ai essayé de sortir quatre-vingt-dix-neuf en Java
Je veux être finalement même à kotlin
Même en Java, je veux sortir true avec un == 1 && a == 2 && a == 3 (Royal road edition qui n'est ni magique ni rien)
Comment résoudre les problèmes d'expression en Java
J'ai essayé de développer une application en 2 langues