2008-11-20 6 views

Antwort

2

Ich glaube nicht, Silverlight eine Möglichkeit, Dateien zum Download anbietet. Sie können Ihrer App eine Schaltfläche hinzufügen, die eine URL aufruft - d. H. http://www.mysite.com/generateexcelfile.aspx. Fügen Sie als Querystring-Werte die Parameter ein, die zum Generieren der in der Silverlight-App angezeigten Daten verwendet werden, führen Sie Ihre Abfrage aus, und verwenden Sie Ihre bevorzugte Excel-Dateigenerierungskomponente, um die Datei im laufenden Betrieb zu generieren. Redirect to it und es wird auf das System des Benutzers herunterladen.

+3

Seien Sie vorsichtig mit "die Datei erstellen und dann umleiten" - Sie müssen diese Dateien irgendwann löschen. Besser wäre es, das Excel einfach in den Ausgabestream der ASPX-Seite mit dem richtigen MIME-Typ zu speichern, so dass der Browser sehen kann, dass es sich um eine Excel-Datei und nicht um eine HTML-Seite handelt . – user8032

4

Ich habe this mit der Zwischenablage gefunden.

Um den Code Generika machen Sie das erste Beispiel ändern können die Spaltenbindungen und wenden sie auf die Daten mithilfe von Reflektion zu lesen:

public String ExportDataGrid(DataGrid grid) 
{ 
    string colPath; 
    System.Reflection.PropertyInfo propInfo; 
    System.Windows.Data.Binding binding; 
    System.Text.StringBuilder strBuilder = new System.Text.StringBuilder(); 
    System.Collections.IList source = (grid.DataContext as System.Collections.IList); 
    if (source == null) 
     return ""; 

    foreach (Object data in source) 
    { 
     foreach (DataGridColumn col in datagrid.Columns) 
     { 
      if (col is DataGridBoundColumn) 
      { 
       binding = (col as DataGridBoundColumn).Binding; 
       colPath = binding.Path.Path; 
       propInfo = data.GetType().GetProperty(colPath); 
       if (propInfo != null) 
       { 
        strBuilder.Append(propInfo.GetValue(data, null).ToString()); 
        strBuilder.Append(","); 
       }       
      } 

     } 
     strBuilder.Append("\r\n"); 
    } 


    return strBuilder.ToString(); 
} 

natürlich funktioniert es nur, wenn der Pfad der Bindung der ist Name des Anwesens. Bei fortgeschrittenen Pfaden müssen Sie die Bindung auf die Daten anwenden (ich denke, das wäre eine bessere Lösung, aber ich bin mir nicht sicher, wie ich das machen soll).

1

Aus der Spitze von meinem Kopf würde ich sagen, dass Sie auf die Schaltfläche Export mit einem ControlTemplate hinzufügen und dann über jedes Element durchlaufen in den DataSource und dann jede Spalte in Columns verwenden Sie den Inhalt jeder Zelle der GetCellContent Methode zu erhalten oder verwenden Sie die Bindungsinformationen der DataGridColumn, um den entsprechenden Zellenwert abzurufen. Sie können dann den angezeigten Wert dieses Inhalts abrufen und diesen in Ihren Bericht schreiben. wie

Etwas ...

foreach (YourType item in grid.DataSource) 
{ 
    foreach (DataGridColumn column in grid.Columns) 
    { 
     FrameworkElement cellContent = column.GetCellContent(item); 

     // Now, determine the type of cell content and act accordingly. 
     TextBlock block = cellContent as TextBlock; 
     if (block != null) 
     { 
     // Report text value... 
     } 

     // ...etc... 

    } 
} 

Oder über die Bindungsinformation, wie durch DaniCE beschrieben.

21

Silverlight 3 ändert die Antwort auf diese Frage, weil es dem Benutzer die Möglichkeit gibt, eine Datei auf dem Desktop des Benutzers an einem von ihnen angegebenen Speicherort zu erstellen. Ich habe den von DaniCE eingereichten Code angepasst, die Dinge in ein paar Methoden zur besseren Lesbarkeit aufgeteilt und verwende ein locker definiertes CSV-Format, das Excel erkennen sollte.

