Excel Import ohne Office (oder sonstige Programme)

  • VB.NET
  • .NET (FX) 3.0–3.5

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von DerSmurf.

    Excel Import ohne Office (oder sonstige Programme)

    Hallo. Ich weiß das Thema findet man im Netz und auch hier zuhauf. Aber ich bekomms trotzdem nicht hin.
    Ziel ist es, eine Exceldatei (xls und xlsx) in ein DGV zu importieren. Egal ob direkt hinein, oder über ein DataSet.
    Mehr soll mit der Excel Datei nicht passieren, nur Einesen ins DGV.
    Jedoch sollte das ganze möglich sein, ohne das Office, oder ein anders Hilfsprogramm auf dem ausführenden Computer installiert ist.
    Das ganze sollte funktionieren mithilfe des OleDbAdapters.
    Aber mein Makro bricht mit dem Fehler: System.InvalidOperationException: "Der 'Microsoft.ACE.OLEDB.12.0'-Provider ist nicht auf dem lokalen Computer registriert." ab.
    Das klingt für mich auch irgendwie so, als müsste ich noch irgendwas installieren (auch wenn hier auf dem PC aktuell Office installiert ist).

    Hier der Code:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim MyConnection As System.Data.OleDb.OleDbConnection
    3. Dim dataSet As System.Data.DataSet
    4. Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
    5. 'Open File Dialog zum öffnen der Exceldatei
    6. Dim Path As String
    7. Using OFD As New OpenFileDialog With {.Filter = "Excel Dateien|*.xls;*.xlsx", .Title = "Rechnung auswählen"}
    8. If OFD.ShowDialog <> 1 Then Exit Sub
    9. Path = OFD.FileName
    10. End Using
    11. MyConnection = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Path + ";Extended Properties=Excel 12.0;")
    12. MyCommand = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection)
    13. dataSet = New System.Data.DataSet
    14. MyCommand.Fill(dataSet)
    15. DataGridView1.DataSource = dataSet.Tables(0)
    16. MyConnection.Close()
    17. End Sub


    Außerdem habe ich mal schnell ein Demoprojekt gebastelt und hier im Dbug Ordner eine xls und eine xlsx reingeschmissen.
    Beide Exceltabellen sind von A1 bis F3 mit den jeweiligen Zellenbezeichnungen beschrieben. Also A1, B1, A2, B2 usw.

    Edit:
    und eine Frage habe ich zu folgender Codezeile:

    VB.NET-Quellcode

    1. ​ MyConnection = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Path + ";Extended Properties=Excel 12.0;")

    gehören hier nicht eigentlich die "+" durch ein "&" ersetzt?
    Dateien
    • ExcelTest.zip

      (47,91 kB, 206 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DerSmurf“ ()

    Einfacher und unabhängig von Office ist es, wenn du über nuget EpPlus lädst.

    DerSmurf schrieb:

    gehören hier nicht eigentlich die "+" durch ein "&" ersetzt?
    Streng genommen ja, aber die String-Klasse kennt auch den + Operator als Verkettung.
    Noch einfacher geht es ab VS2015 mittels interpoliertem String:

    VB.NET-Quellcode

    1. MyConnection = New System.Data.OleDb.OleDbConnection($"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={Path};Extended Properties=Excel 12.0;")
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    DerSmurf schrieb:

    System.InvalidOperationException: "Der 'Microsoft.ACE.OLEDB.12.0'-Provider ist nicht auf dem lokalen Computer registriert."
    Jo, das ist ein alter Bekannter.
    Wenn der auftritt probierma

    VB.NET-Quellcode

    1. MyConnection = New System.Data.OleDb.OleDbConnection($"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={Path};Extended Properties=Excel 12.0;")
    Oder du liest den OLEDB-Provider dynamisch ein.

    VB.NET-Quellcode

    1. Public Function GetOleDbProvider() As String
    2. Dim reader As OleDb.OleDbDataReader = OleDb.OleDbEnumerator.GetRootEnumerator()
    3. While reader.Read
    4. For i As Integer = 0 To reader.FieldCount - 1
    5. If reader.GetName(i) = "SOURCES_NAME" AndAlso reader.GetValue(i).ToString.Contains(".OLEDB.") Then
    6. Return reader.GetValue(i).ToString
    7. End If
    8. Next
    9. End While
    10. reader.Close()
    11. Return String.Empty
    12. End Function
    huhu.
    Danke für eure Hilfe!
    Sowohl die Methode von @petaod, als auch vom @ErfinderDesRades, funktionieren nicht.
    Es kommt zum gleichen Fehler, wie in meinem Versuch - außer dass eben der ACE.OLEDB 4.0 Provider nicht gefunden wurde.

    Die Lösung von @HenryV sieht doch cool aus. Denn die ganze Geschichte scheint ja echt nicht so ganz fehlerfrei zu laufen.
    Da Frage ich mich schon, ob ich nicht tatsächlich Epplus nutzen sollte, um zu gewährleisten, dass die Sub auf verschiedenen PCs auch sauber läuft.

    Unabhängig davon habe ich ein Problem HenryV's Lösung einzubauen. (Ich weiß nicht ganz genau was hier passiert)
    Da mir die Funktion ja den Provider zurückgibt, müsste ich ja den "Return" String irgendwo an diese Stelle packen:
    ​MyConnection = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Path + ";Extended Properties=Excel 12.0;")
    Damit erstmal gucken zu können, was mit die Funktion überhaupt zurückgibt, habe ich folgende Sub ausgeführt:

    VB.NET-Quellcode

    1. Private Sub neu()
    2. Dim provider = GetOleDbProvider()
    3. MessageBox.Show(provider)
    4. End Sub

    Der Rückgabewert ist allerdings Nothing.
    Hmm. Da jetzt nichts mehr kommt, gehe ich davon aus, dass ein Import von Excel Dateien ohne installiertes Office nicht möglich ist, ohne Hilfsprogramme?
    Also verwende ich jetzt (widerwillig, weil 14MB groß - doppelt so viel wie mein Programm) Epplus?
    Ja und ich sehe gerade das Ding ist nur 14MB groß, weil ich über NuGet irgendwie jede Menge anderes Zeug runtergeladen habe.
    Die benötigte dll ist keine 1,5 MB groß - damit werd ich wohl leben können.

    Hat jemand zufällig schonmal damit gearbeitet oder eine VB.NET Tutorial am start?
    Alles was ich an Anleitung finde ist in C# - damit tue ich mich sehr schwer.

    DerSmurf schrieb:

    Alles was ich an Anleitung finde ist in C# - damit tue ich mich sehr schwer.
    Die beiden Sprachen sind weitgehend (abgesehen von der Syntax) identisch einsetzbar.
    Es gibt massenweise Code-Konverter.


    Aber es gibt auch VB-Tutorials
    codeproject.com/Tips/1165476/How-to-Use-EPPlus-in-VB
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Ich habe von zwei Seiten versucht den C# Code in Vb.et zu übersetzen. Leider beide mal ohne Erfolg (verschiedene Converter übersetzen nicht, sondern melden mir nur einen "Error").
    Und ich finde in der Tat kein einziges Vb Tutorial zum IMPORT.
    Auch dein Link ist ein Exporttutorial:
    ​So, here we are going to convert the grid available to Excel sheet. So, you can save it for future reference or you can a print out of it. EPPlus is a DLL (dynamic link library) which helps in creating an Excel worksheet.
    Spoiler anzeigen

    C#-Quellcode

    1. //create a list to hold all the values
    2. List<string> excelData = new List<string>();
    3. //read the Excel file as byte array
    4. byte[] bin = File.ReadAllBytes("C:\\ExcelDemo.xlsx");
    5. //or if you use asp.net, get the relative path
    6. byte[] bin = File.ReadAllBytes(Server.MapPath("ExcelDemo.xlsx"));
    7. //create a new Excel package in a memorystream
    8. using (MemoryStream stream = new MemoryStream(bin))
    9. using (ExcelPackage excelPackage = new ExcelPackage(stream))
    10. {
    11. //loop all worksheets
    12. foreach (ExcelWorksheet worksheet in excelPackage.Workbook.Worksheets)
    13. {
    14. //loop all rows
    15. for (int i = worksheet.Dimension.Start.Row; i <= worksheet.Dimension.End.Row; i++)
    16. {
    17. //loop all columns in a row
    18. for (int j = worksheet.Dimension.Start.Column; j <= worksheet.Dimension.End.Column; j++)
    19. {
    20. //add the cell data to the List
    21. if (worksheet.Cells[i, j].Value != null)
    22. {
    23. excelData.Add(worksheet.Cells[i, j].Value.ToString());
    24. }
    25. }
    26. }
    27. }
    28. }

    von riptutorial.com/de/epplus/exam…s-excel-datei-importieren

    Edit:
    Ich hab jetzt das Einlesen Zeilenweise übersetzt. Der Rest war dann selbsterklärend.
    Mein Code scheint zu funktionieren, und ich glaube er ist garnicht so doof.

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. 'Importdatei auswählen
    3. Dim filepath As String
    4. Using OFD As New OpenFileDialog With {.Filter = "Excel Dateien|*.xls;*.xlsx", .Title = "Datei auswählen"}
    5. If OFD.ShowDialog <> 1 Then Exit Sub
    6. filepath = OFD.FileName
    7. End Using
    8. Dim existingFile As FileInfo = New FileInfo(filepath)
    9. Using package As ExcelPackage = New ExcelPackage(existingFile)
    10. Dim worksheet As ExcelWorksheet = package.Workbook.Worksheets(1)
    11. 'benötigte Spalten im DGV erstellen
    12. Dim ColAmount = worksheet.Dimension.[End].Column
    13. For i = 0 To ColAmount - 1
    14. DataGridView1.Columns.Add("name", "Spalte " & i + 1)
    15. Next
    16. 'Zellenweise einlesen der Daten aus Excel
    17. For i = 1 To worksheet.Dimension.[End].Row '1. Schleife durch Rows
    18. DataGridView1.Rows.Add()
    19. For j = 1 To ColAmount '2. Schleife durch Spalten
    20. If worksheet.Cells(i, j).Value IsNot Nothing Then
    21. DataGridView1.Rows(i - 1).Cells(j - 1).Value = worksheet.Cells(i, j).Value
    22. End If
    23. Next
    24. Next
    25. End Using
    26. End Sub

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „DerSmurf“ ()