dhatim / fastexcel

Generate and read big Excel files quickly
Other
669 stars 121 forks source link

Using Flux<DataBuffer> to send created excel data #224

Open anymate98 opened 1 year ago

anymate98 commented 1 year ago

I am trying to create excel file using fastexcel. Also, my goal is to deliver the file that is being created to the browser at the same time. The function that creates excel should emit Flux concurrently.

So, the code looks like this.

...

val out = dataBuffer.asOutputStream()
val workbook = Workbook(out, "excel-file", "1.0")

// returns flux in this function
return Flux.create({ sink: FluxSink<DataBuffer> ->
    val sheet = workbook.newWorkSheet("my sheet")
    for(i in 1..100000) {
        sheet.value(i, 0, "first")
        sheet.value(i, 1, "second")

         ....

        // writes filled databuffer to flux
         if(i % 100 == 0) {
             sheet.flush()
             sink.next(dataBuffer) // <A>
         }
    }

    // finish sheet
    sheet.finish()
    sink.next(dataBuffer)

    // finish file
    workbook.finish()
    sink.next(dataBuffer)
    sink.complete()
}

With this code, I am able to download excel from browser immediately after request. However, if I collect returned flux and look at downloaded excel file, it is corrupted and cannot be opened from spreadsheet programs.

To fix this, I can delete A line from code. It will then return complete spreadsheet that can be opened. But with this fix, I cannot download excel immediately because the sink operation starts after the sheet is fully created. Regarding that this code creates single sheet excel file, the download will start almost at the same time the file creation is completed.

So, I want to know whether it is possible to use OutputStream applied to the workbook concurrently, so I can download excel file when the sheet is being created. It should also be in reactive way. Or, is it inhibited to access OutputStream while creating a single sheet?

meiMingle commented 1 year ago

@anymate98 Forgive me for not understanding your question. If you are willing to provide a minimal executable demo, I am willing to spend some time on this issue.