private void exportHistoryButton_Click(object sender, RoutedEventArgs e) 
{ 
    string data = ExportDataGrid(true, historyDataGrid); 
    SaveFileDialog sfd = new SaveFileDialog() 
    { 
    DefaultExt = "csv", 
    Filter = "CSV Files (*.csv)|*.csv|All files (*.*)|*.*", 
    FilterIndex = 1 
    }; 
    if (sfd.ShowDialog() == true) 
    { 
    using (Stream stream = sfd.OpenFile()) 
    { 
     using (StreamWriter writer = new StreamWriter(stream)) { 
     writer.Write(data); 
     writer.Close(); 
     } 
     stream.Close(); 
    } 
    } 
} 

private string FormatCSVField(string data) { 
    return String.Format("\"{0}\"", 
     data.Replace("\"", "\"\"\"") 
     .Replace("\n", "") 
     .Replace("\r", "") 
     ); 
} 

public string ExportDataGrid(bool withHeaders, DataGrid grid) 
{ 
    string colPath; 
    System.Reflection.PropertyInfo propInfo; 
    System.Windows.Data.Binding binding; 
    System.Text.StringBuilder strBuilder = new System.Text.StringBuilder(); 
    System.Collections.IList source = (grid.ItemsSource as System.Collections.IList); 
    if (source == null) 
    return ""; 

    List<string> headers = new List<string>(); 
    grid.Columns.ToList().ForEach(col => { 
    if (col is DataGridBoundColumn){ 
     headers.Add(FormatCSVField(col.Header.ToString())); 
    } 
    }); 
    strBuilder 
    .Append(String.Join(",", headers.ToArray())) 
    .Append("\r\n"); 

    foreach (Object data in source) 
    { 
    List<string> csvRow = new List<string>(); 
    foreach (DataGridColumn col in grid.Columns) 
    { 
     if (col is DataGridBoundColumn) 
     { 
     binding = (col as DataGridBoundColumn).Binding; 
     colPath = binding.Path.Path; 
     propInfo = data.GetType().GetProperty(colPath); 
     if (propInfo != null) 
     { 
      csvRow.Add(FormatCSVField(propInfo.GetValue(data, null).ToString())); 
     } 
     } 
    } 
    strBuilder 
     .Append(String.Join(",", csvRow.ToArray())) 
     .Append("\r\n"); 
    } 


    return strBuilder.ToString(); 
} 
+1

Funktioniert das ?! – Goober

+1

Es tut mit etwas Fingerfertigkeit; Es erstellt eine CSV-Datei, nicht XLS. Wenn eine Person Excel installiert hat, wird sie geöffnet, da die Erweiterung Excel zugeordnet ist. – t3rse

+1

Wenn Sie einen Fehler in der Bindungslinie erhalten, versuchen Sie Folgendes: binding = (System.Windows.Data.Binding) ((Microsoft.Windows.Controls.DataGridBoundColumn) col) .Binding; – proudgeekdad

1

Überprüfen Ryans Lösung aus. Sieht gut aus, kann aber nicht dafür bürgen, weil ich es gerade gefunden habe. Ryan macht die oben angeforderte DLL.

http://www.rshelby.com/post/exporting-data-from-silverilght-datagrid-to-excel.aspx

David in Dakota-Lösung sieht oben ein wenig leichter zu implementieren, und es gibt immer die Umleitung zu einer klassischen asp.net Seite mit einem Datenraster auf ihn und den Typ Inhalt auf treffen, aber dann Sie haben mehr Code zur Unterstützung und dieser Weg funktioniert möglicherweise nicht für Offline-Browser-Lösungen, die nicht funktionieren.

Wie auch immer, das ist eine häufige Aufgabe.Ich hoffe, einige Leute hier oder auf Microsoft mit einem Mort Plug kommen und spielen Lösung :)

I datagrid-

