web-dev-qa-db-ja.com

サーバーサイド処理でDataTablesからすべてエクスポートしますか?

DataTablesサーバー側の処理を使用して自分のWebサイトに表示するテーブルがあります。 「すべてエクスポート」して、表示されている行だけでなく、すべての行をエクスポートできるようにしたい。 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で検索しましたが、機能する解決策を見つけていません。

また、テーブルに設定されている現在のフィルターに基づいてすべてをエクスポートすることにも言及します。したがって、エンドユーザーは、検索している行のみのエクスポートを取得します。彼らは通常それをまだ65以上の列で30k-40k行に制限します。列の削除/非表示は(まだ)許可していません。

編集/更新

2つ目の考慮事項は次のとおりです。サーバーからの応答からすべてをエクスポートできない場合、サーバー上でExcelファイルを作成できますか?サーバーにExcelがインストールされていませんが、エンドユーザーにファイルを取得してもらいます。私は自分のサーバーにExcelを取得する方法を見つける必要があると確信していますが、作成したファイルをエンドユーザーに転送するにはどうすればよいですか?ユーザーのコンピューター上のExcelファイル

[〜#〜]編集[〜#〜]

これを機能させるために、jqueryの$.ajax()を試すことをお勧めしました。誰かがそれを行う方法についてのアイデアを私に与えることができるならば、私は3番目のボタンのためにそれを試します。

ユーザーが追加したのと同じフィルターと並べ替えを使用して、すべてのデータを既にプルして、ボタンでそれを行うことができます。上記の2番目の試みはそれを行いますが、画面に送信します。 PHPExcelとExcelシートを作成できるファイルがあります。 2番目のボタンで取得したものをどのようにして他のファイルに送信し、Excelシートを作成しますか?私はjqueryの$.ajax()を使用するとうまくいくかもしれないと思っていましたが、それを取得する方法がわかりません。データが大きすぎて_$_POST_を使用してデータをPHPExcelファイルに送信できない場合があるため、私は_$_GET_を使用する必要があることを知っています。

すでに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);
        })
    }
}
_

編集4

うまくいけば、最後の編集。

この作業を行うには、次の3つのことを行う必要があります。

  1. 現在の並べ替えとフィルタリングを取得する
  2. 長さが-1に設定されたデータセットを取得する
  3. これをPHPExcelファイルに送信して、Excelファイルを処理および作成します。次のようなボタンを作成できます。

    {テキスト: 'すべてのデータをExcelにエクスポートする'、アクション:}

私はアクションが何である必要があるのか​​分かりません。

上記の2回目の試行では、必要なデータセット全体をプルしますが、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);
    }
};
_
6
Mike

私はほとんどこれを働いています。現在はタイムアウトになっていますが、データサイズが原因でこれが機能しないため、別の問題です。小さなデータセットの場合、完全に機能します。

これが私がボタンを作成する方法です(ここで使用しているexportボタンです):

"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に送信され、基準が処理されてデータセットがに返されます。その後、Excelファイルを作成するExportAllToExcell.php。現在、大量のレポートを送信していますが、タイムアウトします。

[〜#〜]更新[〜#〜]

これを行う方法を少し変更しました:

新しいボタンのセットは次のとおりです。

"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');
        }
    }]
}
]

Export All to 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';

クエリを保持する方法も変更しました。Table NameUserNameも保持するようになりました。 このように:

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
Mike

私はこれに遭遇し、別の解決策を考え出しました。

DataTableオプションで、これを追加します。

"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]

これにより、ユーザーはすべての行を選択できるようになり、「長さ」クエリ文字列パラメーターで-1をサーバーに送信します。サーバー側では、負の数を処理し、-1を受け取ったときにすべての行を返すことができるようにする必要があります。

これにより、テーブル内のすべての行が表示され、それらすべてがエクスポートされます。

これは50-60K行には適さないかもしれませんが、小さいデータセットの場合、サーバー側とクライアント側の両方で追加のコードを実装しなくても機能することを理解しています。

1
Prashant Gupta

ボタン内:

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

});}
1
Reza