Skip to content

Instantly share code, notes, and snippets.

@enif-lee
Last active May 2, 2024 11:58
Show Gist options
  • Save enif-lee/20b5a39a15419afc9e2a7de9af1905b5 to your computer and use it in GitHub Desktop.
Save enif-lee/20b5a39a15419afc9e2a7de9af1905b5 to your computer and use it in GitHub Desktop.
Implementation streaming download with spring webflux + fastexcel + databuffer + flow
package com.emotimer.presentation.handler
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.reactive.asPublisher
import kotlinx.coroutines.reactor.awaitSingle
import org.dhatim.fastexcel.Workbook
import org.reactivestreams.Publisher
import org.springframework.core.io.buffer.DataBuffer
import org.springframework.core.io.buffer.DefaultDataBufferFactory
import org.springframework.http.ContentDisposition
import org.springframework.http.MediaType
import org.springframework.web.reactive.function.BodyInserters
import org.springframework.web.reactive.function.server.ServerRequest
import org.springframework.web.reactive.function.server.ServerResponse
import java.io.ByteArrayOutputStream
import java.util.*
class SampleHandler {
suspend fun downloadCsv(request: ServerRequest): ServerResponse {
val buffers: Publisher<DataBuffer> = flow {
val factory = DefaultDataBufferFactory()
val os = ByteArrayOutputStream()
os.use {
val wb = Workbook(it, "excel", "1.0")
val ws = wb.newWorksheet("sheet1")
// Generate large data set
(0..100000).forEach { row ->
(0..100).forEach { col ->
ws.value(row, col, UUID.randomUUID().toString())
}
if (row % 1000 == 0) {
ws.flush()
if (os.size() > 0) {
println("PROCESS : $row, ${os.size()}bytes")
val buffer = factory.wrap(os.toByteArray())
emit(buffer)
os.reset()
}
}
}
wb.finish()
emit(factory.wrap(os.toByteArray()))
}
}.asPublisher()
return ServerResponse.ok()
.headers {
it.contentDisposition = ContentDisposition.attachment().filename("test.xlsx").build()
it.contentType = MediaType.APPLICATION_OCTET_STREAM
}
.body(
BodyInserters.fromDataBuffers(
buffers
)
)
.awaitSingle()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment