投稿タイプデータ(記事)を一括でCSVエクスポートする機能を実装する方法(プラグインなし)
みなさんこんにちは!エンジニアの高澤です!
今回はプラグインなしで投稿タイプ(記事)データを一括でCSVエクスポートする機能を実装する方法について解説していきたいと思います。
当記事を読んでいただくことで、投稿データ(記事データ)を一括で、もしくは特定の記事を選択してCSVとしてダウンロード(エクスポート)を自由自在に実装してできるようになります。
筆者自身これまでの実際のお仕事での経験上、クライアントから当記事の実装内容のご要望が頻繁にありましたので、ぜひ沢山ご活用いただけましたら幸いです。
目次
当記事の実装内容とは
まずは当記事の実装内容について解説し、実装内容のイメージを掴んでいただけたらと思います。
結論としては、下図のように投稿一覧管理画面の絞り込み選択ボタン付近にCSVダウンロード専用のボタンを追加する、という実装になります。
単純にボタンをクリックしたら全件の記事データがエクスポートされ、CSV形式のファイルがダウンロードされます。
そして、投稿一覧の各記事項目の左にあるチェックボックスを選択したら、その選択した記事の分のみエクスポートされ、CSV形式のファイルがダウンロードされる、という機能も合わせて備わっております。
実装する機能としては、割とシンプルな機能になっているかと思います。
当記事の内容のメリット
それでは次に、当記事の内容のメリットを解説いたします。
筆者が考える当記事のメリットは以下になります。
- CSVエクスポートができる(しかも無料で)
- 「一括」もしくは「選択した記事のみ」でエクスポートが可能
- PHPで自作するため柔軟にカスタマイズが可能
- カスタムフィールドやカスタムタクソノミーなど全てのデータに対応できる
メリットとしては上記のような内容になります。
もちろん事前にクライアントから要件聞いたうえで適切かをご判断いただければと思いますが、「CSVで記事をダウンロードしたいんだけど」という問い合わせがあった場合は、当記事のエクスポート機能を実装して対応いただければ喜んでいただけると思います。
また念の為あえてデメリットをあげるとすれば、「もし投稿記事データのデータ構成(カスタムフィールド等)に変更があった場合はエンジニアによるメンテナンスが必要になる可能性がある」というところだと思います。
もちろんメンテナンスが必要ないようにPHPでシステムを作り込めばいいのですが、当記事で扱ったらとんでもない文章量になってしまうため、省略させていただきます。
クライアントに提案する場合はこの部分をしっかり伝え、実装しましょう。
機能を実装する方法
それでは早速、CSVエクスポート機能の実装方法について解説していきます。
サンプルコードをfunctions.phpにコピペする
最初にコードを記述して機能の雛形を実装していきましょう。
以下のコードをfunctions.phpにコピー&ペーストしてください。
<?php
// ボタン追加
function admin_post_list_add_export_button($which) {
// タイプが求人でかつ位置がトップの場合にCSVエクスポートボタンを追加
global $typenow;
if ('post' === $typenow && 'top' === $which) { ?>
<input type="submit" name="export_posts" class="button button-primary" value="<?php _e('CSVエクスポート'); ?>" />
<?php }
}
// 投稿一覧画面のフィルターフックでボタン追加関数を呼び出し
add_action('manage_posts_extra_tablenav', 'admin_post_list_add_export_button', 20, 1);
// CSVエクスポート処理
function func_export_posts() {
// CSVエクスポートボタンがクリックされたかどうかを確認
if (isset($_GET['export_posts'])) {
// 選択された記事のIDをカンマ区切りの文字列に変換
if (isset($_GET['post']) && is_array($_GET['post'])) {
$post = implode(',', $_GET['post']);
}
// 選択された記事の情報を取得
$arg = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'include' => $post
);
global $post;
$arr_post = get_posts($arg);
if ($arr_post) {
// CSVヘッダーを設定
header('Content-type: text/csv');
header('Content-Disposition: attachment; filename="posts'.date('YmdHms').'.csv"');
header('Pragma: no-cache');
header('Expires: 0');
$file = fopen('php://output', 'w');
stream_filter_prepend($file, 'convert.iconv.utf-8/cp932//TRANSLIT');
// CSVヘッダーを設定
fputcsv($file, array('タイトル', 'URL', '日付'));
// ユーザー情報をCSVファイルに書き込む
foreach ($arr_post as $post) {
setup_postdata($post);
// カスタムフィールドやタクソノミーの情報を取得してCSVに書き込む処理を行う
// 例:
// $title = get_the_title();
// $url = get_the_permalink();
// 他のフィールドやタクソノミーも同様に取得してCSVに書き込む
// fputcsv($file, array($title, $url, ...));
fputcsv($file, array(get_the_title(), get_the_permalink(), get_the_time("Y/m/d")));
}
exit();
}
}
}
// イニシャライズフックでCSVエクスポート関数を呼び出し
add_action('init', 'func_export_posts');
上記コードをペースト後して保存後、管理画面のページを更新していただくと投稿(投稿タイプ「post」)の記事一覧管理画面に青色のボタンが上下に新規追加されているのが確認できるかと思います。
試しに「CSVエクスポート」ボタンをクリックしてみてください。
クリックすると、CSV形式のファイルがダウンロードされ、下図のようにエクセルで開いたときに「タイトル」「URL」「日付」の3つが出力されているのがわかるかと思います。
単純に特定の記事を選択せず一度クリックしただけなので、一括で全ての記事データをエクスポートができています。
エクスポート時に下図のようにCSVファイルがダウンロードされたはずです。
一括エクスポートは確認できたので、次は記事を選択してからボタンをクリックしてみてください。すると下図のように選択した記事データだけエクスポートできていることが確認できたかと思います。
これで当記事の実装内容の機能の動きを確認することができました。
ただ、このままでは「タイトル」「URL」「日付」の3つがエクスポートされただけとなってしまい、まだまだ改良の余地があるかと思います。
次からは、ご自身のサイト用、自分用に機能をカスタマイズしていきます。
自分用にカスタマイズする
ペーストが完了して機能の動きが確認できたら、次は自分用にカスタマイズしていきます。
現状のままだと、「タイトル」「URL」「日付」の3つがエクスポートされただけとなってしまいます。
より便利にするために項目を増やしたりしてカスタマイズしていきましょう。
カスタマイズが必要な部分は以下になります。
- シートの一行目の項目部分
- データ行の必要な出力処理の部分
- シートの一行目以外のデータ行の部分
それぞれ解説していきます。
シートの一行目の項目部分(データ項目名)
掲載しているサンプルコードの41行目の値の内容をカスタマイズしていきます。
ご確認いただくと以下のコードがあるのが確認できるかと思います。
<?php
// CSVヘッダーを設定
fputcsv($file, array('タイトル', 'URL', '日付'));
fputcsv()関数の第2引数のarray()の中身を自分用に変更してください。
もし仮にサンプルコードのままエクスポートした場合、下図のようなイメージで一行目が出力されます。
そのため、対象のコード部分を以下のようにカッコ「”」で包んだデータ名をカンマ「,」で区切って追加してください。
<?php
// CSVヘッダーを設定
fputcsv($file, array('タイトル', 'URL', '日付', 'カスタムフィールド1', 'カスタムフィールド2', 'カスタムフィールド3'));
上記では、例えば投稿「post」に「カスタムフィールド1」「カスタムフィールド2」「カスタムフィールド3」の3つのテキストカスタムフィールドが追加実装されていることを想定して対応しております。
上記コードに修正して再度CSVエクスポートボタンをクリックして出力結果をご確認いただくと、下図のように項目名がarray()に追加した順番どおりに「カスタムフィールド1」「カスタムフィールド2」「カスタムフィールド3」の3つが、一行目のデータ名に追加されているのが確認できたかと思います。
このようにして、データ名を柔軟に追加して出力することが可能なので、ご自身のサイトに合わせて自由にカスタマイズすることが可能となります。
ただし、この段階ではまだデータの値が出力されておらず、データ名が追加できたところまでしか進んでおりません。
そのため、次はデータの値が出力されるように実装を進めていきます。
シートの一行目以外のデータ行の部分(データの値)
次に掲載しているサンプルコードの53行目の値の内容をカスタマイズしていきます。
ご確認いただくと以下のコードがあるのが確認できるかと思います。
<?php
fputcsv($file, array(get_the_title(), get_the_permalink(), get_the_time("Y/m/d")));
この行の変更のコツとしては、先ほど変更した項目の順番とデータ出力内容の順番を一致させることが重要です。
それでは実際にコードをカスタマイズしてみましょう。
<?php
fputcsv($file, array(get_the_title(), get_the_permalink(), get_the_time("Y/m/d"), get_post_meta($post->ID, 'custom_text1', true), get_post_meta($post->ID, 'custom_text2', true), get_post_meta($post->ID, 'custom_text3', true)));
上記コードは、投稿日の次の部分からカスタムフィールドのデータを取得する関数であるget_post_meta()関数を3つ追加設定し、CSVエクスポート時にデータの値が出力されるようにしております。
サンプルコードでは、3つのカスタムフィールド「custom_text1」「custom_text2」「custom_text3」を想定しており、それぞれget_post_meta($post->ID, ‘custom_text1’, true)関数、get_post_meta($post->ID, ‘custom_text2’, true)関数、get_post_meta($post->ID, ‘custom_text3’, true)関数を追加しております。
コードを修正していただき、CSVエクスポートボタンをクリックしていただければ下図のイメージで無事データの値が出力されます。
ここまでで一連のオリジナルのCSVエクスポート機能の実装は完了しました。
お疲れ様でした!
投稿タイプを変更する方法
CSVエクスポート機能をWordPressデフォルトの投稿「post」以外の投稿タイプ(カスタム投稿タイプ等)に変更する方法について解説したいと思います。
現状、投稿タイプ「投稿」の記事一覧管理画面のみCSVエクスポートボタンが表示されているかと思います。
これを変更するには、サンプルコードの以下の条件分岐の箇所にある「post」をほかの投稿タイプ名に変更します。
<?php
// ボタン追加
function admin_post_list_add_export_button($which) {
// タイプが求人でかつ位置がトップの場合にCSVエクスポートボタンを追加
global $typenow;
if ('post' === $typenow && 'top' === $which) { ?>
↓以下のように修正
<?php
// ボタン追加
function admin_post_list_add_export_button($which) {
// タイプが求人でかつ位置がトップの場合にCSVエクスポートボタンを追加
global $typenow;
if ('custom_post_type' === $typenow && 'top' === $which) { ?>
上記コードでは例として、カスタム投稿タイプ「custom_post_type」という投稿タイプ名がWordPressに実装されているものとして、コードを修正しています。
逆にいうとこれだけで大丈夫です。
コードを修正後、カスタム投稿タイプの記事一覧管理画面をご確認いただき、CSVエクスポートボタンが追加されていることがご確認いただけるかと思います。
複数のチェックボックスのデータの値を出力する場合
ここでは念の為、複数のチェックボックスのデータの値を出力する方法について解説いたします。
WordPressのカスタムフィールドから配列にして値を取得し、その値をカンマ区切りの文字列に変換する処理を実装します。
<?php
$checkbox_value = get_post_meta($post->ID, 'custom_checkbox', false);
// チェックボックスの値をカンマ区切りの文字列に変換
$checkbox_value = is_array($checkbox_value) ? implode(',', $checkbox_value) : 'サンプルテキスト';
まず2行目を解説すると、2行目にあるget_post_meta関数は、指定された投稿のメタデータ(カスタムフィールド)の値を取得します。
この場合、$post->IDで特定の投稿のIDを指定し、’custom_checkbox’というカスタムフィールドの値を取得します。
第三引数のfalse
は、カスタムフィールドの値を配列として返すために使用されます。これにより、複数の値が格納されている場合に配列形式で取得されます。
次に4行目を解説すると、is_array関数を使って、取得したカスタムフィールドの値が配列かどうかを確認します。
もし配列であれば、implode関数を使ってその配列をカンマ区切りの文字列に変換します。
例えば、配列[‘value1’, ‘value2’, ‘value3’]は、カンマ区切りの文字列value1,value2,value3に変換されます。配列でない場合、デフォルト値として’サンプルテキスト’を設定します。
このコードは、カスタムフィールドに複数の値が格納されている場合に、その値をまとめてCSVや他のフォーマットにエクスポートしたり、画面に表示したりする際に役立ちます。
特に、複数選択可能なチェックボックスのフィールドなどで便利です。この変換により、データの扱いが簡単になり、一貫性のある形式で出力することが可能になります。
容量が重くてエクスポートができない場合の対処法
当記事のCSVエクスポート機能を実装して実際にエクスポートをした際に容量が重すぎてエクスポートができない場合があります。
この時に必要な対応方法についてここで解説させていただきます。
結論、サーバーにあるPHPの設定ファイルであるphp.iniの内容に以下を追加、もしくは修正してください。
memory_limit:1G
post_max_size:1G
内容としては、「memory_limit」と「post_max_size」になります。
ここでは例として両方とも「1G」にしておりますが、ご自身のサイトの状況に合わせて数値を設定してください。
それぞれ解説いたします。
memory_limitとは
memory_limitディレクティブは、PHP スクリプトが使用できる最大メモリ量を設定します。
ここでは、1G
と指定されており、PHP スクリプトが最大で 1 ギガバイトのメモリを使用できるようになります。
大規模な操作やメモリを多く消費する処理を行う場合に便利です。
post_max_sizeとは
post_max_sizeディレクティブは、HTTP POSTリクエストで送信されるデータの最大サイズを制限します。
投稿データがこのサイズを超える場合、データは切り捨てられます。
ここでは、1G
と指定されているため、HTTP POST リクエストのデータサイズが最大で 1 ギガバイトに制限されます。
上記の設定が完了すれば、エクスポートボタンクリック時にエラーになってしまうところを解決でき、エクスポートできるようになります。
まとめ
プラグインなしで投稿タイプ(記事)データを一括でCSVエクスポートする機能を実装する方法についての解説は以上になります。
当記事を読んでいただくことで、投稿データ(記事データ)を一括もしくは特定の記事を選択してCSVとして自由自在にダウンロード(エクスポート)する機能を実装することができます。
筆者自身これまでの実際のお仕事での経験上、クライアントから当記事の実装内容のご要望が頻繁にありましたため、クライアントの需要に応えられる実装内容の構成となっております。
よろしければぜひ沢山ご活用いただけましたら幸いです。
お気軽に皆さんのご要望をお聞かせください!
どんなに些細なことでも構いません!よろしければ記事や当サイトへの「こんな記事があったら仕事とかで役に立つな〜」や「こうだったらもっと役に立つのに!」といったようなご要望等をお気軽にお聞かせください!今後のサービス改善にお役立てさせていただきます!
例1)Reactの技術記事を書いてほしい!
例2)WordPressの使い方とかを初心者向けに解説してほしい!...など