Export Hero information and list of his items to excel sheet/csv
hero.getLevel()+&quot;&quot;

Use an explicit cast instead of implicit one:
Integer.toString(hero.getLevel())


```java
new Date().toString(),
// ...
hero.getGold().toString()

Which might or might not be the format you want in the final file. Ideally you'd define explicit formatting rules.

There are a few approaches to serialization of data like in your case.
POJOs are Serializable
The first approach is to teach your POJOs how they are being serialized. That means that they implement some interface, like CsvSerializable which defines the method `serialize(CSVWriter csvWriter).
This has the upsides that the the objects themselves know how to serialize themselves. The downsides are that your data is now bound to CSVWriter and that you need to thing about where and how to put the header.
Adapters
The second possibility is to use &quot;adapters&quot;, which means that you have Hero and HeroSerializer classes. The later has a method like serialize(Hero hero, CSVWriter csvWriter).
This has the upside that your data classes are fine on their own, the downside is that you need two classes per class (that's 100% more class per class) and that the logic you already have is not that much improved.
Monolithic serializer
That's basically that approach that you already have. With some minor changes (like encapsulating more logic into separate methods, for example the writing of each different item type into its own method) it's actually a very good approach. It keeps your data classes on their own, but you have an ever growing monolith.
Reflective serialization
Fields
Now comes the fun one, you could use reflection to access the fields at runtime. That means that your ITEM_LIST_HEADER actually becomes the key to serialization of your objects. That approach is more complicated, but means a little bit more flexibility. The downside is that your fields always must be the same than the headers...well, if you consider that a downside.
So what you could be doing is something like this:
private void writeLine(CSVWriter csvWriter, Object object, String[] fieldNames) {
    Map&lt;String, Field&gt; fields = getFields(object.getClass());
    String[] values = new String[fields.length];
    
    for (int index = 0; index &lt; fieldNames.length; index++) {
        String currentFieldName = fieldNames[index];
        Field field = fields.get(currentFieldName);
        
        if (field != null) {
            values[index] = Objects.toString(field.getObject(object));
        } else {
            values[index] = &quot;-&quot;;
        }
    }
    
    csvWriter.writeNext(values);
}

private Map&lt;String, Field&gt; getFields(Class&lt;?&gt; clazz) {
    // Could be cached for each class if performance is important.
    Map&lt;String, Field&gt; fields = new HashMap&lt;&gt;();
    
    for (Field field : clazz.getDeclaredFields()) {
        // Maybe add some checks, like if the field is static or not.
        field.setAccessible(true);
        fields.put(field.getName(), field);
    }
    
    return fields;
}

Untested and without exception handling, but I guess you see where this is going.
Getters/Setters
Like above, you can access the Getters/Setters reflectively. It is close to the same solution as above, with the difference that you don't need the set the fields accessible. However, you must be slightly more selective with what methods you expose in that case, and you need to convert the names.