2016-12-27 3 views
3

У меня есть таблицы, которые используют обработку на стороне сервера DataTables для показа на моем веб-сайте. Я хочу иметь возможность «Экспортировать все» и экспортировать все строки, а не только отображаемые строки. Есть 60000+ строк и 65 + столбцов, поэтому это должно быть сделано с обработкой на стороне сервера.Экспортировать все из данных с обработкой на стороне сервера?

Я пробовал несколько вещей, но до сих пор ничего не сработало.

Я попытался это:

{ extend: 'excel', 
    text: 'Export Current Page', 
    exportOptions: { 
     modifier: { 
      page: 'current' 
     } 
    }, 
    customize: function (xlsx) 
    { 
     var sheet = xlsx.xl.worksheets['sheet1.xml']; 
     $('row:first c', sheet).attr('s', '7'); 
    } 
} 

Что экспортируются только те строки, которые были с указанием на этой странице.

Я попытался это:

{ 
    text: 'Export All to Excel', 
    action: function (e, dt, button, config) 
    { 
     dt.one('preXhr', function (e, s, data) 
     { 
      data.length = -1; 
     }).one('draw', function (e, settings, json, xhr) 
     { 
      var excelButtonConfig = $.fn.DataTable.ext.buttons.excelHtml5; 
      var addOptions = { exportOptions: { 'columns': ':all'} }; 

      $.extend(true, excelButtonConfig, addOptions); 
      excelButtonConfig.action(e, dt, button, excelButtonConfig); 
     }).draw(); 
    } 
} 

Это посылает данные всей таблицы на экран вместо использования пагинации и отправок всего набора данных в файл Excel.

Я искал в Google и здесь, в SO, но не нашел решения, которое работает.

Следует также упомянуть, что я хочу экспортировать все на основе текущих фильтров, установленных в таблице. Чтобы конечный пользователь получал Экспорт только тех строк, которые они ищут. Обычно они ограничивают его до 30k - 40k строк, все еще с 65 + столбцами. Я еще не разрешаю удалять/скрывать столбцы.

EDIT/UPDATE

Вот второстепенное значение: Если я не могу экспортировать все из ответа сервера, я могу построить Excel файл на сервере? На моих серверах не установлен Excel, и я все равно хочу, чтобы мой конечный пользователь получил файл. Я уверен, что мне нужно будет найти способ получить Excel на моих серверах, но как я могу передать любые созданные файлы конечному пользователю, и это будет даже быстрее, чем просто отправить ответ со всем набором данных и создать файл Excel на компьютере пользователя?

EDIT

Было рекомендовано, что я пытаюсь JQuery-х $.ajax(), чтобы получить эту работу. Если кто-то может дать мне представление о том, как это сделать, я попробую сделать это для третьей кнопки.

Я уже могу вытащить все данные с теми же фильтрами и сортировкой, которые добавлены пользователем, и сделать это с помощью кнопки. Вторая попытка выше делает это, но отправляет его на экран. У меня есть PHPExcel и файл, который может создать лист Excel. Как я возьму то, что получаю в этой второй кнопке, и отправлю его в другой файл, чтобы создать лист Excel? Я думал, что использование jQuery $.ajax() может работать, я просто не знаю, как его получить. Я знаю, что мне придется использовать $_POST, так как данные могут быть слишком большими, чтобы использовать $_GET для отправки данных в файл PHPExcel.

Я уже могу экспортировать в CSV, но мне нужно экспортировать с некоторым форматированием, которого нет в CSV. Вот почему я столкнулся с проблемой использования PHPExcel.

EDIT III

Я пытаюсь это, хотя он еще не работает:

{ 
    text: 'Export all to Excel II', 
    action: function (e, dt, button, config) 
    { 
     dt.one('preXhr', function (e, s, data) 
     { 
      data.length = -1; 
     }).one('export', function (e, settings, json, xhr) 
     { 
      var excelButtonConfig = $.fn.DataTable.ext.buttons.excelHtml5; 
      var addOptions = { exportOptions: { 'columns': ':all'} }; 

      $.extend(true, excelButtonConfig, addOptions); 
      excelButtonConfig.action(e, dt, button, excelButtonConfig); 
     }) 
    } 
} 

EDIT 4

Будем надеяться последнего редактирования.

Я знаю, что я должен сделать три вещи, чтобы сделать эту работу:

  1. Получить текущий Сортировка и фильтрация
  2. Получить набор данных с длиной равным -1
  3. Отправить это PHPExcel файл для обработка и создание файла Excel Я могу создать кнопку, как это:

    { текст: «экспортировать все данные в Excel», действие: }

Я просто не знаю, какое действие должно быть.

