2016-03-24 1 views
0

J'ai un problème avec l'exportation de fichiers .xls volumineux avec SXSSF, ce qui signifie que je veux dire 27 cols x 100 000 lignes. Le fichier Excel est le retour sur la demande de point de terminaison. J'ai limité le nombre de rangées - il peut être 3 fois plus grand. J'utilise le moteur de gabarit pour insérer des données.Création de fichiers .xls volumineux avec SXSSF

Code d'origine

public StreamingOutput createStreamedExcelReport(Map<String, Object> params, String templateName, String[] columnsToHide) throws Exception { 
     try(InputStream is = ReportGenerator.class.getResourceAsStream(templateName)) { 
      assert is != null; 
      final Transformer transformer = PoiTransformer.createTransformer(is); 
      AreaBuilder areaBuilder = new XlsCommentAreaBuilder(transformer); 
      List<Area> xlsAreaList = areaBuilder.build(); 
      Area xlsArea = xlsAreaList.get(0); 
      Context context = new PoiContext(); 
      for(Map.Entry<String, Object> entry : params.entrySet()) { 
       context.putVar(entry.getKey(), entry.getValue()); 
      } 
      xlsArea.applyAt(new CellRef("Sheet1!A1"), context); 
      xlsArea.processFormulas(); 
      return new StreamingOutput() { 
       @Override 
       public void write(OutputStream out) throws IOException { 
        ((PoiTransformer) transformer).getWorkbook().write(out); 
       } 
      }; 
     } 
    } 

de SXSSF

public StreamingOutput createStreamedExcelReport(Map<String, Object> params, String templateName, String[] columnsToHide) throws Exception { 
     try(InputStream is = ReportGenerator.class.getResourceAsStream(templateName)) { 
      assert is != null; 
      Workbook workbook = WorkbookFactory.create(is); 
      final PoiTransformer transformer = PoiTransformer.createSxssfTransformer(workbook); 
      AreaBuilder areaBuilder = new XlsCommentAreaBuilder(transformer); 
      List<Area> xlsAreaList = areaBuilder.build(); 
      Area xlsArea = xlsAreaList.get(0); 
      Context context = new PoiContext(); 
      for(Map.Entry<String, Object> entry : params.entrySet()) { 
       context.putVar(entry.getKey(), entry.getValue()); 
      } 
      xlsArea.applyAt(new CellRef("Sheet1!A1"), context); 
      xlsArea.processFormulas(); 
      return new StreamingOutput() { 
       @Override 
       public void write(OutputStream out) throws IOException { 
        transformer.getWorkbook().write(out); 
       } 
      }; 
     } 
    } 

Export a été en cours d'exécution pendant 7 minutes et je me suis arrêté serveur - il était trop long. Le temps acceptable serait d'environ 1 minute (2 minutes maximum). La plupart du temps, l'utilisation du processeur était d'environ 60-80% et l'utilisation de la mémoire était constante. J'ai aussi essayé d'exporter 40 lignes - cela m'a pris environ 10 secondes.

Peut-être que ma fonction doit être optimisée.

Le problème supplémentaire est que j'insère des fonctions. Dans le code d'origine, les fonctions sont remplacées par des valeurs. Dans la version SXSSF, ils ne le sont pas.

Répondre

0

Je vous recommande de désactiver le traitement des formules à ce stade car le support des formules pour la version SXSSF est limité et la consommation de mémoire peut être trop élevée. Le support des formules peut être amélioré dans les futures versions de JXLS.

Il suffit donc de supprimer xlsArea.processFormulas() appel et ajouter

context.getConfig().setIsFormulaProcessingRequired(false);

pour désactiver le suivi des références de cellules (comme le montre Jxls doc) et voir si cela fonctionne.

Veuillez également noter que le modèle et le rapport final devraient être au format .xlsx si vous utilisez SXSSF.

+0

Malheureusement, cela n'a pas aidé. Il fonctionne sans traitement de formule, mais il est toujours plus lent que la version non SXSSF. – hya

+0

Avez-vous joué avec l'option Taille de la fenêtre pour SXSSF? Cela a-t-il un effet sur la performance? Ma compréhension est que la performance globale de SXSSF vs non-SXSSF peut ne pas être meilleure. Mais le véritable avantage est une élimination des restrictions de la mémoire. –

+0

Dans ce cas, les restrictions de mémoire ne sont pas le problème. 3000 lignes vont exporter ~ 1min et j'ai besoin de gérer beaucoup plus. L'ensemble de données va se développer afin de stimuler le perfomance est nécessaire. D'autres solutions? Peut-être un script dans une autre langue? – hya