API pour écrire d'énormes fichiers Excel en utilisant java


Je cherche à écrire dans un excel (.xls MS Excel 2003 format) fichier par programme en utilisant Java. Les fichiers de sortie Excel peuvent contenir ~200 000 lignes que je prévois de diviser en nombre de feuilles (64k lignes par feuille, en raison de la limite Excel).

J'ai essayé d'utiliser les API apache POI mais cela semble être un porc de mémoire en raison du modèle d'objet API. Je suis obligé d'ajouter des cellules / feuilles à l'objet classeur en mémoire et seulement une fois toutes les données ajoutées, je peux écrire le classeur dans un fichier! Voici un exemple de la façon dont apache recommande d'écrire des fichiers Excel à l'aide de leur API:

Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("new sheet");

//Create a row and put some cells in it
Row row = sheet.createRow((short)0);

// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Clairement, écrire ~20k lignes(avec quelques 10-20 colonnes dans chaque ligne) me donne le redouté "java.lang.OutOfMemoryError: Java heap space".

J'ai essayé d'augmenter la taille de tas initiale de la JVM et la taille de tas maximale en utilisant les paramètres Xms et Xmx comme Xms512m et Xmx1024. Je ne peux toujours pas écrire plus de 150k lignes dans le fichier.

Je cherche un moyen de diffuser dans un fichier Excel au lieu de construire l'ensemble fichier en mémoire avant de l'écrire sur le disque, ce qui, espérons-le, économisera beaucoup d'utilisation de la mémoire. Toute API ou solution alternative serait appréciée, mais je suis limité à l'utilisation de java. Merci! :)

Author: Jaskirat, 2009-09-28

9 answers

Toutes les API Java existantes essaient de construire le document entier dans la RAM à la fois. Essayez d'écrire un fichier XML conforme au nouveau format de fichier xslx à la place. Pour vous aider à démarrer, je suggère de créer un petit fichier sous la forme souhaitée dans Excel et de l'enregistrer. Ensuite, ouvrez-le et examinez la structure et remplacez les pièces que vous voulez.

, Wikipédia a un bon article sur le format global.

 6
Author: Aaron Digulla, 2009-09-28 09:53:10

Essayez d'utiliserSXSSF classeur, c'est une excellente chose pour les énormes documents xls, son document de construction et ne mange pas de RAM du tout, car vous utilisez nio

 9
Author: Serhii Bohutskyi, 2013-08-08 08:10:06

J'ai dû diviser mes fichiers en plusieurs fichiers Excel afin de surmonter l'exception d'espace de tas. J'ai pensé qu'environ 5k lignes avec 22 colonnes était à ce sujet, donc j'ai juste fait ma logique pour que chaque 5k ligne je termine le fichier, en démarre un nouveau et numérote simplement les fichiers en conséquence.

Dans les cas où j'avais 20k + lignes à écrire, j'aurais 4+ fichiers différents représentant les données.

 4
Author: Chris Dale, 2009-12-21 12:17:27

Jetez un œil ausérialiseur HSSF du projet cocoon.

Le sérialiseur HSSF capture les événements SAX et crée une feuille de calcul au format XLS utilisé par Microsoft Excel

 3
Author: pgras, 2009-12-09 16:43:42

Il y a aussi JExcelApi, mais il utilise plus de mémoire. je pense que vous devriez créer .fichier csv et ouvrez-le dans Excel. il vous permet de transmettre beaucoup de données, mais vous ne pourrez pas faire de "magie excel".

 2
Author: IAdapter, 2009-09-28 09:31:02

Envisagez d'utiliser le format CSV. De cette façon, vous n'êtes plus limité par la mémoire well eh bien, peut-être seulement pendant le prépeuplement des données pour CSV, mais cela peut également être fait efficacement, par exemple en interrogeant des sous-ensembles de lignes de la base de données en utilisant par exemple LIMIT/OFFSET et en l'écrivant immédiatement dans un fichier au lieu de transporter tout le La limitation Excel des lignes de montant dans une "feuille" passera à environ un million.

Cela dit, si les données vient en fait d'une base de données, alors je reconsidérerais fortement si Java est le bon outil pour cela. La plupart des bases de données décentes ont une fonction d'exportation vers CSV qui peut effectuer cette tâche sans aucun doute beaucoup plus efficace. Dans le cas, par exemple, de MySQL, vous pouvez utiliser le LOAD DATA INFILE commande pour cette.

 1
Author: BalusC, 2009-12-09 17:26:08

Nous avons développé une bibliothèque java à cet effet et elle est actuellement disponible en tant que projet open source https://github.com/jbaliuka/x4j-analytic . Nous l'utilisons pour les rapports opérationnels. Nous générons d'énormes fichiers Excel, ~200 000 devraient fonctionner sans problèmes, Excel parvient également à ouvrir de tels fichiers. Notre code utilise POI pour charger le modèle, mais le contenu généré est directement diffusé dans un fichier sans couche XML ou modèle d'objet en mémoire.

 1
Author: jbaliuka, 2013-10-04 14:22:51

Ce problème de mémoire se produit - il lorsque vous insérez des données dans la cellule ou lorsque vous effectuez un calcul/génération de données?

Si vous allez charger des fichiers dans un excel qui se composent de format de modèle statique prédéfini, alors mieux vaut enregistrer un modèle et réutiliser plusieurs fois. Normalement, les cas de modèle se produisent lorsque vous allez générer un rapport de vente quotidien ou etc...

Sinon, chaque fois que vous devez créer une nouvelle ligne, une bordure, une colonne, etc. à partir de zéro.

Jusqu'à présent, Apache POI est le seul choix que j'ai trouvé.

"Clairement, écrire ~20k lignes(avec quelques 10-20 colonnes dans chaque ligne) me donne le redouté "java.lang.OutOfMemoryError: Java heap space"."

"Informatique d'entreprise"

Ce QUE VOUS POUVEZ FAIRE est - effectuer l'insertion de données par lots. Créez une table queuetask, à chaque fois après avoir généré 1 page, reposez-vous pendant quelques secondes, puis continuez la deuxième partie. Si vous vous inquiétez des changements de données dynamiques pendant votre tâche de file d'attente, vous pouvez d'abord obtenir la clé primaire dans Excel (en cachant et verrouiller la colonne de la vue utilisateur). La première exécution sera insérer la clé primaire, puis la deuxième exécution de la file d'attente à partir du bloc-notes et fera la tâche partie par partie.

 0
Author: i need help, 2009-09-28 09:58:00

Nous avons fait quelque chose d'assez similaire, la même quantité de données, et nous avons dû passer à JExcelapi parce que POI est si lourd sur les ressources. Essayez JexcelApi, vous ne le regretterez pas lorsque vous devrez manipuler de gros fichiers Excel!

 0
Author: fvu, 2009-09-28 10:13:54