Моя вторая попытка выше тянет весь набор данных, который мне нужен, но отправляет его на экран вместо моего файла PHPExcel (ExportAllToExcel.php).

Я пытался понять это и не очень далеко. Мне сказали, что мне нужно использовать $.ajax() для этого, мне сказали, что мне не нужно это использовать. Я пробовал с и без, и не смог никуда добраться.

Я также попытался использовать это никакого эффекта:

$.fn.dataTable.ext.buttons.export = 
{ 
    className: 'buttons-alert', 
    "text": "Export All Test", 
    action: function (e, dt, node, config) 
    { 
     var SearchData = dt.search(); 
     var OrderData = dt.order(); 
     alert("Test Data for Searching: " + SearchData); 
     alert("Test Data for Ordering: " + OrderData); 
    } 
}; 
+0

Увеличение памяти в файле php.ini для вашей ошибки. И почему вы делаете это или экспортируете таким образом? – webDev

+0

@ShaileshSingh Я пробовал это в прошлом. Это не жизнеспособное решение, так как нет никакой памяти, которая позволит этому работать. Независимо от того, насколько велика я устанавливаю предел, это всегда достигается. – Mike

+1

Я больше не получаю ошибку о достижении предела памяти. Я думаю, что это была просто случайность, в первую очередь это проявилось. – Mike

ответ

0

У меня это работает, в основном. В настоящее время тайм-аут, но это отдельный вопрос из-за размера данных, а не для этой работы. Для небольших наборов данных он отлично работает.

Это, как я создаю кнопку (это экспорт кнопка, которую я использую здесь):

"buttons": [{ 
       extend: 'collection', 
       text: 'Selection', 
       buttons: ['selectAll', 'selectNone'] 
      }, { 
       extend: 'collection', 
       text: 'Export', 
       buttons: ['export', 'excel', 'csv', 'pdf', { extend: 'excel', 
        text: 'Export Current Page', 
        exportOptions: { 
         modifier: { 
          page: 'current' 
         } 
        }, 
        customize: function (xlsx) 
        { 
         var sheet = xlsx.xl.worksheets['sheet1.xml']; 
         $('row:first c', sheet).attr('s', '7'); 
        } 
       }] 
      } 
      ] 

Это инициализация кнопки, созданную выше:

$.fn.dataTable.ext.buttons.export = 
{ 
    className: 'buttons-alert', 
    id: 'ExportButton', 
    text: "Export All Test III", 
    action: function (e, dt, node, config) 
    { 
     var SearchData = dt.rows({ filter: 'applied' }).data(); 
     var SearchData1 = dt.search(); 
     console.log(SearchData); 
     var OrderData = dt.order(); 
     console.log(SearchData1); 
     var NumCol = SearchData[0].length; 
     var NumRow = SearchData.length; 
     var SearchData2 = []; 
     for (j = 0; j < NumRow; j++) 
     { 
      var NewSearchData = SearchData[j]; 
      for (i = 0; i < NewSearchData.length; i++) 
      { 
       NewSearchData[i] = NewSearchData[i].replace("<div class='Scrollable'>", ""); 
       NewSearchData[i] = NewSearchData[i].replace("</div>", ""); 
      } 
      SearchData2.push([NewSearchData]); 
     } 

     for (i = 0; i < SearchData2.length; i++) 
     { 
      for (j = 0; j < SearchData2[i].length; j++) 
      { 
       SearchData2[i][j] = SearchData2[i][j].join('::'); 
      } 
     } 
     SearchData2 = SearchData2.join("%%"); 
     window.location.href = './ServerSide.php?ExportToExcel=Yes'; 
    } 
}; 

И вот часть файла ServerSide.php, который получает данные и отправляет их на сервер для обработки:

require('FilterSort.class.php'); 

if (isset($_GET['ExportToExcel']) && $_GET['ExportToExcel'] == 'Yes') 
{ 
    $request = @unserialize($_COOKIE['KeepPost']); 
    $DataReturn = json_encode(FilterSort::complex($request,$sqlConnect,$table,$primaryKey,$ColumnHeader)); 
    require './ExportAllToExcel.php'; 
} 
else 
{ 
    echo json_encode(FilterSort::complex($request,$sqlConnect,$table,$primaryKey,$ColumnHeader)); 
} 

Это, как я установить куки, которые я использую, чтобы держать поиск и сортировку критериев:

if(isset($_POST['draw'])) 
{ 
    $KeepPost = $_POST;  
    $KeepPost['length'] = -1; 
    $PostKept = serialize($KeepPost); 
    setcookie("KeepPost",$PostKept,time() + (60*60*24*7)); 
} 

