2008-11-20 6 views

ответ

2

Я не думаю, что Silverlight предлагает способ загрузки файлов. Вы можете добавить кнопку в свое приложение, которое вызывает URL-адрес, то есть http://www.mysite.com/generateexcelfile.aspx. Включить в качестве Querystring значение параметров, используемых для генерации данных, отображаемых в приложении Silverlight, запустить ваш запрос и использовать ваш любимый компонент генерации файлов Excel для генерации файла «на лету». Переадресовываем его и загружаем в систему пользователей.

+3

Будьте осторожны с «создайте файл, а затем перенаправите его» - вы должны удалить эти файлы в какой-то момент. Лучше всего было бы просто сохранить Excel в выходной поток страницы .aspx с правильным типом mime, чтобы браузер мог видеть, что это файл Excel, а не html-страница, и дать пользователю возможность сохранить его , – user8032 2009-11-16 23:24:52

4

Я нашел this используя буфер обмена.

Чтобы сделать код родовым вы можете изменить первый пример для чтения привязок столбцов и их применимости к данным с помощью отражения:

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

конечно, она работает только тогда, когда путь связывания является Имя свойства. Для более продвинутых путей вам необходимо применить привязку к данным (я полагаю, это было бы лучшим решением, но я не уверен, как это сделать).

1

Off верхней части моей головы, я бы сказал, вы можете добавить кнопку экспорта с помощью ControlTemplate, а затем итерации по каждому элементу в DataSource, а затем использовать каждый столбец в Columns, чтобы получить содержимое каждой ячейки с помощью метода GetCellContent , или используйте информацию привязки DataGridColumn, чтобы получить соответствующее значение ячейки. Затем вы можете получить отображаемое значение этого содержимого и записать его в свой отчет.

Что-то вроде ...

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

    } 
} 

Или с помощью связывания информации, как описано DaniCE.

21

Silverlight 3 изменяет ответ на этот вопрос, поскольку он дает возможность пользователю создавать файл на рабочем столе пользователя в указанном им местоположении. Я адаптировал код, представленный DaniCE, разделить вещи на несколько методов для удобочитаемости, и я использую свободно определенный формат CSV, который должен распознать Excel.

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

Это работает ?! – Goober 2009-09-25 08:41:44

+1

Он делает с некоторой ловкостью руки; он создает файл CSV, а не XLS. Если у человека установлен Excel, он открывает его в силу расширения, которое отображается в Excel. – t3rse 2009-09-28 15:42:37

1

Проверьте решение Райана. Выглядит хорошо, не может ручаться за него, хотя, потому что я его нашел. Райан делает то, что запросила DLL.

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

Дэвид в растворе Дакоты выше выглядит немного проще реализовать, и всегда есть редирект классической страницы asp.net с сеткой данных на нем и тип содержимого набора, чтобы преуспеть, но затем у вас есть больше кода для поддержки, и таким образом может не работать из-за недоступных браузеров решений (на самом деле это не сработает).

В любом случае, это обычная задача.Я надеюсь, что некоторые люди здесь или в Microsoft придумали Мортом подключи и играй решение :)

Я нашел метод расширения для экспорта CVS из Silverlight datagrid-

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

Она имеет потенциал для быть подключи и играй, но мне пришлось немного подкрутить его, чтобы заставить его работать с datagrids с источниками данных источника (см. комментарии в сообщении). Кто-то более яркий и опытный, чем я, должен быть в состоянии доработать до совершенства. Проверьте это, он должен приблизить вас к тому, что вам нужно.

2

Я знаю, что это старый пост, но он помог мне. Я сделал некоторые изменения, чтобы заставить его работать с silverlight 4, конвертировать и преуспеть. Мне нужен быстрый экспорт, поэтому я сначала использую CSV, а затем открываю его с помощью excel. Этот код работает в сети silverlight и обеспечивает повышенное доверие. В Web не открывается в 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(); 
    } 
1

Эти решения не сработали для меня, поэтому я изменил их на то, что сработало. (Мое решение не требует кавычек вокруг полей, поэтому я оставил свою функцию FormatCSVField)

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

мне нужно сделать то же самое. Я использовал реализацию t3rse, но должен был внести несколько изменений. Я не хватает репутации сделать комментарий на его ответ, так что я буду перечислять их здесь:

  • Для линии, которая говорит propInfo.GetValue (данные, нуль) .ToString(), я проверил посмотрите, возвращает ли значение, возвращаемое GetValue, Null перед вызовом ToString() на нем.

  • В методе FormatCSVField() он заменил двойную кавычку тремя двойными кавычками. Он должен заменить его только двумя двойными кавычками.

  • Реализация использует только столбцы типа DataGridBoundColumn и игнорирует другие. У меня есть столбцы, которые не являются DataGridBoundColumn, которые я хотел включить, поэтому я получил имя свойства источника данных для этих столбцов с col.SortMemberPath.

Смежные вопросы