XL2Csv : Convertir un fichier Excel en fichiers Csv
(ou en 1 fichier txt)
https://github.com/PatriceDargenton/XL2Csv
Ancien dépôt : https://codes-sources.commentcamarche.net/source/44827
Documentation : XL2Csv.html
Code source : XL2Csv.vbproj.html
http://patrice.dargenton.free.fr/CodesSources/index.html
Version 1.13 du 18/08/2024
Voici un
utilitaire pour convertir directement un fichier Excel en fichiers Csv (un
fichier Csv par feuille Excel, s'il y en a plusieurs), ou bien en un unique
fichier Csv, en s'arrangeant pour le mieux dans le cas où les feuilles
n'auraient pas le même nombre de champs (reprise des entêtes de la feuille
ayant le plus de champs), ou bien encore en un fichier texte, ce qui est plus
simple. Cette dernière fonctionnalité a l'avantage de permettre la comparaison
de contenus de fichiers Excel via l'utilitaire WinDiff,
ainsi que l'indexation, via l'utilitaire VBTextFinder.
Table des matières
ODBC
(XL2CsvODBC) : Convertir un fichier Excel en fichiers Csv via ODBC
Automation
(XL2CsvAutomation) : Convertir un fichier Excel en fichiers Csv via Automation
Excel
Fusion
csv (XL2CsvGroup) : Convertir un fichier Excel en fichier Csv via ODBC
Texte
(XL2Txt) : Convertir un fichier Excel en fichier Texte
Version
1.01 du 25/11/2007 : Première version
Il n'y a pas
besoin de mode d'emploi, car il suffit d'installer les menus contextuels :
pour cela lancez simplement XL2Csv en tant qu'administrateur, cliquez sur OK
puis sur "Ajouter menu ctx.".
Ensuite il
suffit d'utiliser les menus qui apparaissent lorsque l'on sélectionne un
fichier Excel avec le bouton droit de la souris dans l'explorateur de fichiers
de Windows.
Pour
désinstaller (ou réinstaller XL2Csv en cas de déplacement), cliquez sur
"Enlever menu ctx.".
Il y a une
astuce pour comparer le contenu de deux fichiers Excel via l'utilitaire
WinDiff :
- Pour
installer WinDiff (gratuit), voir ici ;
- Si une
colonne seulement est différente sur chaque ligne, alors comparer une copie des
deux fichiers Excel sans cette colonne, ce qui permettra de comparer que les
lignes différentes qui vous intéressent.
Voici la signification
des cases à cocher optionnelles pour les menus contextuels :
Il s'agit de
l'ancienne technique de conversion via ODBC (XL2Csv versions 1.03 et
antérieurs) : cette technique est rapide, mais les données doivent être
homogènes dans une même colonne (même type de donnée dans une colonne) et la
colonne doit avoir un entête. Sinon, des valeurs nulles apparaîtrons à la place
des données qui sont de types différents de celui qui a pu être détecté par
l'analyse d'un certain nombre de valeurs dans la colonne (1024 valeurs
analysées par exemple, pour pouvoir déterminer le type de données de la
colonne. Par défaut, seulement 8 valeurs sont analysées, ce qui est insuffisant
: en modifiant une clé dans la base de registre, on change en 1024, cela est
fait automatiquement par XL2Csv, il faut les droits administrateurs pour ce
changement).
Depuis la
version 1.04, la méthode par défaut est maintenant la librairie ExcelLibrary,
voir ci-dessous.
Cette
technique utilise l'automation Excel pour lire les valeurs de chaque cellule,
en les parcourant une par une, ce qui est très lent (d'autant plus qu'il faut
instancier Excel pour cela, ce qui prend déjà du temps). Le seul intérêt de
cette technique est pour comparer les résultats avec la librairie utilisée par
défaut : ExcelLibrary.
Cette
technique permet de regrouper les données de plusieurs feuilles Excel
(supposées de même nature) dans une seule feuille csv, ce qui est fastidieux à
faire à la main. Parfois on répartie les données sur plusieurs feuilles Excel
pour dépasser la limite des 65000 lignes de données des versions Excel
antérieures à 2007, d'où l'intérêt éventuel de cette option.
Cette
technique permet d'indexer un fichier Excel dans le but de retrouver rapidement
un contenu, en affichant l'ensemble des occurrences trouvées dans le classeur
(voir l'utilitaire VBTextFinder, une fonctionnalité similaire a été ajoutée à Excel à
partir de la version 2010).
Pour
simplifier un éventuel traitement automatique des fichiers csv produits, le
séparateur décimal est forcé au point (même si c'est la virgule qui est fixée
dans les options régionales de Windows) ; l'inconvénient, c'est que si l'on
veut rouvrir un fichier csv ainsi généré sous Excel, il faut convertir les . en , pour retrouver les nombres réels. Pour changer ce
fonctionnement, pour la méthode via ODBC, utilisez l'option suivante dans le code
source :
Me.m_oODBC.m_bRemplacerSepDec = False ' Laisser le séparateur décimal
en vigueur
Pour les
méthodes ODBC et automation, le format régional (du système) des dates est
utilisé : soit le format date courte avec l'heure si elle est précisée, ou
sinon le format date courte sans l'heure (si l'heure est à 0 ou non précisée
dans la cellule Excel).
La méthode via
ExcelLibrary ne dépend pas du format régional, c'est toujours le format jj/mm/aaaa (avec hh:mm:ss, le cas échéant) qui est utilisé par défaut.
ExcelLibrary
est la nouvelle méthode pour lire rapidement un fichier Excel.
https://www.codeproject.com/Articles/16210/Excel-Reader (documentation sur le sujet)
Le dernier
code source est ici (site principal) :
https://code.google.com/archive/p/excellibrary
https://www.nuget.org/packages/ExcelLibrary
Le principal
avantage est que cette méthode est très rapide : d'une part, il n'est pas
besoin d'instancier Excel (Excel n'est pas requis du tout), et le parcours des
cellules est aussi très rapide.
L'autre avantage
est que tous les classeurs Excel peuvent être lus : il n'est pas
nécessaire que les colonnes contiennent des types de données homogènes, comme
c'est le cas pour la méthode ODBC, du coup l'indexation de classeur Excel
devient réellement exploitable (voir l'utilitaire VBTextFinder).
Dans la
version actuelle (release r51 du 31/03/2011), il n'existe pas, à ma
connaissance, de méthode pour distinguer clairement une date d'une valeur
double, car le type de données Excel est le même pour stocker cette valeur,
dans l'un ou l'autre cas. Malheureusement, le format ne permet pas toujours de
distinguer la date, à cause du fait qu'il existe aussi le format personnalisé (en
plus du format Date, Heure, et Date+Heure). Il faudrait donc analyser le format
personnalisé pour se figurer s'il s'agit d'une date ou bien d'une valeur double
(ce qui est potentiellement complexe, et incertain, car on peut appliquer un
format date un peu n'importe où dans Excel). Si on sait à l'avance ce que l'on
attend dans le fichier Excel, on peut choisir le type de données en question
(la technique que j'ai utilisé pour une fonction utilitaire idoine est de
renvoyer par exemple un tableau de valeurs de dates en plus d'un tableur de
valeurs normalement analysées : c'est alors dans la fonction appelante de
décider laquelle est appropriée dans chaque cas). Mais si on cherche par
exemple à convertir l'ensemble d'un classeur Excel en fichiers csv ou texte, on
va tenter de se rapprocher le plus possible de la technique employée dans Excel
pour enregistrer au format csv, car Excel semble donner de bons résultats en ce
sens. Cependant, dans certain cas, on voudrait un format d'affichage des
valeurs qui ne dépendent pas du format des cellules, ni du format régional
choisi dans le système (par exemple pour fiabiliser l'import de données, on
veut un format le plus stable possible, toujours le même quelle que soit la
configuration). Et parfois on veut un format qui dépend du format des cellules,
et aussi du format régional (c'est le fonctionnement de Excel pour
l'enregistrement au format csv). Actuellement, cette dernière fonctionnalité
n'est pas prise en compte dans XL2Csv (il n'y a pas cette option, on utilise le
format le plus stable possible).
Il existe un
projet Java similaire à ExcelLibrary, dans lequel cette question du type de
donnée a été traitée par l'analyse approfondie du format de présentation, mais
les classes en question ont l'air assez complexes :
http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFDataFormatter.html
Pourtant le
but est précisément celui que l'on cherche : afficher les valeurs exactement
telles qu'elles apparaissent sous Excel. Dans le forum d'ExcelLibrary, on
renvoie à cette classe comme suggestion, mais personne ne semble avoir encore
implémenté cette fonctionnalité pour ExcelLibrary.
Il arrive
parfois qu'on trouve des résidus de valeurs doubles via ExcelLibrary (lors de
l'utilisation de graphiques, ou de cellules fusionnées ?), alors que via
automation, on ne trouve rien dans le contenu d'une cellule, on a IsNothing(oVal) :
Dim oVal As Object = oSht.Cells(iLigne, iCol).Value
Il arrive
également qu'un format monétaire sous Excel tronque la valeur affichée à 4
décimales, tandis que l'ensemble des décimales du type System.Double
seront bien présentes via ExcelLibrary.
Heureusement,
ces deux cas sont rares, et la plupart du temps, on obtient exactement les
mêmes fichiers csv générés via l'une ou l'autre des deux méthodes (c'est pour
cette raison que j'ai corrigé #N/A! en #N/A).
On essaie donc
de suivre la méthode Enregistrer sous d'Excel, avec cependant quelques
changements :
- Si on a
des lignes vides au départ, on les conserve (Excel les supprime), pareil pour
les colonnes vides à gauche ;
- On
supprime les signes ; à droite et en bas, s'il n'y a aucune valeur ;
- On ne
tient pas compte du format de la cellule, par exemple on n'affiche pas le
séparateur de millier, le séparateur décimal est toujours le point (Excel tient
compte du format régional), on affiche la valeur réelle des % (sans afficher
%), on utilise un format de date/heure fixe (les heures ne sont pas affichées
si elles sont vides), ...
Autre
limitation grave :
impossibilité de lire des gros documents (même avec la dernière version testée
de ExcelLibrary du 14/04/2011), on n'obtient l'erreur
(je n'ai pas réussi à corriger le problème avec les sources en C#) :
"L'argument
spécifié n'était pas dans les limites de la plage des valeurs valides."
"Nom du
paramètre : sectorID"
- Le cas
échéant, les espaces sont supprimés à la fin des valeurs des champs (mais pas
au début) ;
Me.m_oODBC.m_bEnleverEspacesFin = True
- Les
booléens sont remplacés de la façon suivante :
* La valeur faux ou false est
remplacée par une chaîne vide ;
* La valeur vrai ou true est remplacée par 1 :
Me.m_oODBC.m_bRemplacerVraiFaux = True
Me.m_oODBC.m_sValFaux = ""
Me.m_oODBC.m_sValVrai = "1"
- Voir la
région Configuration où sont regroupées ces options.
Si le classeur
contient une entête, on l'écrit dans le fichier csv, sinon on indique que le
fichier est vide ; en mode regroupement, on ignore la feuille, et en mode
texte, on écrit toujours l'entête, qui vaut F1 si la feuille est vide.
Si le
délimiteur vbTab est présent dans l'un des champs
(dans une cellule Excel), on dépasse le nombre max. de champs, et les champs
suivants sont décalés : les 2 méthodes bLireToutDUnBloc
(GetString) échouent dans ce cas.
Solution : ne pas les utiliser ces 2 méthodes (ce sera moins
rapide).
Problème : on ne peut le savoir qu'après coup (si les données
retournées présentent un défaut).
Notes :
- Pour la
méthode bLireToutDUnBlocRapide, le délimiteur de
colonne est le ; et celui de ligne est le vbCrLf (13
&10) :
Const sDelimiteurColonnesRapide$
= ";"
Const sDelimiteurLignesRapide$ = vbCrLf
- Pour la
méthode bLireToutDUnBloc, le délimiteur de colonne
est la tabulation ; et celui de ligne est le délimiteur par défaut
(probablement vbCrLf), ensuite les lignes sont
découpées via le délimiteur vbCr :
Const sDelimiteurColonnes$ = vbTab
- L'enregistrement
via Excel 2007 perturbe la lecture via Odbc, qui est
pourtant compatible avec le format 2003 :
Si je converti toutes les feuilles :
l'entête se décale d'une colonne (contenu de Entete.csv) .
Dès que je re-sauve depuis une
version Excel 2003, ce bug disparaît ;
Les autres méthodes fonctionnent :
elles ne sont pas sensible à ce bug.
https://github.com/PatriceDargenton/XL2Csv/blob/master/Changelog.md
- Correction
du menu contextuel : apparemment l'association avec le menu .xls et .xlsx ne fonctionne plus
(seulement certaines extensions ? par ex. .doc et
.idx fonctionnent toujours avec VBTextFinder), donc
on va utiliser l'association avec tous les fichiers (*) avec l'application
XL2Csv, en attendant une meilleure solution ;
- NPOI M.àj. en version 2.2.1.1 ;
- Encodage
UTF8 pour les fichiers csv générés ;
- Passage
en VB 2013 DotNet 4.6 (depuis DotNet
2.0).
- M.àj. ModUtilFichier, ModUtilReg, clsODBC ;
- Passage
en VB 2010 (mais on reste en DotNet 2), activation du
warning Return True/False.
- Vérifier
config ODBC : il faut le faire pendant qu'on coche l'option, car s'il y a
besoin d'être admin., on n'y arrive pas via un menu contextuel ;
- Corrections
diverses pour le mode SSG.
- bConvertirXLODBC : bFichierAccessibleMultiTest :
ne pas permettre qu'Excel soit ouvert.
- Test NPOI.
- VerifierConfigODBCExcel juste après l'ajout des menus
contextuels, pour Windows 64 bits, pendant que l'application est lancée en mode
Administrateur, et que la plateforme 32 bits est ciblée (avec la base de
registre 32 correspondante, sinon la clé sera dans la base de registre 64 bits
si on l'ajoute directement via le fichier
ODBCExcelAugmenterTypeGuessRows.reg) ;
- Configuration
ODBC cochée par défaut, car la version ExcelLibrary est encore limitée.
- <PlatformTarget>x86</PlatformTarget>,
voir ici :
Comment
faire fonctionner ODBC avec Windows 64 bits ?
- ExcelLibrary
mis à jour : pareil pour le bug sectorID.
- Méthode
ODBC : vérifier l'accessibilité du classeur Excel, sinon c'est vraiment trop
lent ;
- ExcelLibrary
mis à jour : il fallait installer un client Subversion svn.
- clsODBC : Vérification du dépassement de colonnes (si le
contenu d'un champ contient lui-même le séparateur de champ :
tabulation) ;
- Utilisation
de la librairie rapide ExcelLibrary (conservation de la méthode ODBC seulement
pour regrouper plusieurs feuilles Excel dans un fichier csv fusionné) : la
méthode XL2Txt est maintenant bien adaptée pour indexer des fichiers Excel via VBTextFinder ;
- Cases à
cocher pour choisir les menus contextuels à installer dans le registre ;
- Possibilité
de lire une liste de cellules indiquées par leur adresse au format Excel : bLireCellulesXLAutomation et bLireCellulesXLRapide,
ainsi que leur couleurs : bLireCellulesXLCouleurs
(via automation seulement).
- Bug
corrigé : Classeur Excel contenant une tabulation dans la valeur d'un champ (ne
plante plus mais le résultat est décalé : désactiver bLireToutDUnBloc
si nécessaire) ;
- Bug
corrigé : Classeur ne contenant qu'une feuille vide (s'il y a une entête, on
l'écrit dans le fichier csv, sinon on indique que le fichier est vide ; en mode
regroupement, on ignore la feuille, et en mode texte, on écrit toujours
l'entête, qui vaut F1 si la feuille est vide) ;
- Optimisation
: utilisation de l'option : "Supprimer les contrôles de dépassement sur
les entiers" ;
- Dernière
version pour modUtilFichier, modUtilReg
et clsODBC ;
- Passage
en VB 2008.
- Gestion
améliorée de l'échec en écriture (fichier protégé, ...) ;
- Bug
corrigé : Menu convertir en fichiers csv s'il n'y a qu'une seule feuille :
produire seulement un fichier csv du nom de cette feuille (et non pas deux
fichiers identiques dont un avec le nom du fichier Excel d'origine).
- VBExcelLibrary : Lire rapidement un classeur Excel sans Excel ni ODBC
https://codes-sources.commentcamarche.net/source/52083
- ODBCDotNet : Extraire des requêtes ODBC dans un tableau de tableaux de String
Code source : ODBCDotNet.vbproj.html
- DBComp :
le comparateur de structure de base de données Access (ou ODBC) avec Windiff
Code source : DBComp.vbp.html
- www.csharpfr.com/codes/BULK-COPY-EXCEL-VERS-SQL-SERVER_41677.aspx
- OO Programming By Example : CsvFileImporter
www.codeproject.com/KB/architecture/OOPbyExample.aspx
- A Fast CSV Reader
www.codeproject.com/KB/database/CsvReader.aspx
- Read
Excel files in pure C# without interop
(ExcelLibrary)
www.codeproject.com/office/ExcelReader.asp
- Fast Excel file reader with basic functionality
www.codeproject.com/KB/office/Excel_DataReader.aspx
- CSV to
Excel XML Spreadsheet with
VB.net
www.codeproject.com/KB/office/csvtoexcelxml.aspx
- www.codeproject.com/csharp/AnyDataFileToXmlConverter.asp
- Excel
Export Component Using XSL