2015-03-10 4 views
1

У меня есть приложение MVC5/Code-First, которое я разрабатываю с использованием Entity Framework. В настоящее время я пытаюсь добавить функцию Export to Excel для динамического вывода выбранных пользователем свойств моей модели INV_Assets. Используя EPPlus Libary и Linq.Dynamic, мне удалось экспортировать свои данные в excel, но не совсем правильно.Доступ к содержимому IQueryable/System.Collections.Generic.List?

Я получил заголовки для экспорта в строку 1, но мне все еще трудно получить данные для экспорта. В настоящее время данные для моих выбранных полей встречаются, но каждое значение экспортируется как длинная строка в собственную строку в столбце A. Например, если я выберу следующие поля (Status, ip_address, mac_address, note, owner, cost, PO_NUMBER и описание) я получаю следующее:

row1: [Status][ip_address][mac_address][note][owner][cost][po_number][description]

row2: [{Status=SIGNEDOUT, ip_address=10.10.121.25, mac_address=10.10.134.11, note=, owner=John Smith, cost=35.00, po_number=G348, description=This is a description of the item.}][][][][][][][]

Вот визуальный выход настоящее время я получаю в Excel:

ExcelOutput

Когда я установил свою IQueryable переменную (selectStatement) в качестве переменной Watch в VS2013 я в состоянии углубиться в содержание, но я не могу понять, как получить доступ к этим содержание индивидуально в коде:

IQueryable

В настоящее время я использую свой IQueryable и загружаю его в Excel с помощью метода EPPlus LoadFromCollection(), но если я смогу выяснить, как получить доступ к отдельному содержимому моего , я могу настроить некоторые счетчики и циклы, чтобы соответствующим образом установить ячейки, которые я хочу вместо все демпинг в ColumnA.

Может ли кто-нибудь помочь в этом? Полный код для моего ExportController ниже:

public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model) 
    { 
     ExcelPackage package = new ExcelPackage(); 
     var ws = package.Workbook.Worksheets.Add("TestExport"); 

     var exportFields = new List<string>(); 
     foreach (var selectedField in model.SelectedFields) 
     { 
      // Adds selected fields to [exportFields] List<string> 
      exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value); 
     } 

     IQueryable selectStatement = DynamicSelectionColumns(exportFields); 

     // Loops to insert column headings into Row 1 of Excel 
     for (int i = 0; i < exportFields.Count(); i++) 
     { 
      ws.Cells[1, i + 1].Value = exportFields[i].ToString(); 
     } 

     // Place contents of IQueryable into Excel -- currently dumps selected value for each record into rows with all values for the row as a long string in ColumnA 
     if (selectStatement.Count() > 0) 
     { 
      ws.Cells["A2"].LoadFromCollection(selectStatement.Cast<object>(), true); 
     } 

     int cnt = 20; 
     foreach (var item in selectStatement) 
     { 
      ws.Cells["A" + cnt].LoadFromCollection(selectStatement.Cast<object>(), false); 
      cnt++; 

     } 


     var memoryStream = new MemoryStream(); 
     package.SaveAs(memoryStream); 

     string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx"; 
     string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 

     memoryStream.Position = 0; 
     return File(memoryStream, contentType, fileName); 
    } 

    public IQueryable DynamicSelectionColumns(List<string> fieldsForExport) 
    { 
     using (var db = new InventoryTrackerContext()) 
     { 
      string fieldIds = "," + "4,5,3,2,6,17,11,12" + ","; 

      var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", "")); 

      //string select = "new ( TaskId, " + (taskColum.Count() > 0 ? string.Join(", ", taskColum) + ", " : "") + "Id)"; 
      string select = "new ( " + string.Join(", ", fieldsForExport) + ")"; 

      //return db.INV_Assets.ToList().Select(t => new DynamicColumns() { Id = t.Id, TaskId = Project != null ? Project.Alias + "-" + t.Id : t.Id.ToString(), 
      return db.INV_Assets.ToList().Select(t => new DynamicColumns() 
      { 
       Id = t.Id, 
       Manufacturer = Convert.ToString(t.Manufacturer.manufacturer_description), 
       Type = t.Type.type_description, 
       Location = t.Location.location_room, 
       Vendor = t.Vendor.vendor_name, 
       Status = t.Status.status_description, 
       ip_address = t.ip_address, 
       mac_address = t.mac_address, 
       note = t.note, 
       owner = t.owner, 
       //Module = t.Module != null ? t.Module.Name : "", 
       cost = t.cost, 
       po_number = t.po_number, 
       description = t.description, 
       invoice_number = t.invoice_number, 
       serial_number = t.serial_number, 
       asset_tag_number = t.asset_tag_number, 
       acquired_date = t.acquired_date, 
       disposed_date = t.disposed_date, 
       verified_date = t.verified_date, 
       created_date = t.created_date, 
       created_by = t.created_by, 
       modified_date = t.modified_date, 
       modified_by = t.modified_by 
      }).ToList().AsQueryable().Select(select); 
     } 
    } 
} 

