2016-12-27 491 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); 

});} 
相关问题