Added project

This commit is contained in:
2023-06-10 23:59:27 +03:00
parent 3ca712c8f6
commit fd63b81d22
8 changed files with 597 additions and 6 deletions

View File

@@ -0,0 +1,152 @@
package ru.resprojects.exceltojson
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.mongodb.ConnectionString
import com.mongodb.client.MongoCollection
import mu.KotlinLogging
import org.apache.commons.collections4.list.UnmodifiableList
import org.apache.poi.ss.usermodel.CellType
import org.apache.poi.xssf.usermodel.XSSFSheet
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.litote.kmongo.KMongo
import org.litote.kmongo.findOne
import org.litote.kmongo.getCollection
import java.io.File
import java.net.URI
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.Paths
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
private val logger = KotlinLogging.logger {}
private val mapper = jacksonObjectMapper()
fun main(args: Array<String>) {
if (args.isEmpty()) {
println("""
usage exceltojson <path_to_excel_file> for generate json file
usage exceltojson --mongo=mongodb://<host>:<port>/<database>/<collection_name> <path_to_file_xlsx> for export to mongo
""".trimIndent())
return
}
if (args.first().startsWith("--mongo=")) {
excelToMongo(args, URI(args.first().substring("--mongo=".length)))
} else {
args.forEach {
if (!it.startsWith("--")) {
println("Start process file $it")
excelToJson(it)
println("------")
}
}
}
}
fun excelToMongo(fileNames: Array<String>, mongoUri: URI) {
try {
val client = KMongo.createClient(ConnectionString(mongoUri.scheme + "://" + mongoUri.host + ":" + mongoUri.port))
client.use { mongoClient ->
val database = mongoClient.getDatabase(mongoUri.path.removePrefix("/").split("/")[0])
val collectionName = mongoUri.path.removePrefix("/").split("/")[1]
val collection = database.getCollection<Dict>(collectionName)
fileNames.forEach { fileName ->
if (!fileName.startsWith("--")) {
println("Start process file $fileName")
val book = XSSFWorkbook(File(fileName).inputStream())
book.use { xssfWorkbook ->
collectToList(xssfWorkbook.getSheetAt(0)).forEach {dict ->
if (!isEntryExistsInMongo(collection, dict)) {
collection.insertOne(dict)
} else {
val message = "--> Entry {id=${dict.id}, field=${dict.field}, value=${dict.value}, value_map=${dict.value_map}} is exist in collection '$collectionName' and was skipped"
println(message)
logger.warn { message }
}
}
}
}
}
}
println("Process is end. All entry was success added to mongo")
println("------")
} catch (e: Exception) {
println("Error process ${e.message}")
logger.error(e) { "Error process" }
}
}
fun isEntryExistsInMongo(collection: MongoCollection<Dict>, entry: Dict): Boolean {
return collection.findOne(
"""
{
"id": ${entry.id},
"field": "${entry.field}",
"value": "${entry.value}",
"value_map": "${entry.value_map}"
}
""".trimIndent()
) != null
}
fun excelToJson(fileName: String) {
try {
if (!Files.exists(Paths.get(fileName))) {
val message = "File $fileName not found"
println(message)
logger.error { message }
return
}
val file = File(fileName)
val book = XSSFWorkbook(file.inputStream())
book.use {
val lst = file.name.split(".")
val defaultFileName = "file-${LocalDateTime.now().format(DateTimeFormatter.ofPattern("ddMMyyyy-HHmm"))}.json"
val outFilename = "${if (file.toPath().parent != null) file.toPath().parent.toString() + FileSystems.getDefault().separator else ""}${if (lst.isNotEmpty()) file.name.split(".")[0] else defaultFileName}.json"
mapper.writeValue(File(outFilename), collectToList(it.getSheetAt(0)))
println("End process file. Write result to $outFilename")
println("-----------")
}
} catch (e: Exception) {
val message = "Error while process file $fileName"
println(message)
logger.error(e) { message }
}
}
fun collectToList(sheet: XSSFSheet): List<Dict> {
val list = ArrayList<Dict>()
if (sheet.first().lastCellNum - sheet.first().firstCellNum < 4) {
throw RuntimeException("Column count < 4")
}
for (i in 1 until sheet.lastRowNum) {
val row = sheet.getRow(i)
if (row.getCell(0) == null) {
continue
}
val id = if (row.getCell(0).cellType == CellType.NUMERIC) {
row.getCell(0).numericCellValue.toInt()
} else {
row.getCell(0).stringCellValue.toInt()
}
val value = if (row.getCell(2).cellType == CellType.NUMERIC) {
row.getCell(2).numericCellValue.toInt().toString()
} else {
row.getCell(2).stringCellValue
}
val valueMap = if (row.getCell(3).cellType == CellType.NUMERIC) {
row.getCell(3).numericCellValue.toInt().toString()
} else {
row.getCell(3).stringCellValue
}
list.add(Dict(
id,
row.getCell(1).stringCellValue,
value,
valueMap,
))
}
return UnmodifiableList(list)
}
data class Dict (var id: Int, var field: String, var value: String, var value_map: String)

View File

@@ -0,0 +1,5 @@
log4j.rootLogger=INFO, file
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%5p [%t] (%F:%L) %-30.90c - %m%n
log4j.appender.file.file=${java.io.tmpdir}/exceltojson.log

View File

@@ -0,0 +1,28 @@
package ru.resprojects.exceltojson
import mu.KotlinLogging
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.junit.jupiter.api.Test
import java.io.File
import java.net.URL
import kotlin.test.assertEquals
data class DictVal (var id: Int, var field: String, var value: String, var value_map: String)
private val logger = KotlinLogging.logger {}
class MainTest {
@Test
fun `when input correct xml file when expected not null list`() {
val book = XSSFWorkbook(File(loadResource("xlsx/test.xlsx").toURI()).inputStream())
book.use {
assertEquals(2, collectToList(book.getSheetAt(0)).size)
}
}
private fun loadResource(path: String): URL {
return Thread.currentThread().contextClassLoader.getResource(path) ?: throw RuntimeException("File $path not found")
}
}

Binary file not shown.