jqgrid + EF + MVC: можно ли экспортировать в Excel, используя всегда одно и то же действие контроллера? - PullRequest
2 голосов
/ 17 февраля 2012

Я использую jqgrid (стандарт) с EF 4 + MVC3 . Я хотел бы реализовать экспорт Excel и, если возможно, использовать тот же контроллер действий, который использовался для заполнения сетки. Интересно, возможно ли / логично передать дополнительный параметр, например. Какой метод вы мне предложите? Я задаю этот вопрос, потому что я все еще пытаюсь реализовать экспорт в Excel, и я бы хотел оптимизировать / повторно использовать код, если это возможно.

Чтобы сгенерировать Excel, Я бы хотел использовать эту библиотеку доктора Стивена Вальтера, которая имеет три типа вывода и позволяет также определять заголовки. Пожалуйста, скажите мне, если вы найдете это действительным для моих целей.

О коде jqgrid я нашел этот интересный ответ Олега , но я не понимаю, можно ли применить его к моим потребностям.

К сожалению, к настоящему времени я нашел только части решений для экспорта в Excel с EF MVC, но решения или полных примеров не было ...

Вот частичное представление _Index, содержащее мой jqgrid

  <table id="mygrid"></table>
  <div id="pager2"></div>

  jQuery("#mygrid").jqGrid({
url:'controller/jqIndex',
datatype: "json",
colNames:['id','field1', ...],
colModel:[
    {name:'id',index:'id', width:55},
    {name:'field1',index:'field1', width:90},
            ...
],
rowNum:10,
rowList:[10,20,30],
pager: '#pager2',
sortname: 'id',
viewrecords: true,
sortorder: "desc",
caption:"modal jquery + jqgrid test"}); 
jQuery("#list2").jqGrid('navGrid','#pager2',{edit:false,add:false,del:false});

//TODO
???
...some code to call the controller action with the `excel` parameter set `true`

КОНТРОЛЛЕР (НА ОСНОВЕ ОСУЩЕСТВЛЕНИЕ ОЛЕГА )

     public ActionResult jqIndex(string sidx, string sord, int page, int rows, bool _search, string filters, bool excel) // note the excel parameter <<
       {
        var context = new TManagerContext();
        var objectContext = context.ObjectContext();

        var set = objectContext.CreateObjectSet<Ticket>();
        var serializer = new JavaScriptSerializer();

        Filters f = (!_search || string.IsNullOrEmpty(filters)) ? null : serializer.Deserialize<Filters>(filters);
        ObjectQuery<Ticket> filteredQuery = (f == null ? (set) : f.FilterObjectSet(set));

        filteredQuery.MergeOption = MergeOption.NoTracking; // we don't want to update the data


        int totalRecords = filteredQuery.Count();

        var pagedQuery = filteredQuery.Skip("it." + sidx + " " + sord, "@skip",
                                    new ObjectParameter("skip", (page - 1) * rows))
                             .Top("@limit", new ObjectParameter("limit", rows));

        int pageIndex = Convert.ToInt32(page) - 1;
        int pageSize = rows;

        int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);

        var queryDetails = (from e in pagedQuery
                            select new
                            {
                                e.TicketID,
                                e.field1,
                                ...
                            }).ToList();

        var result = new
        {
            total = totalPages,
            page = page,
            records = totalRecords,
            rows = (from e in queryDetails
                    select new
                    {
                        id = e.TicketID,
                        cell = new string[]
                        {
                            e.field1,
                            ...
                        }

                    }).ToArray()
        };

         if (excel) {
            ExportExcel(result); // if possible, pass filter parameters too, column order, etc...
         }

        return Json(result, JsonRequestBehavior.AllowGet);
    }

Пожалуйста, извините, если вопрос может быть глупым, я просто начинающий (энтузиаст).

Спасибо за вашу драгоценную помощь! С наилучшими пожеланиями

1 Ответ

2 голосов
/ 18 февраля 2012

Ларри - Несколько комментариев.

  1. Вы не должны делать так много логики в вашем контроллере. Переместить все этой бизнес-логики в другой класс / услугу. Тогда ваши действия Метод будет всего несколько строк. Быстрый пример

public JsonResult jqIndex(string sidx, string sord, int page, int rows, 
                          bool _search, string filters){
        return JSON(this.GridQueryService.GetJQGrid(sidx,sord,page,rows,_search,filters), JsosnRequestBehavior.AllowGet);
        }

2.Я знаю, что вы не хотите повторять код (что помогает пункт 1), но здесь есть много параметров и вещей, которые просто не применимы к Excel (страницы, строки).

3.Передача логических параметров, чтобы изменить порядок вещей. Предположим, что теперь вам нужно передавать больше / меньше данных в файл Excel, теперь у вас есть вложенные условия повсюду, и модульное тестирование будет просто бесполезным.

4. Метод действия Excel должен иметь возвращаемый тип FileResult, а не Результат JSON (я полагаю, что все они являются результатами действий, но это делает ваше намерение более ясным в вашем коде. Ваше определение должно быть примерно таким:


public FileResult GetExcelFile(string sidx, string sord, bool _search, 
                               string filters){
              //do stuff to return Excel
        }

Если вы создадите свою Службу в точке один таким образом, что у вас есть два метода, которые возвращают разные элементы, но совместно используют общую функцию запроса / поиска, тогда вы действительно останетесь сухим, следуя принципу единой ответственности. Примером этого сервиса может быть (очень грубый пример, который должен дать вам некоторые соображения):

public class GridQueryService{
   public YourViewModel GetJQGrid(sidx, page, row, _search, filters){
      //Get the base data 
      var myData = this.GetGridData(sidx, _search, filters);
      //Create your view model and return it back to controller
} 
   public StreamWriter GetExcelFIle(sidx, _search, filters){
      //Get the base data 
      var myData = this.GetGridData(sidx, _search, filters);
      //Create your Excel file and return it to the controller
}

    private ObjectQuery<Ticket> GetGridData(string sidx, bool _search, string filters){
     //do your data grabbing here - you never return the raw data back to anything outside
     //of this service, so it should be ok to make private
}

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...