Dividir processamento de arquivo excel - apache POI

5 respostas
R

Caros amigos,

preciso da ajuda de vocês…

por se tratar de uma grande instituição financeira, tenho as seguintes limitações impostas pela arquitetura da empresa:

  • não posso manipular threads no servidor;
  • não posso usar uma procedure no banco para controlar um rotina;
  • não posso gravar arquivos em disco;
  • não posso usar libs que não estejam homologadas pelo setor de arquitetura do cliente, isso inclui o dwr, que eu acho que resolveria em parte o meu problema;

bom, chega de enrolação e vamos ao problema:

tenho que importar um planilha excel de 86 colunas e até mais de 10.000 linhas, exibir essa planilha na tela (um grid montado na mão com dois for each em jstl), com os possiveis erros de validação, para que o cliente altere na tela mesmo antes de mandar gravar no banco…

Quem já trabalhou com o POI deve saber que ele tem sérios problemas de performance. Hoje eu importo uma planilha de 20 linhas com o POI no mesmo tempo que eu importava uma planilha similar, porém com 400 linhas com JExcel (10 segundos - incluindo validação… cada campo tem uma diferente)…

o servidor tem um time-out de 30 segundos… se com 20 linhas está em 10 segundos, imaginem com 400, ou 10.000.

Gostaria da ajuda de vocês com idéias, soluções ou até mesmo rezas brabas (RSRS) que me ajudem a resolver esse problema (abacaxi)…

a minha idéia inicial era:

de alguma forma dividir o arquivo em várias partes, e processá-las uma a uma, e devolvendo essas partes para o cliente na mesma ordem que estavam no excel, carregar essas partes na tela conforme forem sendo processadas… acredito que com dwr eu conseguiria resolver isso, porém não posso usar essa lib…

a aplicação usa os seguintes frameworks:

  • struts 2.1.8 (sem algumas libs… como a strutsJquery (ou algo assim, não me lembro bem));
  • spring 3 (também com algumas alterações).

desde já agradeço a ajuda…

5 Respostas

J

rlp1905:
Caros amigos,
Quem já trabalhou com o POI deve saber que ele tem sérios problemas de performance. Hoje eu importo uma planilha de 20 linhas com o POI no mesmo tempo que eu importava uma planilha similar, porém com 400 linhas com JExcel (10 segundos - incluindo validação… cada campo tem uma diferente)…

Muito estranho isso. Aqui na empresa fiz um complemento no sistema para ler uma planilha do excel com umas 15 colunas e 1600 linhas e não demora mais que 1,5 ou no máximo 2 segundos!
Porém o cliente é desktop (Swing).

R

acredito que a lógica de implementação não mude de desktop para web (não nesse caso), mas o fato de uma aplicação desktop ter uma “máquina só pra ela” pode fazer a diferença, pois em um desktop você tem muito mais recursos disponiveis (processador/memória) que em um servidor web onde tudo é limitado…

leonardobhbr

Boa noite provavelmente vc não pode trabalhar JExcel né

voce tem certeza que não ha nenhum gargalo no seu código?

se não houver nada no código nenhum for tendendo a infinito etc.

fica dificil porque vc tem mais essa restrição

O que poderia ser feito e vc dividir o arquivo em dois ou mais, mas como voce não pode gravar arquivo em disco complica.

não tem como vc mandar o trecho de código só da leitura não?

outra questão no pior caso vc mostraria um grid com 10 mil registros?

Uma outra solução seria fazer o que o google faz ele fala que encontrou 100 mil registros mais vai carregando sob demanda

R

então… como não estou no trabalho, não tenho como mandar o codigo de importação… só na segunda… =(

mas é algo parecido com isso:

ArrayList<String>    colNames    = null;
   ArrayList<Map>       mapArray    = null;
   HSSFRow              row         = null;
   HSSFSheet            sheet       = null;
   int                  sheetRows   = 0;
   int                  rowCols     = 0;
   Map<String, Object>  rowMap      = null;

   sheet     = this.workbook.getSheetAt(sheetIndex);
   sheetRows = sheet.getPhysicalNumberOfRows();
   mapArray  = new ArrayList<Map>(sheetRows - 1);
   colNames  = getColNames(sheetIndex);

   colNames.trimToSize();

   rowCols = colNames.size();

   for (int i = 1; i < sheetRows; i++)
   {
      row    = sheet.getRow(i);
      rowMap = new HashMap<String, Object>(rowCols);
      for (int c = 0; c < rowCols; c++)
      {
         rowMap.put(colNames.get(c), getCellValue(row.getCell(c)));
      }
      mapArray.add(rowMap);
   }
   return mapArray;

A minha idéia é exatamente essa… porém não sei como seria a implementação… também poderia dar um jeito de fazer uma paginação, e a cada página aberta faz-se uma nova consulta, porém os dados não estão no banco, eu não posso gravar arquivo em disco, e deixar tudo em memória é muito custoso…

to ficando louco com essa parada já…

R

E aí pessoal, alguma idéia???

Criado 29 de julho de 2011
Ultima resposta 2 de ago. de 2011
Respostas 5
Participantes 3