2008-11-20 40 views

Trả lời

2

Tôi không nghĩ Silverlight cung cấp cách tải xuống tệp. Bạn có thể thêm nút vào ứng dụng gọi URL theo số http://www.mysite.com/generateexcelfile.aspx. Bao gồm giá trị chuỗi truy vấn các thông số được sử dụng để tạo dữ liệu được hiển thị trong ứng dụng Silverlight của bạn, chạy truy vấn của bạn và sử dụng thành phần tạo tệp Excel yêu thích của bạn để tạo tệp ngay lập tức. Chuyển hướng đến nó và nó sẽ tải xuống hệ thống của người dùng.

+3

Hãy cẩn thận với "tạo tệp và sau đó chuyển hướng đến tệp" - bạn phải xóa các tệp này tại một số thời điểm. Điều tốt hơn cần làm là chỉ lưu Excel vào luồng đầu ra của trang .aspx với loại mime chính xác, để trình duyệt có thể thấy rằng đó là tệp Excel, không phải trang html và cung cấp cho người dùng tùy chọn để lưu nó . – user8032

4

Tôi đã tìm thấy this bằng cách sử dụng khay nhớ tạm.

Để thực hiện các mã chung bạn có thể sửa đổi các ví dụ đầu tiên để đọc các cam kết ràng buộc cột và áp dụng chúng vào các dữ liệu sử dụng phản ánh:

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(); 
} 

tất nhiên, nó chỉ hoạt động khi con đường của các ràng buộc là tên tài sản. Đối với các đường dẫn nâng cao hơn, bạn phải áp dụng ràng buộc cho dữ liệu (tôi cho rằng đó sẽ là một giải pháp tốt hơn, nhưng tôi không chắc chắn bây giờ làm thế nào để làm điều này).

1

Off đỉnh đầu của tôi tôi sẽ nói bạn có thể thêm các nút xuất khẩu sử dụng một ControlTemplate và sau đó lặp lại trên mỗi mục trong DataSource, và sau đó sử dụng mỗi cột trong Columns để có được nội dung của mỗi tế bào bằng cách sử dụng phương pháp GetCellContent hoặc sử dụng thông tin ràng buộc của DataGridColumn để nhận giá trị ô thích hợp. Sau đó, bạn có thể nhận được giá trị được hiển thị của nội dung này và viết nội dung đó vào báo cáo của mình.

Cái gì đó như ...

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... 

    } 
} 

Hoặc sử dụng các thông tin ràng buộc như mô tả của DaniCE.

21

Silverlight 3 thay đổi câu trả lời cho câu hỏi này vì nó cho phép người dùng tạo tệp trên màn hình của người dùng ở vị trí mà họ chỉ định. Tôi đã điều chỉnh mã được DaniCE gửi, phân chia mọi thứ thành một vài phương pháp để dễ đọc và đang sử dụng định dạng CSV được định nghĩa lỏng lẻo mà Excel sẽ nhận ra.

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

Tính năng này có hoạt động không ?! – Goober

+1

Nó thực hiện với một số trò ảo thuật của bàn tay; nó tạo một tệp CSV chứ không phải XLS. Nếu một người đã cài đặt Excel, nó sẽ mở nó nhờ vào phần mở rộng đang được ánh xạ tới Excel. – t3rse

+1

Nếu bạn gặp lỗi trên đường liên kết, hãy thử truyền như sau: binding = (System.Windows.Data.Binding) ((Microsoft.Windows.Controls.DataGridBoundColumn) col) .Binding; – proudgeekdad

1

Kiểm tra giải pháp của Ryan. Có vẻ tốt, không thể xác minh cho nó mặc dù bởi vì tôi chỉ tìm thấy nó. Ryan thực hiện những gì DLL ở trên được yêu cầu.

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

David trong dung dịch Dakota trên trông một chút dễ dàng hơn để thực hiện, và luôn luôn có sự chuyển hướng đến một trang asp.net cổ điển với một mạng lưới dữ liệu vào nó và kiểu nội dung thiết lập để nổi trội, nhưng sau đó bạn có thêm mã để hỗ trợ và cách đó có thể không hoạt động đối với các giải pháp trình duyệt ngoại tuyến (thực sự sẽ không hoạt động).

Dù sao, đây là một nhiệm vụ phổ biến.Tôi hy vọng một số người đây hoặc tại Microsoft đưa ra một Mort plug and play giải pháp :)

Tôi tìm thấy một phương pháp mở rộng xuất khẩu CVS từ một Silverlight datagrid-

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

Nó có tiềm năng được cắm và chạy, nhưng tôi đã phải tweek nó chỉ là một chút để có được nó để làm việc với datagrids với mục datasources (xem ý kiến ​​trong bài viết). Một người nào đó sáng hơn và nhiều kinh nghiệm hơn bản thân tôi sẽ có thể tinh chỉnh để hoàn thiện. Kiểm tra nó ra, nó sẽ giúp bạn gần gũi với những gì bạn cần.

2

