I have created a MappingsBean class where all the columns of the CSV file are specified. Next I parse XML files and create a list of mappingbeans. Then I write that data int
I've improved on previous answers by removing all references to deprecated APIs while using the latest release of opencsv (4.6).
/**
* Custom OpenCSV [ColumnPositionMappingStrategy] that allows for a header line to be generated from a target CSV
* bean model class using the following annotations when present:
* * [CsvBindByName]
* * [CsvCustomBindByName]
*/
class CustomMappingStrategy(private val beanType: Class) : ColumnPositionMappingStrategy() {
init {
setType(beanType)
setColumnMapping(*getAnnotatedFields().map { it.extractHeaderName() }.toTypedArray())
}
override fun generateHeader(bean: T): Array = columnMapping
private fun getAnnotatedFields() = beanType.declaredFields.filter { it.isAnnotatedByName() }.toList()
private fun Field.isAnnotatedByName() = isAnnotationPresent(CsvBindByName::class.java) || isAnnotationPresent(CsvCustomBindByName::class.java)
private fun Field.extractHeaderName() =
getAnnotation(CsvBindByName::class.java)?.column ?: getAnnotation(CsvCustomBindByName::class.java)?.column ?: EMPTY
}
Then use it as follows:
private fun csvBuilder(writer: Writer) =
StatefulBeanToCsvBuilder(writer)
.withSeparator(ICSVWriter.DEFAULT_SEPARATOR)
.withMappingStrategy(CustomMappingStrategy(MappingsBean::class.java))
.withApplyQuotesToAll(false)
.build()
// Kotlin try-with-resources construct
PrintWriter(File("$reportOutputDir/$REPORT_FILENAME")).use { writer ->
csvBuilder(writer).write(makeFinalMappingBeanList())
}
and for completeness, here's the CSV bean as a Kotlin data class:
data class MappingsBean(
@field:CsvBindByName(column = "TradeID")
@field:CsvBindByPosition(position = 0, required = true)
private val tradeId: String,
@field:CsvBindByName(column = "GWML GUID", required = true)
@field:CsvBindByPosition(position = 1)
private val gwmlGUID: String,
@field:CsvBindByName(column = "MXML GUID", required = true)
@field:CsvBindByPosition(position = 2)
private val mxmlGUID: String,
@field:CsvBindByName(column = "GWML File")
@field:CsvBindByPosition(position = 3)
private val gwmlFile: String? = null,
@field:CsvBindByName(column = "MxML File")
@field:CsvBindByPosition(position = 4)
private val mxmlFile: String? = null,
@field:CsvBindByName(column = "MxML Counterparty")
@field:CsvBindByPosition(position = 5)
private val mxmlCounterParty: String? = null,
@field:CsvBindByName(column = "GWML Counterparty")
@field:CsvBindByPosition(position = 6)
private val gwmlCounterParty: String? = null
)