http://www.codeproject.com/KB/silverlight/SilverlightDataGridExport.aspx

das Potenzial, eine Erweiterungsmethode für CVS Export von einem Silverlight gefunden hat Plug-and-Play sein, aber ich musste es nur ein bisschen zwicken, um es mit Datagrids mit Datenquellen zu arbeiten (siehe Kommentare im Beitrag). Jemand, der heller und erfahrener ist als ich, sollte in der Lage sein, perfekt zu optimieren. Schau es dir an, es sollte dir nahe bringen, was du brauchst.

2

für mich gearbeitet ich weiß, dass dies eine alte Post, aber es tat mir helfen. Ich habe einige Änderungen vorgenommen, damit es mit silverlight 4 funktioniert, konvertiert und übertrifft. Ich wollte den schnellen Export, also benutze ich zuerst CSV und öffne es dann mit Excel. Dieser Code funktioniert silverlight web und oob erhöht das Vertrauen. Im Web wird nicht in Excel geöffnet.

+0

Danke sieht gut aus, es zu versuchen. Bitte entfernen Sie Ihre hinzufügen, siehe hier http://StackOverflow.com/faq#signatures –

+0

Nur eine Anmerkung, um zu sagen, dass die Steuerung von Excel über Interop auf diese Weise erfordert, dass der Benutzer out-of-Browser (OOB) ausgeführt wird. Sie müssen Ihre App auch so erstellen, dass sie erhöhte Berechtigungen anfordert (über die Eigenschaftenseiten des Projekts). –

1

Diese Lösungen funktionierten nicht für mich, also modifizierte ich sie zu einer, die funktionierte (Meine Lösung erfordert keine Anführungszeichen um Felder, so verließ ich die FormatCSVField Funktion aus)

public void SaveAs(string csvPath) 
    { 
     string data = ExportDataGrid(true, _flexGrid); 
     StreamWriter sw = new StreamWriter(csvPath, false, Encoding.UTF8); 
     sw.Write(data); 
     sw.Close(); 
    } 

    public string ExportDataGrid(bool withHeaders, Microsoft.Windows.Controls.DataGrid grid) 
    { 
     System.Text.StringBuilder strBuilder = new System.Text.StringBuilder(); 
     System.Collections.IEnumerable source = (grid.ItemsSource as System.Collections.IEnumerable); 

     if (source == null) return ""; 

     List<string> headers = new List<string>(); 

     grid.Columns.ToList().ForEach(col => 
     { 
      if (col is Microsoft.Windows.Controls.DataGridBoundColumn) 
      { 
       headers.Add(col.Header.ToString()); 
      } 
     }); 

     strBuilder.Append(String.Join(",", headers.ToArray())).Append("\r\n"); 
     foreach (Object data in source) 
     { 
      System.Data.DataRowView d = (System.Data.DataRowView)data; 
      strBuilder.Append(String.Join(",", d.Row.ItemArray)).Append("\r\n"); 
     } 

     return strBuilder.ToString(); 
    } 
0

ich brauchte, das Gleiche zu tun. Ich habe die Implementierung von t3rse benutzt, musste aber einige Änderungen vornehmen. Ich habe nicht genug Ruf einen Kommentar zu seiner Antwort zu tun, so will ich sie hier aufzulisten:

  • Für die Linie, die sagt propInfo.GetValue (Daten, null) .ToString(), I geprüft Prüfen Sie, ob der von GetValue zurückgegebene Wert Null ist, bevor Sie ToString() aufrufen.

  • In der Methode FormatCSVField() wurde ein doppeltes Anführungszeichen durch drei doppelte Anführungszeichen ersetzt. Es sollte nur durch zwei doppelte Anführungszeichen ersetzt werden.

  • Die Implementierung verwendet nur Spalten vom Typ DataGridBoundColumn und ignoriert andere. Ich habe Spalten, die nicht DataGridBoundColumn sind, die ich enthalten wollte, also habe ich den Eigenschaftsnamen der Datenquelle für diese Spalten mit col.SortMemberPath.