Tôi biết đây là một bài cũ nhưng nó đã giúp tôi. Tôi đã thực hiện một số chỉnh sửa để làm cho nó hoạt động với Silverlight 4, chuyển đổi và vượt trội. Tôi muốn xuất nhanh vì vậy lần đầu tiên tôi sử dụng CSV rồi mở nó bằng excel. Mã này hoạt động trên nền web bạc và nâng cao lòng tin. Trong Web sẽ không mở trong excel.

 private static void OpenExcelFile(string Path) 
    { 
     dynamic excelApp; 
     excelApp = AutomationFactory.CreateObject("Excel.Application"); 
     dynamic workbook = excelApp.workbooks; 
     object oMissing = Missing.Value; 

     workbook = excelApp.Workbooks.Open(Path, 

      oMissing, oMissing, oMissing, oMissing, oMissing, 

      oMissing, oMissing, oMissing, oMissing, oMissing, 

      oMissing, oMissing, oMissing, oMissing); 



     dynamic sheet = excelApp.ActiveSheet; 


     // open the existing sheet 


     sheet.Cells.EntireColumn.AutoFit(); 
     excelApp.Visible = true; 
    } 
    private static string FormatCSVField(string data) 
    { 
     return String.Format("\"{0}\"", 
      data.Replace("\"", "\"\"\"") 
      .Replace("\n", "") 
      .Replace("\r", "") 
      ); 
    } 
    public static string ExportDataGrid(DataGrid grid,string SaveFileName,bool AutoOpen) 
    { 
     string colPath; 
     System.Reflection.PropertyInfo propInfo; 
     System.Windows.Data.Binding binding; 
     System.Text.StringBuilder strBuilder = new System.Text.StringBuilder(); 
     var source = grid.ItemsSource; 

     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 (var 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) 
         { 
          string valueConverted = ""; 
          if (binding.Converter.GetType().ToString() != "System.Windows.Controls.DataGridValueConverter") 
           valueConverted = binding.Converter.Convert(propInfo.GetValue(data, null), typeof(System.String), binding.ConverterParameter, System.Globalization.CultureInfo.CurrentCulture).ToString(); 
          else 
           valueConverted = FormatCSVField(propInfo.GetValue(data, null) == null ? "" : propInfo.GetValue(data, null).ToString()); 

          csvRow.Add(valueConverted.ToString()); 
         } 
        } 
       } 
       strBuilder 
        .Append(String.Join(",", csvRow.ToArray())) 
        .Append("\r\n"); 
      } 

     if (AutomationFactory.IsAvailable) 
     { 
      var sampleFile = "\\" + SaveFileName; 
      var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 
      path += "\\Pement"; 


      if (!System.IO.Directory.Exists(path)) 
      { 
       System.IO.Directory.CreateDirectory(path); 
      } 
      else 
      { 
       var files = System.IO.Directory.EnumerateFiles(path); 
       foreach (var item in files) 
       { 
        try 
        { 
         System.IO.File.Delete(item); 
        } 
        catch { } 
       } 
      } 

      StreamWriter sw = File.CreateText(path + sampleFile); 
      sw.WriteLine(strBuilder.ToString()); 
      sw.Close(); 

      if (AutoOpen) 
       OpenExcelFile(path + sampleFile, true, true); 
     } 
     else 
     { 
      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(strBuilder.ToString()); 
         writer.Close(); 
        } 
        stream.Close(); 
       } 
      } 
     } 
     return strBuilder.ToString(); 
    } 
+0

Cảm ơn bạn đã sẵn sàng để thử. Vui lòng xóa phần bổ sung của bạn, xem tại đây http://stackoverflow.com/faq#signatures –

+0

Chỉ cần lưu ý rằng việc kiểm soát Excel qua interop theo cách này yêu cầu người dùng phải chạy ngoài trình duyệt (OOB). Bạn cũng phải xây dựng ứng dụng của mình sao cho nó yêu cầu quyền cao (thông qua các trang thuộc tính của dự án). –

1

Các giải pháp này không có tác dụng đối với tôi, vì vậy tôi đã sửa đổi giải pháp đó thành giải pháp đã hoạt động. (Giải pháp của tôi không yêu cầu báo giá xung quanh các trường, vì vậy tôi đã bỏ qua chức năng Định dạngCSVField)

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

Tôi cần làm điều tương tự. Tôi đã sử dụng việc thực hiện bởi t3rse, nhưng phải thực hiện một vài thay đổi. Tôi không có đủ uy tín để làm một bình luận về câu trả lời của mình, vì vậy tôi sẽ liệt kê chúng ở đây:

  • Đối với dòng mà nói propInfo.GetValue (dữ liệu, null) ToString(), tôi đã kiểm tra để xem nếu giá trị trả về bởi GetValue là Null trước khi gọi ToString() trên đó.

  • Trong phương thức FormatCSVField(), nó thay thế một dấu ngoặc kép bằng ba dấu ngoặc kép. Nó chỉ nên thay thế nó bằng hai dấu ngoặc kép.

  • Việc triển khai chỉ sử dụng các cột thuộc loại DataGridBoundColumn và bỏ qua những người khác. Tôi có cột mà không phải là DataGridBoundColumn mà tôi muốn bao gồm, vì vậy tôi đã nhận được tên thuộc tính của nguồn dữ liệu cho những cột với col.SortMemberPath.

Các vấn đề liên quan