Запись огромного файла excel (20k записей) занимает более 1 минуты java? - PullRequest
0 голосов
/ 09 июля 2020

Привет, я использую apache POI, а для записи в книгу я использую SXSSFWorkbook, так как данные будут огромными,

Все выглядит хорошо, но при преобразовании книги во входной поток требуется огромное время для экспорта отчетов.

Вот мой код

public StreamedContent generateStreamRep(String fileName, Workbook wb) {
    try (ByteArrayOutputStream dsf = new ByteArrayOutputStream();){     
        wb.write(dsf);      
        file = new DefaultStreamedContent(ByteSource.wrap(dsf.toByteArray()).openStream(), "xlsx", fileName);
   }

Я использовал IOUtils, теперь переключился на com.google.common.io.ByteSource

Заглянул в PipedStreams но не получает должного ресурса.

1 Ответ

0 голосов
/ 09 июля 2020

A Пример минимальной воспроизводимости поможет дать более полный ответ.

Однако в следующем коде используется PipedStreams для ускорения операций, показанных в коде вопроса. Однако выгода, которую вы получаете от этого подхода, не может быть больше, чем у самого быстрого из двух параллельных процессов. Или, говоря иначе, конечная продолжительность не может быть быстрее, чем более медленная из параллельных операций. В подходе PipedStreams вам нужно 2 потока. PipedOutputStream, куда будут записываться данные, и PipedInputStream, где данные будут использоваться. Чтобы воспользоваться этим подходом, вам необходимо выполнить эти две операции параллельно.

public StreamedContent generateStreamRep(final String fileName, final Workbook wb) {
    try (final PipedOutputStream dsf = new PipedOutputStream ();
         final PipedInputStream sink=new PipedInputStream (dsf);){     

        final ExecutorService executorService= Executors.newSingleThreadExecutor();

        //Write to output stream
        executorService.execute(()->wb.write(dsf));

       //read from input stream
       file = new DefaultStreamedContent(sink, "xlsx", fileName);

        executorService.shutdown();

         //wait until task is finished or until a maximum time, which ever comes first. Normally in this case the task is already finished
        executorService.awaitTermination(2,TimeUnit.Minutes);
  

   }
...