Hallo zusammen,
ich versuche mich gerade an Rainbirds Excel export via oleDB.
Mein Problem ist, das mir das Snippet NUR die Spaltenüberschriften anzeigt, aber keinen Dateninhalt .... Hier mal kurz das Script, vllt. kann mir ja jemand sagen was ich hier falsch gemacht habe.:
'Ich vermute ja den Fehler evtl. beim deklarieren der Datatable. Habe aber keine Ahnung.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Runtime.Remoting;
using System.Reflection;
using System.Runtime.InteropServices;
namespace Excel
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void bestellungenBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.bestellungenBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.fDTEL_DE_SQL_2008DataSet);
}
private void Form1_Load(object sender, EventArgs e)
{
// TODO: Diese Codezeile lädt Daten in die Tabelle "fDTEL_DE_SQL_2008DataSet.Bestellungen". Sie können sie bei Bedarf verschieben oder entfernen.
this.bestellungenTableAdapter.Fill(this.fDTEL_DE_SQL_2008DataSet.Bestellungen);
}
FDTEL_DE_SQL_2008DataSet.BestellungenDataTable bestell = new FDTEL_DE_SQL_2008DataSet.BestellungenDataTable();
public class ExcelExport
{
/// <summary>
/// Privater Standardkonstruktor.
/// </summary>
private ExcelExport() { }
/// <summary>
/// Schreibt das Schema einer bestimmten Tabelle in eine neue Excel-Datei.
/// </summary>
/// <param name="table">Tabelle</param>
/// <param name="fileName">Dateiname</param>
public static void WriteTableSchemaToExcelFile(DataTable table, string fileName)
{
// Excel im Hintergrund öffnen
object excel = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
// Auflistung der Mappeen abrufen
object books = excel.GetType().InvokeMember("Workbooks", BindingFlags.IgnoreCase | BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, excel, new object[0]);
// Neue Mappe erstellen
object book = books.GetType().InvokeMember("Add", BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, books, new object[0]);
// Auflistung der Tabellenblätter abrufen
object sheets = book.GetType().InvokeMember("Sheets", BindingFlags.IgnoreCase | BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, book, new object[0]);
// Neues Tabellenblatt erstellen
object sheet = sheets.GetType().InvokeMember("Add", BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, sheets, new object[0]);
// Name des Tabellenblatts festlegen
sheet.GetType().InvokeMember("Name", BindingFlags.SetProperty, null, sheet, new object[1] { table.TableName });
// Zähler
int i = 0;
// Spalten der Tabelle durchlaufen
foreach (DataColumn column in table.Columns)
{
// Zähler erhöhen
i++;
// Feldnamen einfügen
object range = sheet.GetType().InvokeMember("Cells", BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, sheet, new object[2] { 1, i });
range.GetType().InvokeMember("Value", BindingFlags.SetProperty | BindingFlags.OptionalParamBinding, null, range, new object[1] { column.ColumnName });
}
// Dokument speichern
book.GetType().InvokeMember("SaveAs", BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, book, new object[1] { fileName });
// COM-Verweise freigeben
Marshal.ReleaseComObject(sheet);
Marshal.ReleaseComObject(sheets);
Marshal.ReleaseComObject(book);
Marshal.ReleaseComObject(books);
// Excel schließen
excel.GetType().InvokeMember("Quit", BindingFlags.InvokeMethod, null, excel, new object[0]);
// Excel.Application COM-Verweis freigeben
Marshal.ReleaseComObject(excel);
}
/// <summary>
/// Erzeugt eine OLEDB-Verbindungszeichenfolge für ein bestimmtes Excel-Dokument.
/// </summary>
/// <param name="fileName">Dateiname (.XLS)</param>
/// <returns>Verbindungszeichenfolge</returns>
private static string BuidExcelConnectionString(string fileName)
{
// Verbindungszeichenfolge erzeugen un zurückgeben
return "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";Extended Properties=Excel 8.0";
}
/// <summary>
/// Erzeugt aus einer Tabelle ein Excel-Dokument.
/// </summary>
/// <param name="table">Tabelle</param>
/// <param name="fileName">Dateiname des Ziel-Excel-Dokuments</param>
public static void FillExcelSheet(DataTable table, string fileName)
{
// Neue leere Excel-Datei aus dem Tabellenschema erzeugen
WriteTableSchemaToExcelFile(table, fileName);
// Verbindungszeichenfolge erzeugen
string connectionString = BuidExcelConnectionString(fileName);
// Neue OLEDB-Verbindung erzeugen
OleDbConnection connection = new OleDbConnection(connectionString);
connection.Open();
// String-Generator für Parameter erzeugen
StringBuilder parameterBuilder = new StringBuilder(") VALUES (");
// Spalten zählen
int columnCount = table.Columns.Count;
// INSERT SQL-Anweisung für Excel erzeugen
StringBuilder builder = new StringBuilder("INSERT INTO [");
builder.Append(table.TableName);
builder.Append("$] (");
// Alle Spalten durchlaufen
for (int i = 0; i < columnCount; i++)
{
// Spaltennamen anfügen
builder.Append(table.Columns[i].ColumnName);
// Parameter anfügen
parameterBuilder.Append("?");
// Wenn eine weitere Spalte folgt ...
if (i < (columnCount - 1))
{
// Kommas anfügen
builder.Append(",");
parameterBuilder.Append(",");
}
}
// SQL-Anweisung fertigstellen
builder.Append(parameterBuilder.ToString());
builder.Append(")");
string insertStatement = builder.ToString();
// Preisliste durchlaufen
foreach (DataRow row in table.Rows)
{
// Neuen OLEDB-Befehl erzeugen
OleDbCommand command = new OleDbCommand(insertStatement, connection);
// Alle Spalten durchlaufen
foreach (DataColumn column in table.Columns)
{
// Parameter übergeben
command.Parameters.Add(new OleDbParameter(column.ColumnName, row[column]));
}
// Befehl ausführen
command.ExecuteNonQuery();
}
// Verbindung schließen
connection.Close();
}
}
private void button1_Click(object sender, EventArgs e)
{
ExcelExport.WriteTableSchemaToExcelFile(bestell, "C:\\TEST2.XLS");
ExcelExport.FillExcelSheet(bestell, "C:\\TEST2.XLS");
}
}
}
Viele Grüße
Ronny
Hallo romu2000,
WriteTableSchemaToExcelFile wird bereits implizit durch FillExcelSheet aufgerufen. Deshalb verschluckt er sich wahrscheinlich daran. Probleme kann es auch geben, wenn Spaltennamen der DataTable Leer- oder Sonderzeichen enthalten.
private void button1_Click(object sender, EventArgs e)
{
// Falsch (wird implizit aufgerufen): ExcelExport.WriteTableSchemaToExcelFile(bestell, "C:\\TEST2.XLS");
// Excel-Export ausführen
ExcelExport.FillExcelSheet(bestell, "C:\\TEST2.XLS");
}
OLEDB ist manchmal etwas empfindlich. Wesentlich robuster ist folgende Lösung: Excel-Export ohne Excel (Snippet)
Läuft allerdings erst ab Excel 2003 oder höher und erzeugt XML-Dateien statt XLS-Dateien.
Hallo,
habe gerade versucht deine Klasse bei mir einzubauen.
Bekomme in Methode "FillExcelSheet" immer einen Fehler und zwar wenn er die Excel-Tabelle füllen will.
// durchlaufen
foreach (DataRow row in table.Rows)
{
// Neuen OLEDB-Befehl erzeugen
OleDbCommand command = new OleDbCommand(insertStatement, connection);
// Alle Spalten durchlaufen
foreach(DataColumn column in table.Columns)
{
// Parameter übergeben
command.Parameters.Add(new OleDbParameter(column.ColumnName,row[column]));
}
// Befehl ausführen
command.ExecuteNonQuery();
}
Er läuft hier nur einmal durch die obere Schleife und dann bricht er ab.
Die Spaltennamen werden im ersten Schleifendurchlauf in Excel gesetzt und dann kommt der Abbruch mit "Ungültiger Tabellennamen".
Das DataTable habe ich mit einem SQL-String gefüllt.
Benutze VS 2003.
Habe mir den Code nochmals angeschaut und durch den Kopf gehen lassen.
Ist natürlich alles mist was ich in meinem Beitrag geschrieben habe.
Eine frage habe trotzdem.
// INSERT SQL-Anweisung für Excel erzeugen
StringBuilder builder = new StringBuilder("INSERT INTO [");
builder.Append(table.TableName);
wohin schreibt er den Insert?
Das DataTable habe ich mit einem SQL-String gefüllt welches mehrere Tabellen beinhaltet.
Hallo,
das Thema ist zwar schon etwas älter aber ich habe eine kleine Frage.
Ich benutze Excel 2010 und bekomme einen Fehler nach der Schleife die mir den Sql Insert Befehl zusammensetzt.
Meldung bei ExecuteNonQuery();
"Das Microsoft Jet-Datenbankmodul konnte das Objekt '$' nicht finden. Stellen Sie sicher, dass das Objekt existiert und dass die Namens- und Pfadangaben richtig eingegeben wurden."
ich habe auch schon "$Tabelle4" oder "Tabelle4" als Table.TableName vergeben. dann steht an der stelle wo das Dollar steht halt der andere String.
Die Überschriften werden normal erzeugt und die Datei wird auch gespeichert.
Ich denke mal das die Parameter in der Foreach Schleife nicht gefüllt werden.