2016-12-27 493 views
3

我有使用DataTables服務器端處理顯示在我的網站上的表。我希望能夠「全部導出」並導出所有行,而不僅僅是顯示的那些行。有60000多行和65 +列,所以它必須在服務器端處理完成。使用服務器端處理從DataTable中導出所有數據?

我已經嘗試了一些東西,但到目前爲止沒有任何工作。

我已經試過這樣:

{ 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文件。

我已經在谷歌和這裏搜索了周圍,但還沒有找到一個可行的解決方案。

我還應該提到,我希望基於表格中設置的當前過濾器導出全部。這樣最終用戶將只獲得他們正在搜索的那些行的導出。他們通常將其限制在30k - 40k行,仍然是65列。我不(允許)刪除/隱藏列。

編輯/ UPDATE

這裏是一個次要的考慮:如果我不能全部從服務器的響應導出,我可以建立了Excel服務器上的文件嗎?我的服務器沒有安裝Excel,我仍然希望最終用戶獲取該文件。我確信我必須找到一種方法將Excel放到我的服務器上,但是如何將任何已創建的文件傳輸給最終用戶,甚至可以比發送整個數據集的響應更快用戶計算機上的Excel文件?

編輯

有人建議我嘗試jQuery的$.ajax()得到這個工作。如果有人能給我一個如何做的想法,我會嘗試第三個按鈕。

我已經可以提取所有數據,使用用戶添加的相同過濾器和排序,並使用按鈕執行此操作。上面的第二次嘗試是這樣做的,但將它發送到屏幕。我有PHPExcel和一個可以創建Excel工作表的文件。我如何將第二個按鈕中的內容拿到第二個按鈕中,並將其發送到另一個文件以創建Excel工作表?我認爲使用jquery的$.ajax()可能工作,我只是不知道如何去。我知道我必須使用$_POST,因爲數據可能太大而無法使用$_GET將數據發送到PHPExcel文件。

我已經可以導出爲CSV格式,但我需要導出一些格式,而CSV沒有。這就是爲什麼我要使用PHPExcel的麻煩。

編輯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)); 
} 

這是我的設置,我用它來保持搜索和排序標準的cookie:

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

所有這一切結合發送正確的標準來FilterSort.class.php應處理標準並將數據集返回到ExportAllToExcell。然後創建Excel文件的php。現在我發送了大量的報告,但它超時了。

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'; 

我也改變了我把查詢的方式,我現在還保持表名稱用戶名這樣的:

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

});} 
相關問題