Ich möchte ein Objekt im CSV-Format mit mehrzeiligem Header und Filter in Java zurückgeben

1. Zuallererst

Beschreiben Sie das Programm, das als verwendete Bibliothek angesehen wurde, da ein CSV-Format erstellt werden musste, mit dem Ausgabefelder nach mehrzeiligem Header und Feldnamen gefiltert werden können.

2.CsvMapper/CsvSchema

Mit der Jackson-Bibliothek (jackson-dataformat-csv) können Sie ein Objekt (json) problemlos in csv konvertieren. Diesmal habe ich das benutzt.

// getter/Setter ist erforderlich, aber weggelassen
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) {
  //Fehlerbehandlung (vorläufig)
  e.printStackTrace();
}

[Ausgabe]

field1,field2,field3
aaa,,ccc

Sie können auch Folgendes tun

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

[Ausgabe]

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

[Ausgabe]

"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();

[Ausgabe]

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

Es ist zu beachten, dass die folgenden Änderungen an verschachtelten Objekten nicht unterstützt werden.

//Kann in CSV konvertiert werden
class TestObj {
  private String field1 = "aaa";
  private String field2 = "bbb";
  private String field3 = "ccc";
}

//Kann nicht in CSV konvertiert werden
class TestObj2 {
  TestObj obj = new TestObj();
  private String field4 = "aaa";
}

3. Filtern Sie nach mehrzeiligem Header & Feld und Ausgabe

Erstellen Sie etwas, das den Feldnamen und den Typnamen des Objekts als Überschriften ausgibt (2 Zeilen).

Leider unterstützt Jackson nicht mehrere Header und Filter, deshalb habe ich es selbst erstellt.


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);
	
	//Zu filterndes Feld (ursprünglich externer Eingang)
	List<String> filterParam = new ArrayList<String>() {
		{
			add("field1");
			add("field3");
		}
	};
	//Erstellen Sie mehrere Header und Filter
	String header = createHeader(obj, filterParam, fields);
	List<String> bodies = new ArrayList<>();
	try {
		bodies = Arrays.asList(mapper.writer(schema).writeValueAsString(obj).split(","));
	} catch (JsonProcessingException e) {
		//Fehlerbehandlung (vorläufig)
		e.printStackTrace();
	}
	String body = filter(bodies, filterParam, fields);
	
	//Ursprünglich verbunden und zurückgegeben
	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(","));
}

[Ausgabeergebnis]

field1,field3
String,String
aaa,ccc

Referenzseite

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

Verschiedene Möglichkeiten zum Verketten von durch Kommas getrennten Zeichenfolgen in Java https://qiita.com/shisama/items/b27d16b3aeb1baf055b1

String-Verkettung in Java 8 https://qiita.com/lonerydeveloper/items/9f7c977c039ad4d24d30

Recommended Posts

Ich möchte ein Objekt im CSV-Format mit mehrzeiligem Header und Filter in Java zurückgeben
Ich möchte eine E-Mail in Java senden.
Ich möchte für jedes Array mit Lambda-Ausdruck in Java
Ich möchte mit Kotlin und Java zum vorherigen Bildschirm zurückkehren!
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben (PowerMockito Edition)
Ich möchte Java8 für jeden mit Index verwenden
rsync4j - Ich möchte rsync in Java berühren.
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 (Black Magic) ausgeben.
Ich möchte so etwas wie "cls" in Java machen
Ich möchte Bildschirmübergänge mit Kotlin und Java machen!
Ich möchte Java Applet ohne Verwendung einer IDE erstellen
Ich möchte eine mit Rails 6 erstellte App an GitHub senden
Ich möchte manuell eine Autorisierungs-E-Mail mit Devise senden
Ich möchte verschiedene Funktionen mit Kotlin und Java implementieren!
Konvertieren Sie ein zweidimensionales Array mit der Java 8 Stream-API in das CSV-Format
[Java] Ich möchte Standardeingabe und Standardausgabe mit JUnit testen
Ich möchte die if-else-Anweisung für bedingte Verzweigungen in Java vereinfachen
Nachdem ich einen Artikel mit Rails Simple Calendar veröffentlicht habe, möchte ich ihn im Kalender wiedergeben.
Ich möchte eine Schleife schreiben, die auf einen Index mit der Stream-API von Java 8 verweist
Ich möchte mit Java8 StreamAPI redu () einen anderen Typ als das Eingabeelement zurückgeben.
Ich habe eine E-Mail in Java gesendet
Ich habe versucht, mit Java zu interagieren
Ich habe versucht, eine Android-Anwendung mit MVC zu erstellen (Java)
Ich habe eine Anmerkung in Java gemacht.
[Java] Geben Sie das Ergebnis von ffprobe -show_streams in JSON aus und ordnen Sie es einem Objekt in Jackson zu
Ich möchte Bilder mit REST Controller von Java und Spring anzeigen!
Ich möchte im Dialogfeld mehrere Elemente mit einem benutzerdefinierten Layout auswählen
(Beschränkt auf Java 7 oder höher) Ich möchte, dass Sie Objekte in Objects.equals vergleichen
[Hinweis] Ich möchte mit afterLast mit JdbcTemplate in umgekehrter Reihenfolge arbeiten
Ich möchte mit Jakarta EE 8 mit Java 11 ein dunkles Web-SNS erstellen
Ich möchte ein chinesisches (koreanisches) PDF mit dünnen Berichten anzeigen
Ich möchte die IP-Adresse erhalten, wenn ich mit Java eine Verbindung zu Wi-Fi herstelle
Ich möchte bei der Registrierung in der Datenbank eine Fehlermeldung anzeigen
[Java Spring MVC] Ich möchte DI in meiner eigenen Klasse verwenden
Ich möchte eine ios.android App machen
Ich möchte DBViewer mit Eclipse 2018-12 verwenden! !!
spring-data-jpa @Query gibt ein benutzerdefiniertes Objekt zurück
Ich möchte Java-Updates insgesamt stoppen
Ich möchte @Autowired in Servlet verwenden
Lassen Sie uns eine TODO-Anwendung mit Java 2 erstellen. Ich möchte eine Vorlage mit Spring Initializr erstellen und eine Hello-Welt erstellen
Speichern von Objekten in PostgreSQL als JSON mit MyBatis (Mapper XML)
Rails6 Ich möchte ein Array von Werten mit einem Kontrollkästchen erstellen
R von Java ausführen Ich möchte rJava ausführen
Ich habe versucht, eine Standardauthentifizierung mit Java durchzuführen
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben (graue Magie, die weniger schwarze Magie ist)
Deserialisieren Sie CSV in Java basierend auf dem Headernamen
Ich möchte APP_HOME an Logback in Gradle übergeben
Ich wollte (a == 1 && a == 2 && a == 3) in Java wahr machen
Auch wenn ich den Inhalt eines Datenobjekts in Java in JSON konvertieren möchte, gibt es einen Zirkelverweis ...
Ich habe versucht, neunundneunzig in Java auszugeben
Ich möchte irgendwann sogar in Kotlin sein
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben (Royal Road Edition, die weder Magie noch irgendetwas ist)
So lösen Sie Ausdrucksprobleme in Java
Ich habe versucht, eine Anwendung in 2 Sprachen zu entwickeln