Все это в сочетании посылает правильные критерии для FilterSort.class.php, которые должны обрабатывать критерии и вернуть набор данных в ExportAllToExcell.php, который затем создает файл Excel. Прямо сейчас я отправляю ему огромные отчеты, но это время.

UPDATE

Я немного изменил способ, что я делаю это:

Вот новый набор кнопок:

"buttons": [{ 
    extend: 'collection', 
    text: 'Export', 
    buttons: ['export', { extend: 'csv', 
     text: 'Export All To CSV',    //Export all to CSV file 
     action: function (e, dt, node, config) 
     { 
      window.location.href = './ServerSide.php?ExportToCSV=Yes'; 
     } 
    }, 'csv', 'pdf', { extend: 'excel', 
     text: 'Export Current Page',   //Export to Excel only the current page and highlight the first row as headers 
     exportOptions: { 
      modifier: { 
       page: 'current' 
      } 
     }, 
     customize: function (xlsx) 
     { 
      var sheet = xlsx.xl.worksheets['sheet1.xml']; 
      $('row:first c', sheet).attr('s', '7'); 
     } 
    }] 
} 
] 

Вот как я создаю Экспортировать все к Excel кнопка:

$.fn.dataTable.ext.buttons.export = 
{ 
    className: 'buttons-alert',       //Adds the "Export all to Excel" button 
    id: 'ExportButton', 
    text: "Export All To Excel", 
    action: function (e, dt, node, config) 
    { 
     window.location.href = './ServerSide.php?ExportToExcel=Yes'; 
    } 
}; 

Теперь они посылают данные в том же ServerSide.php файл, который я использовал раньше:

require('FilterSort.class.php'); 
if (isset($_GET['ExportToExcel']) && $_GET['ExportToExcel'] == 'Yes') 
{ 
    include 'Helper/LogReport.php'; 
    $GetSQL = "Select Value from PostKept where UserName = '" .$_COOKIE['UserName']. "'"; 
    $KeepResult = $conn->query($GetSQL); 
    $KeepResults = $KeepResult->fetchALL(PDO::FETCH_ASSOC); 

    $request = unserialize($KeepResults[0]['Value']); 

    $DataReturn = json_encode(FilterSort::complex($request,$sqlConnect,$table,$primaryKey,$ColumnHeader,1)); 
    require './ExportAllToExcel.php'; 

Я также изменил способ, которым я держу запрос, я теперь также сохраняя таблицу Имя и UserName так:

include 'DBConn.php'; 
$KeepPost = $_POST;          //POST holds all the data for the search 
$KeepPost['length'] = -1;        //-1 means pulling the whole table 
$PostKept = serialize($KeepPost);      //This takes the array of data and turns it into a string for storage in SQL 
$SQLCheck = "select distinct UserName from PostKept"; //Gets all the distinct Usernames of users that have used the Report Dashboard. 
$sth = $conn->query($SQLCheck); 
$CheckedUser = $sth->fetchALL(PDO::FETCH_ASSOC); 
foreach($CheckedUser as $User) 
{ 
    foreach($User as $Index => $Who) 
    { 
     $FoundUsers[] = $Who;       //Taking all the found users and placing them into a simpler array for searching later 

    } 
} 

if(isset($_COOKIE['UserName']) && in_array($_COOKIE['UserName'],$FoundUsers)) //If the user already has an entry update it with new information 
{ 
    $TSQL = "UPDATE PostKept set Value = '" .$PostKept. "', TableName = '" .$TableName. "' where UserName = '" .$_COOKIE['UserName']. "'"; 
} 
else 
{ 
    if(isset($_COOKIE['UserName']))  //If this is a new user 
    { 
     $TSQL = "INSERT into PostKept(Value, TableName, UserName) select '" .$PostKept. "','" .$TableName. "','" .$_COOKIE['UserName']. "'"; 
    } 
    else  //If this is on the Prod site and the User info is not yet kept 
    { 
     $TSQL = "INSERT into PostKept(Value, TableName) select '" .$PostKept. "','" .$TableName. "'"; 
    } 
} 

$sth = $conn->prepare($TSQL); 
$sth->execute(); 

Это теперь, что все комбинаты, чтобы отправить данные в ExportAllToExcel.php файла т у меня есть, а затем он в свою очередь создает файл.

1

в кнопках:

action: function (e, dt, node, config) { 

var formData = 'yourfilters'; 
formData.begin = '0'; 
formData.length = 'yourTotalSize'; 

$http({ 
    url: 'yourURL', 
    method: 'POST', 
    data: JSON.stringify(formData) 
}).then(function (ajaxReturnedData) { 

    dt.rows.add(ajaxReturnedData.data).draw(); 
    $.fn.dataTable.ext.buttons.excelHtml5.action.call(this, e, dt, node, config); 

});}