Accueil > > > IMPORTER/EXPORTER FACILEMENT VOS DONNÉES SOUS DIFFÉRENTS FORMATS
IMPORTER/EXPORTER FACILEMENT VOS DONNÉES SOUS DIFFÉRENTS FORMATS
Information sur la source
Description
Dans mes développements quotidiens, j'avais besoin d'une API qui facilite l'importation et l'exportation de données sous différents formats. Malheureusement, la plupart des APIs disponibles sur la toile ne se préoccupent que de l'exportation. Qui plus est, elles ont la fâcheuse habitude d'ajouter des éléments de mise en forme aux documents générés qui les rendent difficilement modifiables (cf. Crystal Reports). Le seul outil véritablement fiable que j'ai trouvé c'est le service DTS de SQL server. Cependant, son utilisation dans une application .NET complique un peu le déploiement. Tout ceci m'a donc amené à chercher une solution personnelle. Dans cette source, je vous propose une classe utilitaire qui gère l'importation et l'exportation des données sous quatre formats: XML, CSV, Document Word et Classeur Excel. La démo n'est pas très exsaustive mais bon...A vous de définir la façon dont vous l'utiliserez. Les difficultés de déploiement sont moindre car il suffit que l'utilisateur final dispose de MS Office (Il est rare que ce ne soit pas le cas).
Source
- Imports System.IO
- Imports Addy.Utilities
-
-
- '==================================================================================
- ' Englobe les fonctionnalités d'échange de données avec les applications les plus
- ' courantes. Gère l'importation et l'exportation du contenu d'un DataSet ADO.NET
- ' sous l'un des formats suivants: XML, CSV, Document Word et Classeur Excel.
- '==================================================================================
- Public Class DataExchange
-
- #Region " Constantes "
-
- Const WORD_MAX_ROWS As Integer = 32767
- Const EXCEL_MAX_ROWS As Integer = 65535
- Const DEFAULT_FIELD_SEPARATOR As Char = ";"c
-
- #End Region
-
- #Region " Export "
-
- #Region " Generique "
-
- ' Permet d'exporter les données d'un DataSet vers un fichier.
- ' L'extension du nom de fichier permet de déviner le format.
- Public Shared Sub Export(ByVal dataSet As DataSet, ByVal fileName As String)
- Dim ext As String = Path.GetExtension(fileName)
- Select Case ext.ToLower()
- Case ".xml"
- ExportXml(dataSet, fileName)
- Case ".csv"
- ExportCSV(dataSet.Tables(0), fileName)
- Case ".doc"
- ExportWord(dataSet, fileName)
- Case ".xls"
- ExportExcel(dataSet, fileName)
- Case Else
- Throw New InvalidOperationException("Ce format de fichier n'est pas pris en charge")
- End Select
- End Sub
-
- #End Region
-
- #Region " XML "
-
- ' Exporte les données d'un DataSet vers un document XML
- Public Shared Sub ExportXml(ByVal dataSet As DataSet, ByVal fileName As String)
- dataSet.WriteXml(fileName)
- End Sub
-
- ' Exporte une plage de données d'un DataTable vers un document XML
- Public Shared Sub ExportXml(ByVal dataTable As DataTable, ByVal fileName As String, ByVal startIndex As Integer, ByVal rowCount As Integer)
- ' On crée un DataSet et on y met une copie du DataTable
- Dim dataSet As New dataSet(dataTable.TableName)
- Dim dtClone As dataTable = dataTable.Clone()
- dataSet.Tables.Add(dtClone)
-
- ' Par la suite, on transfarère une copie des lignes à exporter dans la copie du DataTable
- Dim i As Integer = startIndex
- Dim n As Integer = Math.Min(startIndex + rowCount, dataTable.Rows.Count)
-
- While i < n
- dtClone.ImportRow(dataTable.Rows(i))
- i += 1
- End While
-
- ' On termine en enregistrant le tout au format XML
- dataSet.WriteXml(fileName)
- End Sub
-
- ' Exporte toutes les données d'un DataTable vers un document XML
- Public Shared Sub ExportXml(ByVal dataTable As DataTable, ByVal fileName As String)
- ExportXml(dataTable, fileName, 0, Integer.MaxValue)
- End Sub
-
- #End Region
-
- #Region " CSV "
-
- ' Exporte une plage de données d'un DataTable vers un fichier texte
- ' Chaque enregistrement sera écrit sur une seule ligne. Un caractère spécial sera
- ' utilisé comme séparatier de champs. Un autre sera utilisé pour entourer les champs.
- Public Shared Sub ExportCSV(ByVal dataTable As DataTable, ByVal fileName As String, _
- ByVal startIndex As Integer, ByVal rowCount As Integer, ByVal fieldSeparator As Char, _
- ByVal fieldContainer As Char)
-
- ' Ouvrir un fichier texte en écriture
- Dim csvFile As New StreamWriter(fileName)
- Dim n As Integer = dataTable.Columns.Count
-
- ' Ecrire les noms de colonnes sur la première ligne en les séparant par des points-virgules
- For j As Integer = 0 To n - 2
- csvFile.Write(DataFormat.QuotedString(dataTable.Columns(j).ColumnName, fieldContainer))
- csvFile.Write(fieldSeparator)
- Next j
-
- csvFile.WriteLine(DataFormat.QuotedString(dataTable.Columns(n - 1).ColumnName, fieldContainer))
-
- ' Ecrire chaque enregistrement par la suite en respectant la même logique
- Dim i As Integer = startIndex
- Dim m As Integer = Math.Min(startIndex + rowCount, dataTable.Rows.Count)
-
- While i < m
- For j As Integer = 0 To n - 2
- csvFile.Write(DataFormat.QuotedString(Convert.ToString(dataTable.Rows(i)(j)), fieldContainer))
- csvFile.Write(fieldSeparator)
- Next j
-
- csvFile.WriteLine(DataFormat.QuotedString(Convert.ToString(dataTable.Rows(i)(n - 1)), fieldContainer))
- i += 1
- End While
-
- ' Fermer le fichier
- csvFile.Close()
- End Sub
-
- ' Une surchage pour laquelle fieldSeparator vaut le poit-virgule tandis que fieldContainer est le caractère nul (donc pas de conteneur de champs)
- Public Shared Sub ExportCSV(ByVal dataTable As DataTable, ByVal fileName As String, ByVal startIndex As Integer, ByVal rowCount As Integer)
- ExportCSV(dataTable, fileName, startIndex, rowCount, DEFAULT_FIELD_SEPARATOR, Char.MinValue)
- End Sub
-
- ' Une surchage sans borne (on exporte toute la table)
- Public Shared Sub ExportCSV(ByVal dataTable As DataTable, ByVal fileName As String, ByVal fieldSeparator As Char, ByVal fieldContainer As Char)
- ExportCSV(dataTable, fileName, 0, Integer.MaxValue, fieldSeparator, fieldContainer)
- End Sub
-
- ' Une surchage sans borne et pour laquelle fieldSeparator vaut le poit-virgule tandis que fieldContainer est le caractère nul
- Public Shared Sub ExportCSV(ByVal dataTable As DataTable, ByVal fileName As String)
- ExportCSV(dataTable, fileName, 0, Integer.MaxValue, DEFAULT_FIELD_SEPARATOR, Char.MinValue)
- End Sub
-
- ' Exporte les données d'un DataSet vers un ensemble de fichiers texte à valeurs separées par des caractères spéciaux.
- ' Chaque table est exportée vers un fichier distinct. Tous ces fichiers sont regroupés dans le même dossier
- Public Shared Sub ExportCSV(ByVal dataSet As DataSet, ByVal dirName As String, ByVal fieldSeparator As Char, ByVal fieldContainer As Char)
- ' On crée le répertoire du groupe...
- If Not Directory.Exists(dirName) Then
- Directory.CreateDirectory(dirName)
- End If
-
- ' ...et on exporte chaque jeu d'enregistrements du groupe de données vers un fichier qui porte son nom
- For Each table As DataTable In dataSet.Tables
- ExportCSV(table, Path.Combine(dirName, table.TableName & ".csv"), fieldSeparator, fieldContainer)
- Next
- End Sub
-
- ' Exporte les données d'un DataSet vers un ensemble de fichiers texte à valeurs separées par des point-virgules.
- Public Shared Sub ExportCSV(ByVal dataSet As DataSet, ByVal dirName As String)
- ExportCSV(dataSet, dirName, DEFAULT_FIELD_SEPARATOR, Char.MinValue)
- End Sub
-
- #End Region
-
- #Region " Word "
-
- ' Exporte les données d'un DataSet vers un document Word
- Public Shared Sub ExportWord(ByVal dataSet As DataSet, ByVal fileName As String)
- ' Lancer Word en arrière-plan
- Dim wordApp As New Word.ApplicationClass
-
- Try
- ' Créer un nouveau document
- Dim document As Word.Document = wordApp.Documents.Add()
-
- ' Définir Arial (taille 10) comme police par défaut du document
- Dim range As Word.Range = document.Content
- range.Font.Name = "Arial"
- range.Font.Size = 10
-
- ' Exporter chaque DataTable dans un tableau spécifique
- For Each dataTable As dataTable In dataSet.Tables
- ExportWord(dataTable, document, range, 0, WORD_MAX_ROWS)
- SkipToNextParagraph(range)
- Next
-
- ' Enregistrer le document sous le chemin spécifié
- document.SaveAs(CObj(fileName))
- Catch ex As System.Runtime.InteropServices.COMException
- Throw New ApplicationException(ex.Message, ex)
- Finally
- ' Quitter Word
- wordApp.Quit()
- End Try
- End Sub
-
- ' Exporte une plage de données d'un DataTable vers un document Word
- Public Shared Sub ExportWord(ByVal dataTable As DataTable, ByVal fileName As String, ByVal startIndex As Integer, ByVal rowCount As Integer)
- ' Lancer Word en arrière-plan
- Dim wordApp As New Word.ApplicationClass
-
- Try
- ' Créer un nouveau document
- Dim document As Word.Document = wordApp.Documents.Add()
-
- ' Définir Arial (taille 10) comme police par défaut du document
- Dim range As Word.Range = document.Content
- range.Font.Name = "Arial"
- range.Font.Size = 10
-
- ' Exporter la plage de DataRows dans un tableau spécifique
- ExportWord(dataTable, document, range, startIndex, rowCount)
-
- ' Enregistrer le document sous le chemin spécifié
- document.SaveAs(CObj(fileName))
- Catch ex As System.Runtime.InteropServices.COMException
- Throw New ApplicationException(ex.Message, ex)
- Finally
- ' Quitter Word
- wordApp.Quit()
- End Try
- End Sub
-
- ' Exporte toutes les données d'un DataTable vers un document Word
- Public Shared Sub ExportWord(ByVal dataTable As DataTable, ByVal fileName As String)
- ExportWord(dataTable, fileName, 0, WORD_MAX_ROWS)
- End Sub
-
- ' Définit la logique d'exportation vers Word à proprement parler
- Private Shared Sub ExportWord(ByVal dataTable As DataTable, ByVal document As Word.Document, ByVal range As Word.Range, ByVal startIndex As Integer, ByVal rowCount As Integer)
- Dim m As Integer = Math.Min(rowCount, WORD_MAX_ROWS - 2)
- Dim n As Integer = dataTable.Columns.Count
-
- With document.Tables.Add(range, m + 2, n) ' Créer un tableau dans la plage "range"
- .Cell(1, 1).Merge(.Cell(1, n)) ' Fusionner toutes les cellules de la première ligne du tableau
- With .Cell(1, 1).Range ' Mettre l'unique cellule de cette ligne en forme et lui affecter le nom du DataTable
- .Shading.BackgroundPatternColor = Word.WdColor.wdColorGray15
- .ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
- .Font.Size = 16
- .Bold = True
- .Text = dataTable.TableName
- End With ' Cell(1, 1).Range
-
- ' Les cellules de la deuxième ligne contiendront les noms de colonnes
- For i As Integer = 0 To n - 1
- With .Cell(2, i + 1).Range
- .ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
- .Bold = True
- .Text = dataTable.Columns(i).ColumnName
- End With ' Cell(2, i + 1).Range
- Next i
-
- ' Les autres cellules du tableau contiendront les valeurs du DataTable
- Dim k As Integer = startIndex, l As Integer = 3
- Dim m2 As Integer = Math.Min(startIndex + m, dataTable.Rows.Count)
-
- While k < m2
- For j As Integer = 0 To n - 1
- .Cell(l, j + 1).Range.Text = Convert.ToString(dataTable.Rows(k)(j))
- Next j
- l += 1
- k += 1
- End While
-
- .AutoFitBehavior(Word.WdAutoFitBehavior.wdAutoFitContent) ' Ajuster la taille du tableau à son contenu
- .Borders.OutsideLineStyle = Word.WdLineStyle.wdLineStyleSingle ' Encadrer le tableau à l'exterieur...
- .Borders.InsideLineStyle = Word.WdLineStyle.wdLineStyleSingle ' ...et à l'intérieur (afficher le quadrillage)
- End With ' Word.Tables.Add
- End Sub
-
- #End Region
-
- #Region " Excel "
-
- ' Exporte les données d'un DataSet vers un classeur Excel
- Public Shared Sub ExportExcel(ByVal dataSet As DataSet, ByVal fileName As String)
- ' Lancer Excel en arrière-plan
- Dim excelApp As New Excel.ApplicationClass
-
- Try
- Dim workBook As Excel.Workbook = excelApp.Workbooks.Add()
-
- ' Avant de continuer, on enregistre les feuilles par défaut créées
- ' dans le classeur afin de pouvoir les supprimer plus tard
- Dim defaultSheets As New ArrayList
- For i As Integer = 1 To workBook.Sheets.Count
- defaultSheets.Add(workBook.Sheets(i))
- Next
-
- ' On parcourre la collection de DataTables du DataSet et
- ' on crée une feuille de calcul pour chacun
- For Each table As DataTable In dataSet.Tables
- ExportExcel(table, workBook, 0, Integer.MaxValue)
- Next
-
- ' Supprimer les feuilles par défaut (Feuil1...Feuil3 ou Sheet1...Sheet3 ou...)
- ' Il est impossible de les supprimer toutes au départ car un classeur Excel
- ' doit toujours conténir une feuille au moins
- For Each worksheet As Excel.Worksheet In defaultSheets
- worksheet.Delete()
- Next
-
- ' Sauvegarder le classeur
- workBook.SaveAs(fileName)
- Catch ex As System.Runtime.InteropServices.COMException
- Throw New ApplicationException(ex.Message, ex)
- Finally
- ' Quitter Excel
- excelApp.Quit()
- End Try
- End Sub
-
- ' Exporte une plage de données de DataTable vers un classeur Excel
- Public Shared Sub ExportExcel(ByVal dataTable As DataTable, ByVal fileName As String, ByVal startIndex As Integer, ByVal rowCount As Integer)
- ' Lancer Excel en arrière-plan
- Dim excelApp As New Excel.ApplicationClass
-
- Try
- Dim workBook As Excel.Workbook = excelApp.Workbooks.Add()
-
- ' Avant de continuer, on enregistre les feuilles par défaut créées
- ' dans le classeur afin de pouvoir les supprimer plus tard
- Dim defaultSheets As New ArrayList
- For i As Integer = 1 To workBook.Sheets.Count
- defaultSheets.Add(workBook.Sheets(i))
- Next
-
- ' On crée une feuille de calcul pour le DataTable
- ExportExcel(dataTable, workBook, startIndex, rowCount)
-
- ' Supprimer les feuilles par défaut (Feuil1...Feuil3 ou Sheet1...Sheet3 ou...)
- ' Il est impossible de les supprimer toutes au départ car un classeur Excel
- ' doit toujours conténir une feuille au moins
- For Each worksheet As Excel.Worksheet In defaultSheets
- worksheet.Delete()
- Next
-
- ' Sauvegarder le classeur
- workBook.SaveAs(fileName)
- Catch ex As System.Runtime.InteropServices.COMException
- Throw New ApplicationException(ex.Message, ex)
- Finally
- ' Quitter Excel
- excelApp.Quit()
- End Try
- End Sub
-
- ' Exporte toutes les données de DataTable vers un classeur Excel
- Public Shared Sub ExportExcel(ByVal dataTable As DataTable, ByVal fileName As String)
- ExportExcel(dataTable, fileName, 0, Integer.MaxValue)
- End Sub
-
- Private Shared Sub ExportExcel(ByVal dataTable As DataTable, ByVal workBook As Excel.Workbook, ByVal startIndex As Integer, ByVal rowCount As Integer)
- Dim m As Integer = Math.Min(Math.Min(rowCount, dataTable.Rows.Count), EXCEL_MAX_ROWS)
- Dim n As Integer = dataTable.Columns.Count
-
- With CType(workBook.Worksheets.Add(), Excel.Worksheet)
- .Name = dataTable.TableName ' Le nom de la feulle est celui du DataTable
-
- ' La première ligne de la feuille contient les noms de colonnes
- Dim headers(n - 1) As String
- For i As Integer = 0 To n - 1
- headers(i) = dataTable.Columns(i).ColumnName
- Next
-
- ' Définir la ligne d'en-tête
- With .Range(GetExcelRange(0, 0, 0, n - 1))
- .Font.Bold = True
- .HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter
- .Value2 = headers
- End With
-
- ' Les autres lignes contiennent les données du jeu d'enregistrements
- Dim k As Integer = startIndex, l As Integer = 0
- Dim m2 As Integer = Math.Min(startIndex + rowCount, m)
- Dim values(m - 1, n - 1) As String ' toutes les valeurs seront exportés sous-forme de texte
-
- While k < m2
- For j As Integer = 0 To n - 1
- values(l, j) = Convert.ToString(dataTable.Rows(k)(j))
- Next
- l += 1
- k += 1
- End While
-
- ' Définir les valeurs de cellule
- .Range(GetExcelRange(1, 0, m, n - 1)).Value2 = values
-
- ' Définir la zone d'impression à la plage nouvellement créée
- Dim printArea As String = GetExcelRange(0, 0, m, n - 1)
- .PageSetup.PrintArea = printArea
- .Range(printArea).Columns.AutoFit()
- End With
- End Sub
-
- #End Region
-
- #End Region
-
- #Region " Import "
-
- #Region " Générique "
-
- ' Permet d'importer les données d'un DataSet depuis un fichier.
- ' L'extension du nom de fichier permet de déviner le format.
- ' DataExchange n'a aucune idée du SGBD à partir duquel les données seront importées.
- ' Pour cette raison, le schema du groupe de données doit avoir été créé avant l'appel de cette méthode.
- ' La méthode FillSchema des DataAdapters peut être utilisée à cet effet.
- ' Si des colonnes ont été renommées dans la table de destination, ouvrir
- ' le document source et y renommer les colonnes avant l'importation.
- ' Les colonnes qui ne sont pas mappées dans le schema du DataSet seront ignorées.
- ' La même politique s'applique aux tables.
- ' La mise à jour effective peut se faire soit en invoquant la méthode Update d'un DataAdapter,
- ' Soit en parcourrant chaque jeu d'enregistrements et en exécutant un ordre SQL INSERT
- Public Shared Sub Import(ByVal dataSet As DataSet, ByVal fileName As String)
- Dim ext As String = Path.GetExtension(fileName)
- Select Case ext.ToLower()
- Case ".xml"
- ImportXml(dataSet, fileName)
- Case ".csv"
- ImportCSV(dataSet.Tables(0), fileName)
- Case ".doc"
- ImportWord(dataSet, fileName)
- Case ".xls"
- ImportExcel(dataSet, fileName)
- Case Else
- Throw New InvalidOperationException("Ce format de fichier n'est pas pris en charge")
- End Select
- End Sub
-
- #End Region
-
- #Region " XML "
-
- ' Importe les données d'un DataSet depuis un document XML
- Public Shared Sub ImportXml(ByVal dataSet As DataSet, ByVal fileName As String)
- dataSet.ReadXml(fileName)
- End Sub
-
- ' Importe une plage de données d'un DataTable vers un document XML
- Public Shared Sub ImportXml(ByVal dataTable As DataTable, ByVal fileName As String)
- ' On lit le document XML à partir d'un DataSet ...
- Dim dataSet As New dataSet
- dataSet.ReadXml(fileName)
-
- ' ...et on importe le contenu du DataSet dans dataTable
- For Each row As DataRow In dataSet.Tables(dataTable.TableName).Rows
- dataTable.ImportRow(row)
- Next
- End Sub
-
- #End Region
-
- #Region " CSV "
-
- ' Importe les données d'un DataSet depuis un fichier texte à valeurs separées par des points-virgules.
- ' Dans ce cas, fileName est sensé désigner un répertoire plutôt qu'un fichier
- Public Shared Sub ImportCSV(ByVal dataSet As DataSet, ByVal dirName As String)
- For Each table As DataTable In dataSet.Tables
- Dim fileName As String = Path.Combine(dirName, table.TableName & ".csv")
- If File.Exists(fileName) Then ImportCSV(table, fileName)
- Next
- End Sub
-
- ' Importe les données d'un DataTable depuis un fichier texte à valeurs separées par des points-virgules
- Public Shared Sub ImportCSV(ByVal dataSet As DataSet, ByVal tableName As String, ByVal fileName As String)
- ImportCSV(dataSet.Tables(tableName), fileName)
- End Sub
-
- ' Importe les données d'un DataTable depuis un fichier texte à valeurs separées par des points-virgules
- Public Shared Sub ImportCSV(ByVal dataTable As DataTable, ByVal fileName As String)
- ' Ouvrir le fichier et lire son contenu d'une seule traite
- Dim csvFile As New StreamReader(fileName)
- Dim csvContent As String = csvFile.ReadToEnd()
- csvFile.Close()
-
- ' Décomposer le contenu du fichier en lignes
- Dim csvLines() As String = csvContent.Split(vbCrLf.ToCharArray())
- ' La première ligne contient les noms de colonnes
- Dim columnNames() As String = csvLines(0).Split(";"c)
-
- ' S'il n'y a aucune colonne ont sort.
- If columnNames.Length <= 0 Then Return
-
- ' Chacune des autres lignes contient un enregistrement
- For i As Integer = 1 To csvLines.GetUpperBound(0)
- If csvLines(i) <> "" Then ' Sauter les lignes blanches résultant du split
- Dim csvFields() As String = csvLines(i).Split(";"c)
- Dim row As DataRow = dataTable.NewRow()
-
- ' Transférer chaque champ dans le nouvel enregistrement.
- ' Sauter les colonnes qui ne sont pas mappées dans le DataSet
- For j As Integer = 0 To columnNames.GetUpperBound(0)
- If csvFields(j) <> "" And dataTable.Columns.Contains(columnNames(j)) Then
- row(columnNames(j)) = csvFields(j)
- End If
- Next j
-
- ' L'insertion du nouvel enregistrement peut echouer pour des raisons
- ' d'intégrité des données. Dans ce cas, on ignore l'echec et on continue
- Try
- dataTable.Rows.Add(row)
- Catch ex As Exception
- End Try
- End If ' csvLine(i) <> ""
- Next i
- End Sub
-
- #End Region
-
- #Region " Word "
-
- ' Importe les données d'un DataSet depuis un document Word.
- ' Dans le document source, chaque table est représentée par un tableau.
- ' La première cellule d'un tableau s'étend sur toute une ligne et contient le nom de la table.
- ' Les cellules de la deuxième ligne contiennent les noms de colonnes.
- ' Le reste du tableau contient les données de la table.
- Public Shared Sub ImportWord(ByVal dataSet As DataSet, ByVal fileName As String)
- With New Word.ApplicationClass ' Lancer Word en arrière-plan
- With .Documents.Open(CObj(fileName)) ' Ouvrir le document source
- For i As Integer = 1 To .Tables.Count ' Parcourir sa collection de tableaux
- With .Tables(i) ' A chaque tableau, associer un DataTable dans le DataSet
- Dim tableName As String = TrimNoises(.Cell(1, 1).Range.Text)
- If dataSet.Tables.Contains(tableName) Then ' Sauter les tables qui ne sont pas mappés dans le DataSet
- Dim dataTable As DataTable = dataSet.Tables(tableName)
-
- For j As Integer = 3 To .Rows.Count
- Dim dataRow As DataRow = dataTable.NewRow()
-
- ' Transférer chaque champ dans le nouvel enregistrement.
- ' Sauter les colonnes qui ne sont pas mappées dans le DataSet
- For k As Integer = 1 To .Columns.Count
- Dim columnName As String = TrimNoises(.Cell(2, k).Range.Text)
- Dim cellValue As String = TrimNoises(.Cell(j, k).Range.Text)
- If cellValue <> "" And dataTable.Columns.Contains(columnName) Then
- dataRow(columnName) = cellValue
- End If
- Next k
-
- ' L'insertion du nouvel enregistrement peut echouer pour des raisons
- ' d'intégrité des données. Dans ce cas, on ignore l'echec et on continue
- Try
- dataTable.Rows.Add(dataRow)
- Catch ex As Exception
- End Try
- Next j
- End If
- End With ' Word.Table
- Next i
-
- .Close() ' Fermer le document
- End With ' Word.Document
-
- .Quit() ' Quitter Word
- End With ' Word.Application
- End Sub
-
- #End Region
-
- #Region " Excel "
-
- ' Importe les données d'un DataSet depuis un classeur Excel.
- ' Dans le document source, chaque table est représentée par une feuille de calcul.
- ' Les cellules de la première ligne contiennent les noms de colonnes.
- ' Le reste de la feuille de calcul contient les données de la table.
- Public Shared Sub ImportExcel(ByVal dataSet As DataSet, ByVal fileName As String)
- ' Lancer Excel en arrière-plan
- Dim excelApp As New Excel.ApplicationClass
-
- Try
- ' Ouvrir le classeur fileName
- Dim workBook As Excel.Workbook = excelApp.Workbooks.Open(fileName)
- ' Importer chaque feuille de calcul dans le DataTable de même nom
- For Each worksheet As Excel.Worksheet In workBook.Worksheets
- If dataSet.Tables.Contains(worksheet.Name) Then
- ImportExcel(dataSet.Tables(worksheet.Name), worksheet)
- End If
- Next
- Catch ex As System.Runtime.InteropServices.COMException
- Throw New ApplicationException(ex.Message, ex)
- Finally
- ' Quitter Excel
- excelApp.Quit()
- End Try
- End Sub
-
- Public Shared Sub ImportExcel(ByVal dataTable As DataTable, ByVal fileName As String)
- ' Lancer Excel en arrière-plan
- Dim excelApp As New Excel.ApplicationClass
-
- Try
- ' Ouvrir le classeur fileName
- Dim workBook As Excel.Workbook = excelApp.Workbooks.Open(fileName)
- ' Importer la feuille de calcul dans le DataTable de même nom
- For Each worksheet As Excel.Worksheet In workBook.Worksheets
- If worksheet.Name = dataTable.TableName Then
- ImportExcel(dataTable, worksheet)
- Exit For
- End If
- Next
- Catch ex As System.Runtime.InteropServices.COMException
- Throw New ApplicationException(ex.Message, ex)
- Finally
- ' Quitter Excel
- excelApp.Quit()
- End Try
- End Sub
-
- Private Shared Sub ImportExcel(ByVal dataTable As DataTable, ByVal worksheet As Excel.Worksheet)
- ' Localiser la dernière colonne
- Dim lastCol As Excel.Range = worksheet.Range("A1").End(Excel.XlDirection.xlToRight)
- ' Localiser la dernière ligne
- Dim lastRow As Excel.Range = worksheet.Range("A1").End(Excel.XlDirection.xlDown)
- ' Extraire toutes les données de la feuille de calcul en une seule opération
- Dim rangeName As String = GetExcelRange(0, 0, lastRow.Row - 1, lastCol.Column - 1)
- Dim values As Object(,) = worksheet.Range(rangeName).Value2
-
- ' Transférérer les données extraites dans le DataTable
- For i As Integer = 2 To values.GetUpperBound(0) Step 1
- Dim newRow As DataRow = dataTable.NewRow()
- For j As Integer = 1 To values.GetUpperBound(1) Step 1
- If Nothing Is values(i, j) Then
- newRow(values(1, j).ToString()) = DBNull.Value
- Else
- newRow(values(1, j).ToString()) = values(i, j)
- End If
- Next
- dataTable.Rows.Add(newRow)
- Next
- End Sub
-
- #End Region
-
- #End Region
-
- #Region " Méthodes utilitaires "
-
- ' Permet d'obtenir le nom d'un cellule Excel à partir de ses coordonnées.
- ' Par exemple, pour les coordonnées (0, 0) on obtiendrait "A1".
- ' Le nombre de colonnes ne doit pas dépasser 26, sinon...
- Private Shared Function GetExcelRange(ByVal rowIndex As Integer, ByVal columnIndex As Integer) As String
- Return ChrW(columnIndex + 65) & (rowIndex + 1)
- End Function
-
- ' Permet d'obtenir le nom d'une plages de cellules Excel à partir de ses coordonnées.
- Private Shared Function GetExcelRange(ByVal startRowIndex As Integer, ByVal startColumnIndex As Integer, ByVal endRowIndex As Integer, ByVal endColumnIndex As Integer) As String
- Return GetExcelRange(startRowIndex, startColumnIndex) & ":" & GetExcelRange(endRowIndex, endColumnIndex)
- End Function
-
- ' Permet de sauter au paragraphe suivant d'un document Word
- Private Shared Sub SkipToNextParagraph(ByVal range As Word.Range)
- range.InsertParagraphAfter() ' Ajouter un paragraphe à la suite de la plage en cours
- range.Collapse(Word.WdCollapseDirection.wdCollapseEnd) ' Réduire la plage à sa fin
- range.MoveEnd(Word.WdUnits.wdParagraph, 1) ' Sauter au paragraphe suivant
- End Sub
-
- ' Permet de débarrasser une chaîne de caractères d'éventuels symboles indésirables.
- ' Ces symboles que j'appelle "bruits" entourrent parfois le texte extrait de Word
- Private Shared Function TrimNoises(ByVal s As String) As String
- Return s.Trim(ChrW(7), ChrW(13))
- End Function
-
- #End Region
-
- End Class
Imports System.IO
Imports Addy.Utilities
'==================================================================================
' Englobe les fonctionnalités d'échange de données avec les applications les plus
' courantes. Gère l'importation et l'exportation du contenu d'un DataSet ADO.NET
' sous l'un des formats suivants: XML, CSV, Document Word et Classeur Excel.
'==================================================================================
Public Class DataExchange
#Region " Constantes "
Const WORD_MAX_ROWS As Integer = 32767
Const EXCEL_MAX_ROWS As Integer = 65535
Const DEFAULT_FIELD_SEPARATOR As Char = ";"c
#End Region
#Region " Export "
#Region " Generique "
' Permet d'exporter les données d'un DataSet vers un fichier.
' L'extension du nom de fichier permet de déviner le format.
Public Shared Sub Export(ByVal dataSet As DataSet, ByVal fileName As String)
Dim ext As String = Path.GetExtension(fileName)
Select Case ext.ToLower()
Case ".xml"
ExportXml(dataSet, fileName)
Case ".csv"
ExportCSV(dataSet.Tables(0), fileName)
Case ".doc"
ExportWord(dataSet, fileName)
Case ".xls"
ExportExcel(dataSet, fileName)
Case Else
Throw New InvalidOperationException("Ce format de fichier n'est pas pris en charge")
End Select
End Sub
#End Region
#Region " XML "
' Exporte les données d'un DataSet vers un document XML
Public Shared Sub ExportXml(ByVal dataSet As DataSet, ByVal fileName As String)
dataSet.WriteXml(fileName)
End Sub
' Exporte une plage de données d'un DataTable vers un document XML
Public Shared Sub ExportXml(ByVal dataTable As DataTable, ByVal fileName As String, ByVal startIndex As Integer, ByVal rowCount As Integer)
' On crée un DataSet et on y met une copie du DataTable
Dim dataSet As New dataSet(dataTable.TableName)
Dim dtClone As dataTable = dataTable.Clone()
dataSet.Tables.Add(dtClone)
' Par la suite, on transfarère une copie des lignes à exporter dans la copie du DataTable
Dim i As Integer = startIndex
Dim n As Integer = Math.Min(startIndex + rowCount, dataTable.Rows.Count)
While i < n
dtClone.ImportRow(dataTable.Rows(i))
i += 1
End While
' On termine en enregistrant le tout au format XML
dataSet.WriteXml(fileName)
End Sub
' Exporte toutes les données d'un DataTable vers un document XML
Public Shared Sub ExportXml(ByVal dataTable As DataTable, ByVal fileName As String)
ExportXml(dataTable, fileName, 0, Integer.MaxValue)
End Sub
#End Region
#Region " CSV "
' Exporte une plage de données d'un DataTable vers un fichier texte
' Chaque enregistrement sera écrit sur une seule ligne. Un caractère spécial sera
' utilisé comme séparatier de champs. Un autre sera utilisé pour entourer les champs.
Public Shared Sub ExportCSV(ByVal dataTable As DataTable, ByVal fileName As String, _
ByVal startIndex As Integer, ByVal rowCount As Integer, ByVal fieldSeparator As Char, _
ByVal fieldContainer As Char)
' Ouvrir un fichier texte en écriture
Dim csvFile As New StreamWriter(fileName)
Dim n As Integer = dataTable.Columns.Count
' Ecrire les noms de colonnes sur la première ligne en les séparant par des points-virgules
For j As Integer = 0 To n - 2
csvFile.Write(DataFormat.QuotedString(dataTable.Columns(j).ColumnName, fieldContainer))
csvFile.Write(fieldSeparator)
Next j
csvFile.WriteLine(DataFormat.QuotedString(dataTable.Columns(n - 1).ColumnName, fieldContainer))
' Ecrire chaque enregistrement par la suite en respectant la même logique
Dim i As Integer = startIndex
Dim m As Integer = Math.Min(startIndex + rowCount, dataTable.Rows.Count)
While i < m
For j As Integer = 0 To n - 2
csvFile.Write(DataFormat.QuotedString(Convert.ToString(dataTable.Rows(i)(j)), fieldContainer))
csvFile.Write(fieldSeparator)
Next j
csvFile.WriteLine(DataFormat.QuotedString(Convert.ToString(dataTable.Rows(i)(n - 1)), fieldContainer))
i += 1
End While
' Fermer le fichier
csvFile.Close()
End Sub
' Une surchage pour laquelle fieldSeparator vaut le poit-virgule tandis que fieldContainer est le caractère nul (donc pas de conteneur de champs)
Public Shared Sub ExportCSV(ByVal dataTable As DataTable, ByVal fileName As String, ByVal startIndex As Integer, ByVal rowCount As Integer)
ExportCSV(dataTable, fileName, startIndex, rowCount, DEFAULT_FIELD_SEPARATOR, Char.MinValue)
End Sub
' Une surchage sans borne (on exporte toute la table)
Public Shared Sub ExportCSV(ByVal dataTable As DataTable, ByVal fileName As String, ByVal fieldSeparator As Char, ByVal fieldContainer As Char)
ExportCSV(dataTable, fileName, 0, Integer.MaxValue, fieldSeparator, fieldContainer)
End Sub
' Une surchage sans borne et pour laquelle fieldSeparator vaut le poit-virgule tandis que fieldContainer est le caractère nul
Public Shared Sub ExportCSV(ByVal dataTable As DataTable, ByVal fileName As String)
ExportCSV(dataTable, fileName, 0, Integer.MaxValue, DEFAULT_FIELD_SEPARATOR, Char.MinValue)
End Sub
' Exporte les données d'un DataSet vers un ensemble de fichiers texte à valeurs separées par des caractères spéciaux.
' Chaque table est exportée vers un fichier distinct. Tous ces fichiers sont regroupés dans le même dossier
Public Shared Sub ExportCSV(ByVal dataSet As DataSet, ByVal dirName As String, ByVal fieldSeparator As Char, ByVal fieldContainer As Char)
' On crée le répertoire du groupe...
If Not Directory.Exists(dirName) Then
Directory.CreateDirectory(dirName)
End If
' ...et on exporte chaque jeu d'enregistrements du groupe de données vers un fichier qui porte son nom
For Each table As DataTable In dataSet.Tables
ExportCSV(table, Path.Combine(dirName, table.TableName & ".csv"), fieldSeparator, fieldContainer)
Next
End Sub
' Exporte les données d'un DataSet vers un ensemble de fichiers texte à valeurs separées par des point-virgules.
Public Shared Sub ExportCSV(ByVal dataSet As DataSet, ByVal dirName As String)
ExportCSV(dataSet, dirName, DEFAULT_FIELD_SEPARATOR, Char.MinValue)
End Sub
#End Region
#Region " Word "
' Exporte les données d'un DataSet vers un document Word
Public Shared Sub ExportWord(ByVal dataSet As DataSet, ByVal fileName As String)
' Lancer Word en arrière-plan
Dim wordApp As New Word.ApplicationClass
Try
' Créer un nouveau document
Dim document As Word.Document = wordApp.Documents.Add()
' Définir Arial (taille 10) comme police par défaut du document
Dim range As Word.Range = document.Content
range.Font.Name = "Arial"
range.Font.Size = 10
' Exporter chaque DataTable dans un tableau spécifique
For Each dataTable As dataTable In dataSet.Tables
ExportWord(dataTable, document, range, 0, WORD_MAX_ROWS)
SkipToNextParagraph(range)
Next
' Enregistrer le document sous le chemin spécifié
document.SaveAs(CObj(fileName))
Catch ex As System.Runtime.InteropServices.COMException
Throw New ApplicationException(ex.Message, ex)
Finally
' Quitter Word
wordApp.Quit()
End Try
End Sub
' Exporte une plage de données d'un DataTable vers un document Word
Public Shared Sub ExportWord(ByVal dataTable As DataTable, ByVal fileName As String, ByVal startIndex As Integer, ByVal rowCount As Integer)
' Lancer Word en arrière-plan
Dim wordApp As New Word.ApplicationClass
Try
' Créer un nouveau document
Dim document As Word.Document = wordApp.Documents.Add()
' Définir Arial (taille 10) comme police par défaut du document
Dim range As Word.Range = document.Content
range.Font.Name = "Arial"
range.Font.Size = 10
' Exporter la plage de DataRows dans un tableau spécifique
ExportWord(dataTable, document, range, startIndex, rowCount)
' Enregistrer le document sous le chemin spécifié
document.SaveAs(CObj(fileName))
Catch ex As System.Runtime.InteropServices.COMException
Throw New ApplicationException(ex.Message, ex)
Finally
' Quitter Word
wordApp.Quit()
End Try
End Sub
' Exporte toutes les données d'un DataTable vers un document Word
Public Shared Sub ExportWord(ByVal dataTable As DataTable, ByVal fileName As String)
ExportWord(dataTable, fileName, 0, WORD_MAX_ROWS)
End Sub
' Définit la logique d'exportation vers Word à proprement parler
Private Shared Sub ExportWord(ByVal dataTable As DataTable, ByVal document As Word.Document, ByVal range As Word.Range, ByVal startIndex As Integer, ByVal rowCount As Integer)
Dim m As Integer = Math.Min(rowCount, WORD_MAX_ROWS - 2)
Dim n As Integer = dataTable.Columns.Count
With document.Tables.Add(range, m + 2, n) ' Créer un tableau dans la plage "range"
.Cell(1, 1).Merge(.Cell(1, n)) ' Fusionner toutes les cellules de la première ligne du tableau
With .Cell(1, 1).Range ' Mettre l'unique cellule de cette ligne en forme et lui affecter le nom du DataTable
.Shading.BackgroundPatternColor = Word.WdColor.wdColorGray15
.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
.Font.Size = 16
.Bold = True
.Text = dataTable.TableName
End With ' Cell(1, 1).Range
' Les cellules de la deuxième ligne contiendront les noms de colonnes
For i As Integer = 0 To n - 1
With .Cell(2, i + 1).Range
.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
.Bold = True
.Text = dataTable.Columns(i).ColumnName
End With ' Cell(2, i + 1).Range
Next i
' Les autres cellules du tableau contiendront les valeurs du DataTable
Dim k As Integer = startIndex, l As Integer = 3
Dim m2 As Integer = Math.Min(startIndex + m, dataTable.Rows.Count)
While k < m2
For j As Integer = 0 To n - 1
.Cell(l, j + 1).Range.Text = Convert.ToString(dataTable.Rows(k)(j))
Next j
l += 1
k += 1
End While
.AutoFitBehavior(Word.WdAutoFitBehavior.wdAutoFitContent) ' Ajuster la taille du tableau à son contenu
.Borders.OutsideLineStyle = Word.WdLineStyle.wdLineStyleSingle ' Encadrer le tableau à l'exterieur...
.Borders.InsideLineStyle = Word.WdLineStyle.wdLineStyleSingle ' ...et à l'intérieur (afficher le quadrillage)
End With ' Word.Tables.Add
End Sub
#End Region
#Region " Excel "
' Exporte les données d'un DataSet vers un classeur Excel
Public Shared Sub ExportExcel(ByVal dataSet As DataSet, ByVal fileName As String)
' Lancer Excel en arrière-plan
Dim excelApp As New Excel.ApplicationClass
Try
Dim workBook As Excel.Workbook = excelApp.Workbooks.Add()
' Avant de continuer, on enregistre les feuilles par défaut créées
' dans le classeur afin de pouvoir les supprimer plus tard
Dim defaultSheets As New ArrayList
For i As Integer = 1 To workBook.Sheets.Count
defaultSheets.Add(workBook.Sheets(i))
Next
' On parcourre la collection de DataTables du DataSet et
' on crée une feuille de calcul pour chacun
For Each table As DataTable In dataSet.Tables
ExportExcel(table, workBook, 0, Integer.MaxValue)
Next
' Supprimer les feuilles par défaut (Feuil1...Feuil3 ou Sheet1...Sheet3 ou...)
' Il est impossible de les supprimer toutes au départ car un classeur Excel
' doit toujours conténir une feuille au moins
For Each worksheet As Excel.Worksheet In defaultSheets
worksheet.Delete()
Next
' Sauvegarder le classeur
workBook.SaveAs(fileName)
Catch ex As System.Runtime.InteropServices.COMException
Throw New ApplicationException(ex.Message, ex)
Finally
' Quitter Excel
excelApp.Quit()
End Try
End Sub
' Exporte une plage de données de DataTable vers un classeur Excel
Public Shared Sub ExportExcel(ByVal dataTable As DataTable, ByVal fileName As String, ByVal startIndex As Integer, ByVal rowCount As Integer)
' Lancer Excel en arrière-plan
Dim excelApp As New Excel.ApplicationClass
Try
Dim workBook As Excel.Workbook = excelApp.Workbooks.Add()
' Avant de continuer, on enregistre les feuilles par défaut créées
' dans le classeur afin de pouvoir les supprimer plus tard
Dim defaultSheets As New ArrayList
For i As Integer = 1 To workBook.Sheets.Count
defaultSheets.Add(workBook.Sheets(i))
Next
' On crée une feuille de calcul pour le DataTable
ExportExcel(dataTable, workBook, startIndex, rowCount)
' Supprimer les feuilles par défaut (Feuil1...Feuil3 ou Sheet1...Sheet3 ou...)
' Il est impossible de les supprimer toutes au départ car un classeur Excel
' doit toujours conténir une feuille au moins
For Each worksheet As Excel.Worksheet In defaultSheets
worksheet.Delete()
Next
' Sauvegarder le classeur
workBook.SaveAs(fileName)
Catch ex As System.Runtime.InteropServices.COMException
Throw New ApplicationException(ex.Message, ex)
Finally
' Quitter Excel
excelApp.Quit()
End Try
End Sub
' Exporte toutes les données de DataTable vers un classeur Excel
Public Shared Sub ExportExcel(ByVal dataTable As DataTable, ByVal fileName As String)
ExportExcel(dataTable, fileName, 0, Integer.MaxValue)
End Sub
Private Shared Sub ExportExcel(ByVal dataTable As DataTable, ByVal workBook As Excel.Workbook, ByVal startIndex As Integer, ByVal rowCount As Integer)
Dim m As Integer = Math.Min(Math.Min(rowCount, dataTable.Rows.Count), EXCEL_MAX_ROWS)
Dim n As Integer = dataTable.Columns.Count
With CType(workBook.Worksheets.Add(), Excel.Worksheet)
.Name = dataTable.TableName ' Le nom de la feulle est celui du DataTable
' La première ligne de la feuille contient les noms de colonnes
Dim headers(n - 1) As String
For i As Integer = 0 To n - 1
headers(i) = dataTable.Columns(i).ColumnName
Next
' Définir la ligne d'en-tête
With .Range(GetExcelRange(0, 0, 0, n - 1))
.Font.Bold = True
.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter
.Value2 = headers
End With
' Les autres lignes contiennent les données du jeu d'enregistrements
Dim k As Integer = startIndex, l As Integer = 0
Dim m2 As Integer = Math.Min(startIndex + rowCount, m)
Dim values(m - 1, n - 1) As String ' toutes les valeurs seront exportés sous-forme de texte
While k < m2
For j As Integer = 0 To n - 1
values(l, j) = Convert.ToString(dataTable.Rows(k)(j))
Next
l += 1
k += 1
End While
' Définir les valeurs de cellule
.Range(GetExcelRange(1, 0, m, n - 1)).Value2 = values
' Définir la zone d'impression à la plage nouvellement créée
Dim printArea As String = GetExcelRange(0, 0, m, n - 1)
.PageSetup.PrintArea = printArea
.Range(printArea).Columns.AutoFit()
End With
End Sub
#End Region
#End Region
#Region " Import "
#Region " Générique "
' Permet d'importer les données d'un DataSet depuis un fichier.
' L'extension du nom de fichier permet de déviner le format.
' DataExchange n'a aucune idée du SGBD à partir duquel les données seront importées.
' Pour cette raison, le schema du groupe de données doit avoir été créé avant l'appel de cette méthode.
' La méthode FillSchema des DataAdapters peut être utilisée à cet effet.
' Si des colonnes ont été renommées dans la table de destination, ouvrir
' le document source et y renommer les colonnes avant l'importation.
' Les colonnes qui ne sont pas mappées dans le schema du DataSet seront ignorées.
' La même politique s'applique aux tables.
' La mise à jour effective peut se faire soit en invoquant la méthode Update d'un DataAdapter,
' Soit en parcourrant chaque jeu d'enregistrements et en exécutant un ordre SQL INSERT
Public Shared Sub Import(ByVal dataSet As DataSet, ByVal fileName As String)
Dim ext As String = Path.GetExtension(fileName)
Select Case ext.ToLower()
Case ".xml"
ImportXml(dataSet, fileName)
Case ".csv"
ImportCSV(dataSet.Tables(0), fileName)
Case ".doc"
ImportWord(dataSet, fileName)
Case ".xls"
ImportExcel(dataSet, fileName)
Case Else
Throw New InvalidOperationException("Ce format de fichier n'est pas pris en charge")
End Select
End Sub
#End Region
#Region " XML "
' Importe les données d'un DataSet depuis un document XML
Public Shared Sub ImportXml(ByVal dataSet As DataSet, ByVal fileName As String)
dataSet.ReadXml(fileName)
End Sub
' Importe une plage de données d'un DataTable vers un document XML
Public Shared Sub ImportXml(ByVal dataTable As DataTable, ByVal fileName As String)
' On lit le document XML à partir d'un DataSet ...
Dim dataSet As New dataSet
dataSet.ReadXml(fileName)
' ...et on importe le contenu du DataSet dans dataTable
For Each row As DataRow In dataSet.Tables(dataTable.TableName).Rows
dataTable.ImportRow(row)
Next
End Sub
#End Region
#Region " CSV "
' Importe les données d'un DataSet depuis un fichier texte à valeurs separées par des points-virgules.
' Dans ce cas, fileName est sensé désigner un répertoire plutôt qu'un fichier
Public Shared Sub ImportCSV(ByVal dataSet As DataSet, ByVal dirName As String)
For Each table As DataTable In dataSet.Tables
Dim fileName As String = Path.Combine(dirName, table.TableName & ".csv")
If File.Exists(fileName) Then ImportCSV(table, fileName)
Next
End Sub
' Importe les données d'un DataTable depuis un fichier texte à valeurs separées par des points-virgules
Public Shared Sub ImportCSV(ByVal dataSet As DataSet, ByVal tableName As String, ByVal fileName As String)
ImportCSV(dataSet.Tables(tableName), fileName)
End Sub
' Importe les données d'un DataTable depuis un fichier texte à valeurs separées par des points-virgules
Public Shared Sub ImportCSV(ByVal dataTable As DataTable, ByVal fileName As String)
' Ouvrir le fichier et lire son contenu d'une seule traite
Dim csvFile As New StreamReader(fileName)
Dim csvContent As String = csvFile.ReadToEnd()
csvFile.Close()
' Décomposer le contenu du fichier en lignes
Dim csvLines() As String = csvContent.Split(vbCrLf.ToCharArray())
' La première ligne contient les noms de colonnes
Dim columnNames() As String = csvLines(0).Split(";"c)
' S'il n'y a aucune colonne ont sort.
If columnNames.Length <= 0 Then Return
' Chacune des autres lignes contient un enregistrement
For i As Integer = 1 To csvLines.GetUpperBound(0)
If csvLines(i) <> "" Then ' Sauter les lignes blanches résultant du split
Dim csvFields() As String = csvLines(i).Split(";"c)
Dim row As DataRow = dataTable.NewRow()
' Transférer chaque champ dans le nouvel enregistrement.
' Sauter les colonnes qui ne sont pas mappées dans le DataSet
For j As Integer = 0 To columnNames.GetUpperBound(0)
If csvFields(j) <> "" And dataTable.Columns.Contains(columnNames(j)) Then
row(columnNames(j)) = csvFields(j)
End If
Next j
' L'insertion du nouvel enregistrement peut echouer pour des raisons
' d'intégrité des données. Dans ce cas, on ignore l'echec et on continue
Try
dataTable.Rows.Add(row)
Catch ex As Exception
End Try
End If ' csvLine(i) <> ""
Next i
End Sub
#End Region
#Region " Word "
' Importe les données d'un DataSet depuis un document Word.
' Dans le document source, chaque table est représentée par un tableau.
' La première cellule d'un tableau s'étend sur toute une ligne et contient le nom de la table.
' Les cellules de la deuxième ligne contiennent les noms de colonnes.
' Le reste du tableau contient les données de la table.
Public Shared Sub ImportWord(ByVal dataSet As DataSet, ByVal fileName As String)
With New Word.ApplicationClass ' Lancer Word en arrière-plan
With .Documents.Open(CObj(fileName)) ' Ouvrir le document source
For i As Integer = 1 To .Tables.Count ' Parcourir sa collection de tableaux
With .Tables(i) ' A chaque tableau, associer un DataTable dans le DataSet
Dim tableName As String = TrimNoises(.Cell(1, 1).Range.Text)
If dataSet.Tables.Contains(tableName) Then ' Sauter les tables qui ne sont pas mappés dans le DataSet
Dim dataTable As DataTable = dataSet.Tables(tableName)
For j As Integer = 3 To .Rows.Count
Dim dataRow As DataRow = dataTable.NewRow()
' Transférer chaque champ dans le nouvel enregistrement.
' Sauter les colonnes qui ne sont pas mappées dans le DataSet
For k As Integer = 1 To .Columns.Count
Dim columnName As String = TrimNoises(.Cell(2, k).Range.Text)
Dim cellValue As String = TrimNoises(.Cell(j, k).Range.Text)
If cellValue <> "" And dataTable.Columns.Contains(columnName) Then
dataRow(columnName) = cellValue
End If
Next k
' L'insertion du nouvel enregistrement peut echouer pour des raisons
' d'intégrité des données. Dans ce cas, on ignore l'echec et on continue
Try
dataTable.Rows.Add(dataRow)
Catch ex As Exception
End Try
Next j
End If
End With ' Word.Table
Next i
.Close() ' Fermer le document
End With ' Word.Document
.Quit() ' Quitter Word
End With ' Word.Application
End Sub
#End Region
#Region " Excel "
' Importe les données d'un DataSet depuis un classeur Excel.
' Dans le document source, chaque table est représentée par une feuille de calcul.
' Les cellules de la première ligne contiennent les noms de colonnes.
' Le reste de la feuille de calcul contient les données de la table.
Public Shared Sub ImportExcel(ByVal dataSet As DataSet, ByVal fileName As String)
' Lancer Excel en arrière-plan
Dim excelApp As New Excel.ApplicationClass
Try
' Ouvrir le classeur fileName
Dim workBook As Excel.Workbook = excelApp.Workbooks.Open(fileName)
' Importer chaque feuille de calcul dans le DataTable de même nom
For Each worksheet As Excel.Worksheet In workBook.Worksheets
If dataSet.Tables.Contains(worksheet.Name) Then
ImportExcel(dataSet.Tables(worksheet.Name), worksheet)
End If
Next
Catch ex As System.Runtime.InteropServices.COMException
Throw New ApplicationException(ex.Message, ex)
Finally
' Quitter Excel
excelApp.Quit()
End Try
End Sub
Public Shared Sub ImportExcel(ByVal dataTable As DataTable, ByVal fileName As String)
' Lancer Excel en arrière-plan
Dim excelApp As New Excel.ApplicationClass
Try
' Ouvrir le classeur fileName
Dim workBook As Excel.Workbook = excelApp.Workbooks.Open(fileName)
' Importer la feuille de calcul dans le DataTable de même nom
For Each worksheet As Excel.Worksheet In workBook.Worksheets
If worksheet.Name = dataTable.TableName Then
ImportExcel(dataTable, worksheet)
Exit For
End If
Next
Catch ex As System.Runtime.InteropServices.COMException
Throw New ApplicationException(ex.Message, ex)
Finally
' Quitter Excel
excelApp.Quit()
End Try
End Sub
Private Shared Sub ImportExcel(ByVal dataTable As DataTable, ByVal worksheet As Excel.Worksheet)
' Localiser la dernière colonne
Dim lastCol As Excel.Range = worksheet.Range("A1").End(Excel.XlDirection.xlToRight)
' Localiser la dernière ligne
Dim lastRow As Excel.Range = worksheet.Range("A1").End(Excel.XlDirection.xlDown)
' Extraire toutes les données de la feuille de calcul en une seule opération
Dim rangeName As String = GetExcelRange(0, 0, lastRow.Row - 1, lastCol.Column - 1)
Dim values As Object(,) = worksheet.Range(rangeName).Value2
' Transférérer les données extraites dans le DataTable
For i As Integer = 2 To values.GetUpperBound(0) Step 1
Dim newRow As DataRow = dataTable.NewRow()
For j As Integer = 1 To values.GetUpperBound(1) Step 1
If Nothing Is values(i, j) Then
newRow(values(1, j).ToString()) = DBNull.Value
Else
newRow(values(1, j).ToString()) = values(i, j)
End If
Next
dataTable.Rows.Add(newRow)
Next
End Sub
#End Region
#End Region
#Region " Méthodes utilitaires "
' Permet d'obtenir le nom d'un cellule Excel à partir de ses coordonnées.
' Par exemple, pour les coordonnées (0, 0) on obtiendrait "A1".
' Le nombre de colonnes ne doit pas dépasser 26, sinon...
Private Shared Function GetExcelRange(ByVal rowIndex As Integer, ByVal columnIndex As Integer) As String
Return ChrW(columnIndex + 65) & (rowIndex + 1)
End Function
' Permet d'obtenir le nom d'une plages de cellules Excel à partir de ses coordonnées.
Private Shared Function GetExcelRange(ByVal startRowIndex As Integer, ByVal startColumnIndex As Integer, ByVal endRowIndex As Integer, ByVal endColumnIndex As Integer) As String
Return GetExcelRange(startRowIndex, startColumnIndex) & ":" & GetExcelRange(endRowIndex, endColumnIndex)
End Function
' Permet de sauter au paragraphe suivant d'un document Word
Private Shared Sub SkipToNextParagraph(ByVal range As Word.Range)
range.InsertParagraphAfter() ' Ajouter un paragraphe à la suite de la plage en cours
range.Collapse(Word.WdCollapseDirection.wdCollapseEnd) ' Réduire la plage à sa fin
range.MoveEnd(Word.WdUnits.wdParagraph, 1) ' Sauter au paragraphe suivant
End Sub
' Permet de débarrasser une chaîne de caractères d'éventuels symboles indésirables.
' Ces symboles que j'appelle "bruits" entourrent parfois le texte extrait de Word
Private Shared Function TrimNoises(ByVal s As String) As String
Return s.Trim(ChrW(7), ChrW(13))
End Function
#End Region
End Class
Conclusion
Cette source a été écrite et testée sur une machine équipée de Office 2003. Je ne sais pas si elle se comporte autrement avec d'autres versions de la suite. Vous m'en direz plus. Par ailleurs, l'echange de données avec Word est assez lent. Bon mais ça dépend de votre équipement n'est-ce pas?
Historique
- 07 avril 2008 20:27:42 :
- Dans cette mise à jour, l'exportation vers excel est rendue plus rapide du fait de l'utilisation de la propriété Value2 de l'interface Range: elle permet de définir le contenu de toute une plage en une seule opération sous-forme de tableau.
Sources du même auteur
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Importer/exporter des données SQL server [ par macflyFR ]
bonjourj'ai un programme développé en vb qui utilise les données d'une base sql serverj'aimerais pouvoir importer et exporter certaines tables de ma b
importer, exporter des données entre Word et Access [ par Smileyg10 ]
Boujour à tous, je voudrais à partir d'une page Web affichant un document word contenant des champs Nom, Prénom etc... remplir une tab
migration de données bo vers excel [ par ini_enst ]
Bonjour à tous ,Je voudrais exporter les données d' une requete Business version 6.5 Object vers un fichier excel en automatique, dans le but de les e
Importer, exporter des données sql. [ par mryassine ]
Salut a vous tous on savait que dans entreprise manager (sql server) on peut exporter des tables ou importer des données sous forme des tables,ou sauv
exporter des données vers pdf, html et word [ par amalsohail ]
Bonjour,J'ai besoin d'un code vb6 pour exporter des données depuis SQL Server 2000 vers access, excel, word, Html et pdf. Si quelqu'un puisse me donne
Exporter les données d'une liste sous VBA vers Access [ par Benythefrog ]
Bonjour a tous et a toutes les DeveloppeursMerci d'avance pour votre aide qui j'en suis sure me sera trés précieuseVoila je recupere dans une liste un
exporter données dataset vers fichier texte (txt) [ par koutami ]
slt à tous, si quelqu'un peut m'aider à avoir le code source en vb5 d'un programme qui exporte les données du data set ou du data table vers un fichi
Importer des données sous forme de tableau d'une page web [ par Julian50 ]
Bonjour à tous, je cherche à importer un tableau d'une page web depuis son url et son numéro webtable et récupérer les données dans une table. Actuel
importer fichier excel [ par ziedchebbi ]
Bonjour, J'ai une application windows en vb.net sous de la BD sql server et je veux importer des données d'un fichier excel et l'afficher dans un data
migration d'une base de données de sql server 2000 à oracle 9i [ par disso ]
Bonjour à tous,j'ai un projet sur la migration d'une base de données initialement sous sql server 2000 vers une oracle.Pour l'instant je n'ai vraiment
|
Derniers Blogs
[WP7] DYNAMICALLY CHANGE STARTUP PAGE[WP7] DYNAMICALLY CHANGE STARTUP PAGE par KooKiz
Let's say that you want to allow the user to customize the startup page of your application. You can easily change the startup page by editing the 'NavigationPage' attribute in the manifest file. But the manifest cannot be modified once the applicatio...
Cliquez pour lire la suite de l'article par KooKiz SESSION SILVERLIGHT 5 3D : SLIDES ET DEMOSSESSION SILVERLIGHT 5 3D : SLIDES ET DEMOS par Groc
Durant les techdays, j'ai eu le plaisir d'animer une session sur Silverlight 5 et la 3D avec Simon Ferquel. Comme promis, voici nos slides et mes démos (celles avec le viper BSG) ici et là. Pour mémoire, les démos utilisent toutes le viper BSG...
Cliquez pour lire la suite de l'article par Groc [TECHDAYS 2012] SESSION WEBMATRIX 2 : LE COUTEAU SUISSE GRATUIT POUR VOS DéVELOPPEMENTS WEB - SLIDES[TECHDAYS 2012] SESSION WEBMATRIX 2 : LE COUTEAU SUISSE GRATUIT POUR VOS DéVELOPPEMENTS WEB - SLIDES par gpommier
Suite à la session que j'ai présenté sur WebMatrix 2, vous pouvez trouver les slides ici, ainsi que les démos en packages nuget : démos1 et démos2 J'en profite pour remercier chaleureusement tous ceux qui sont venus très nombreux à cette sess...
Cliquez pour lire la suite de l'article par gpommier [SHAREPOINT] LES SESSIONS TECHDAYS 2012.[SHAREPOINT] LES SESSIONS TECHDAYS 2012. par Patrick Guimonet
Voici donc pour ceux qui n'ont pas pu venir, ou ceux qui n'ont pas pu toutes les suivre la liste des sessions SharePoint aux TechDays 2012, que je mettrais à jour dès que les liens des vidéo seront disponibles. Ou ici : http...
Cliquez pour lire la suite de l'article par Patrick Guimonet TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3 par ROMELARD Fabrice
Speaker: Bernard Ourghanlian Cette session est comme chaque jour transmise en live par BrainSonic, et j'ai donc suivi cette troisième pleinière par ce moyen sur mon iPad . Elle est dédiée comme chaque année à la mise en perspective de l'é...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Forum
LISTER KEYS.KEYLISTER KEYS.KEY par Onin42
Cliquez pour lire la suite par Onin42
Logiciels
Tribler (2012)TRIBLER (2012)Tribler est un client pair à pair (P2P/Peer-to-Peer) open source avec la capacité de regarder des... Cliquez pour télécharger Tribler OneSwarm (2012)ONESWARM (2012)Le peer-to-peer qui protège votre vie privée, c'est OneSwarm.
Ce logiciel de peer-to-peer crypté... Cliquez pour télécharger OneSwarm PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V8.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V8.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning
|