public class DynamicColumns : INV_Assets 
{ 
    public string Model { get; set; } 
    public string Manufacturer { get; set; } 
    public string Type { get; set; } 
    public string Location { get; set; } 
    public string Vendor { get; set; } 
    public string Status { get; set; } 
    public string ip_address { get; set; } 
    public string mac_address { get; set; } 
    public string note { get; set; } 
    public string owner { get; set; } 
    public decimal cost { get; set; } 
    public string po_number { get; set; } 
    public string description { get; set; } 
    public int invoice_number { get; set; } 
    public string serial_number { get; set; } 
    public string asset_tag_number { get; set; } 
    public DateTime? acquired_date { get; set; } 
    public DateTime? disposed_date { get; set; } 
    public DateTime? verified_date { get; set; } 
    public DateTime created_date { get; set; } 
    public string created_by { get; set; } 
    public DateTime? modified_date { get; set; } 
    public string modified_by { get; set; } 
} 

public enum EnumTasks 
{ 
    Model = 1, 
    Manufacturer = 2, 
    Type = 3, 
    Location = 4, 
    Vendor = 5, 
    Status = 6, 
    ip_address = 7, 
    mac_address = 8, 
    note = 9, 
    owner = 10, 
    cost = 11, 
    po_number = 12, 
    description = 13, 
    invoice_number = 14, 
    serial_number = 15, 
    asset_tag_number = 16, 
    acquired_date = 17, 
    disposed_date = 18, 
    verified_date = 19, 
    created_date = 20, 
    created_by = 21, 
    modified_date = 22, 
    modified_by = 23 
} 
+0

@ Эрик Дж., Хорошо? Как только я передаю эту строку кода и проверю 'dbg' в' Immediate Window', я получаю граф 14 с каждым из перечисленных значений 0-13. –

+0

Добавлен правильный ответ. –

ответ

0

Выход вы получаете в ваших клетках, не заголовочных:

Status = SIGNEDOUT, ip_address = 10.10.121.25, mac_address = 10.10.134.11, примечание = , owner = John Smith, cost = 35.00, po_number = G348, description = Это описание предмета.

выглядит следующим образом: property=value, через запятую. Я бы предположил, что метод ToString() объекта переопределен и создает этот вывод.

Поскольку вы бросаете ваши сильно типизированных объекты System.Object

selectStatement.Cast<object>() 

, что, вероятно, самое лучшее, что может сделать EPPlus.

Не пытайтесь использовать его в System.Object, например.

ws.Cells["A2"].LoadFromCollection(selectStatement, true); 

Вот статья, которая показывает правильное использование LoadFromCollection

http://www.sitecorecleveland.com/resources/blogs-posts/easy_excel_interaction_pt5

UPDATE

Погрешность

Аргументы типа для метода «OfficeOpenXml.ExcelRangeBase. LoadFromCollection (System.Collection.Generic.IE numerable, bool) 'не может быть выведено из использования. Попробуйте явно указать аргументы типа.

говорит вам, что вам нужно указать тип фактическое возвращенного запросом (вместо указания object).

ws.Cells["A2"].LoadFromCollection(selectStatement.Cast<DynamicColumns>(), true); 
+0

Я думаю, что я вижу, что вы говорите, но когда я удаляю 'Cast()' then 'ws.Cells [" A2 "]. LoadFromCollection (selectStatement, true);' flags в VS2013 как '" Аргументы типа для метода 'OfficeOpenXml.ExcelRangeBase.LoadFromCollection (System.Collection.Generic.IEnumerable , bool)' не может быть выведен из использования. Попробуйте явно указать аргументы типа. "...? –

+0

См. Мое обновление. Я думаю, что 'DynamicColumns' - правильный тип данных, основанный на вашем примере кода, но не уверен. –

+0

Хм ... Я не уверен. Когда я пытаюсь использовать ws.Cells ["A2"]. LoadFromCollection (selectStatement.Cast (), true); 'Я получаю во время выполнения:' Исключение типа 'System.InvalidCastException' произошло в System.Core.dll но не был обработан в коде пользователя. Дополнительная информация: Невозможно наложить объект типа «DynamicClass1» на тип «InventoryTracker.Controllers.DynamicColumns». '' 'Cast()' как 'DynamicClass', однако выполняет код таким же, как и приведение к' object', со всеми ценности; но как длинная строка в столбце A. –

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