GoogleスプレッドシートをExcelファイルでダウンロードします。またアップロードしたExcelファイルでGoogleスプレッドシートに書き込みます。
動作確認はこちらから
今回はExcelファイルのデータをGoogleスプレッドシートに書き込んでみます。
前回同様にGoogle Cloud PlatformにおけるProjectの作成、Google Sheet APIの有効化、サービスアカウントの作成と認証情報を含んだJSONファイルのダウンロードをしておく必要があります。前回のダウンロードしたJSONファイルをそのまま使ってもかまいません。
最初にGoogleスプレッドシートのデータをExcelファイルとしてダウンロードする処理をやってみましょう。
excelファイルをphpで扱うにはphpspreadsheetが必要です。composerがインストールされているのであればコマンドラインから
|
composer require phpoffice/phpspreadsheet |
これでインストール完了です。ファイル数は900個くらい。サイズは6MBくらいです。これを前回使用したGoogle Api Clientのフォルダといっしょにサーバーにアップロードしておきます。ワードプレスがインストールされているディレクトリのなかにsampleというディレクトリを作成し、そのなかへアップロードしました。
sampleディレクトリのなかにspreadsheet-excelというディレクトリをつくり、そのなかに以下のようなファイルを作成します。
これはスプレッドシートのA1:E5の範囲を取得し、excelファイルとしてダウンロードするためのコードです。
download.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
<?php $spreadsheet_id = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; $sheetName = "シート名"; $keyFile = __DIR__. "/XXXX.json"; // ダウンロードしたファイルを指定する require '../google-api-php-client/vendor/autoload.php'; require '../phpspreadsheet/vendor/autoload.php'; // アカウント認証情報インスタンスを作成 $client = new Google_Client(); $client->setAuthConfig($keyFile); //任意名 $client->setApplicationName("Sheet API TEST"); //サービスの権限スコープ $scopes = [Google_Service_Sheets::SPREADSHEETS]; $client->setScopes($scopes); //シート情報を操作するインスタンスを生成 $sheet = new Google_Service_Sheets($client); $range = $sheetName.'!A1:E5'; // 取得する範囲 $response = $sheet->spreadsheets_values->get($spreadsheet_id, $range); $values = $response->getValues(); $excel_book = new \PhpOffice\PhpSpreadsheet\Spreadsheet(); $excel_sheet = $excel_book->getSheet(0); //fromArray(セットする配列, セットしない値, 開始場所のセル) $excel_sheet->fromArray($values, null, 'A1'); header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition: attachment;filename="myfile.xlsx"'); header('Cache-Control: max-age=0'); $writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($excel_book); $writer->save('php://output'); |
アップロードしたphpファイルにアクセスするとスプレッドシートの内容がexcelファイルとしてダウンロードされます。注意する点としてecho文でどのようなデータが取得できるか表示させてみたいのですが、これをするとダウンロードされるファイルに変更が加えられ、開こうとしてもうまくいかなくなることです。余計なものは出力してはいけません。
つぎにexcelファイルをアップロードして、このデータをスプレッドシートに追加する方法を考えます。
まずはindex.htmlを作成します。Downloadリンクをクリックすると上記のダウンロードの処理が実行されます。アップロードするとup.phpにかかれている処理が実行されます。
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>GoogleスプレッドシートとExcelファイル</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <p>スプレッドシートをExcelファイルに変換してダウンロードする<br /> <a href="download.php" target="_blank" rel="noopener">Download</a></p> <form action="up.php" method="post" enctype="multipart/form-data"> <input type="file" name="fname"> <input type="submit" value="UPLOAD"> </form> </body> </html> |
アップロードするとup.phpにかかれている処理が実行されるのですが、どのような処理が実行されるのでしょうか?
ファイルをアップロードすると自作のgetValueArray関数によってファイルのデータが配列として取得され、setDataToSpreadsheet自作関数によって配列がスプレッドシートに書き込まれます。
up.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
<?php $tempfile = $_FILES['fname']['tmp_name']; $filename = './' . $_FILES['fname']['name']; $spreadsheet_id = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; $sheetName = "シート名"; $keyFile = __DIR__. "/XXXX.json"; // ダウンロードしたファイルを指定する if (is_uploaded_file($tempfile)) { if ( move_uploaded_file($tempfile , $filename )) { try{ $array = getValueArray($filename); setDataToSpreadsheet($spreadsheet_id, $SheetName, $array); unlink($filename); echo "書き込みました。"; } catch (\Exception $e){ unlink($filename); echo "処理はできませんでした。"; } } else { echo "ファイルをアップロードできません。"; } } else { echo "ファイルが選択されていません。"; } // getValueArray関数とsetDataToSpreadsheet関数は後述 |
ファイルのデータが配列として取得するgetValueArray関数を示します。
取得したデータがnullのとき書き込み処理でエラーになるので空白文字をいれています。
up.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
function getValueArray($filename) { require '../phpspreadsheet/vendor/autoload.php'; $filePath = $filename; $reader = new PhpOffice\PhpSpreadsheet\Reader\Xlsx(); $excel_book = $reader->load($filePath); $excel_sheet = $excel_book->getSheet(0); $str = ""; $array1 = array(); foreach( $excel_sheet->getRowIterator() as $row ){ $array2 = array(); foreach( $excel_sheet->getColumnIterator() as $column ){ $str = $excel_sheet->getCell( $column->getColumnIndex().$row->getRowIndex() )->getValue(); if($str != null) $array2[] = $str; else $array2[] = ""; } $array1[] = $array2; } return $array1; } |
次にsetDataToSpreadsheet関数を示します。
up.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
function setDataToSpreadsheet($spreadsheet_id, $SheetName, $array){ require '../google-api-php-client/vendor/autoload.php'; $keyFile = __DIR__. "/my-project-php-sheet-2a593b2e9368.json"; // ダウンロードしたファイルを指定する // アカウント認証情報インスタンスを作成 $client = new Google_Client(); $client->setAuthConfig($keyFile); //任意名 $client->setApplicationName("Sheet API TEST"); //サービスの権限スコープ $scopes = [Google_Service_Sheets::SPREADSHEETS]; $client->setScopes($scopes); //シート情報を操作するインスタンスを生成 $spreadsheet_service = new Google_Service_Sheets($client); $range = $SheetName.'!A1'; $body = new \Google_Service_Sheets_ValueRange([ 'values' => $array ]); $params = ['valueInputOption' => 'USER_ENTERED']; $result = $spreadsheet_service->spreadsheets_values->append($spreadsheet_id, $range, $body, $params); } |
鳩でも分かるC#管理人からのお願い
できる仕事であれば請け負います。鳩でもわかるC#管理人はクラウドワークスに在宅ワーカーとして登録しています。お仕事の依頼もお待ちしております。
⇒ 仕事を依頼する
コメントについて
コメントで英語などの外国語でコメントをされる方がいますが、管理人は日本語以外はわからないので基本的に内容が理解できず、承認することもありません。それからへんな薬を売っているサイトやリンク先のサイトが存在しないというスパムコメントも多々あります。
Some people make comments in foreign languages such as English, but since the manager does not understand anything other than Japanese, he basically cannot understand the content and does not approve it. Please use Japanese when making comments.
そんななか日本語のコメントもいただけるようになりました。「○○という変数はどこで宣言されているのか?」「××というメソッドはどこにあるのか」「例外が発生する」「いっそのことソース丸ごとくれ」という質問ですが、管理人としては嬉しく思います。「自分が書いた記事は読まれているんだな」と。疑問点には可能な限り答えます。記事に問題があれば修正いたします。
そのうえでお願いがあります。「匿名」という味も素っ気もない名前ではなく、捨てハンでいいのでなにかハンドルネームをつくってほしいと思います。
管理人のモチベーションアップのために
よろしければご支援お願いします。
⇒ 管理人の物乞いリスト