PHPWordを使ってみた【後編】

#はじめに
本記事は前回の続きになりますので、ぜひそちらもご覧になっていただけたら幸いです。
[PHPWordを使ってみた](https://qiita.com/wdsh523/items/8cc0c86a6c2e264cfb77)

#GoogleドライブにWordファイルをアップロード
作成したWordファイルをせっかくならGoogleドライブにアップロードして他の人とも共有したい、
ということで、以下の記事を参考にGCP（Google Cloud Platform）の設定からファイルアップロードまでを行いました。
[【PHP】Laravelを使ってGoogleドライブにファイルをアップロードしてみる](https://qiita.com/kazama1209/items/94db0ff9d10df249bf14)

#Googleドライブにフォルダを作成
Wordファイルのアップロード先は

```
   $fileMetadata = new Google_Service_Drive_DriveFile([
      'name' => '◯◯◯◯◯◯◯◯', // Googleドライブへアップロードされた際のファイル名
      'parents' => ['××××××××'], // 保存先のフォルダID
   ]);
```
parentsの指定によって変わりますが、GoogleDriveApiを使ってフォルダを作り、そのURLを取得してparentsに動的に格納できれば、Wordファイル作成からアップロードまでの流れが自動化できて最高ですよね！
ということで、コードの実装を行なっていきます。

####フォルダの作成

```
   $google = new Google_Client();
   // サービスアカウント作成時にダウンロードしたJSONファイルを、configフォルダ内に設置
   $keyFile = config('googleApi_json');
   $google->setAuthConfig($keyFile);
   $google->setScopes([Google_Service_Drive::DRIVE]);
   $service = new Google_Service_Drive($google);
   // フォルダの作成
   $folderMetadata = new Google_Service_Drive_DriveFile([
      'name' => '', // Googleドライブへアップロードされた際のフォルダ名
      'mimeType' => 'application/vnd.google-apps.folder', // フォルダタイプを指定
      'parents' => [''], // 保存先のフォルダID
   ]);
   $options = [
      'fields' => 'id',
      'supportsTeamDrives' => true,
   ];
   $folder = $service->files->create($folderMetadata, $options);
   $folderUrl = 'https://drive.google.com/drive/u/0/folders/'.$folder['id'];
```

####作成したフォルダにファイルをアップロード

```
   $google = new Google_Client();
   // サービスアカウント作成時にダウンロードしたJSONファイルを、configフォルダ内に設置
   $keyFile = config('googleApi_json');
   $google->setAuthConfig($keyFile);
   $google->setScopes([Google_Service_Drive::DRIVE]);
   $service = new Google_Service_Drive($google);
   // フォルダの作成
   $folderMetadata = new Google_Service_Drive_DriveFile([
      'name' => '', // Googleドライブへアップロードされた際のフォルダ名
      'mimeType' => 'application/vnd.google-apps.folder', // フォルダタイプを指定
      'parents' => [''], // 保存先のフォルダID
   ]);
   $folderOptions = [
      'fields' => 'id',
      'supportsTeamDrives' => true,
   ];
   $folder = $service->files->create($folderMetadata, $folderOptions);

   // 以下を追加
   $folderUrl = 'https://drive.google.com/drive/u/0/{××××××××}/'.$folder['id']; //フォルダのURLを取得（{××××××××}の例としてmy-driveなど）
   // ファイルのアップロード
   $fileMetadata = new Google_Service_Drive_DriveFile([
      'name' => '', // Googleドライブへアップロードされた際のファイル名
      'mimeType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // ファイルタイプの指定
      'parents' => [$folder['id']], // 保存先のフォルダID（先ほど作成したフォルダのID）
   ]);
   $fileOptions = [
      'data' => file_get_contents(''), // アップロード対象となるファイルのパス
      'uploadType' => 'multipart',
      'fields' => 'id',
   ];
   $file = $service->files->create($fileMetadata, $fileOptions);
```

こうして、フォルダの作成からファイルアップロードまでが行えるようになります。

#テンプレートファイルの読み込みと編集
本記事前編ではPHPWordを使ってWordファイルの作成を行いましたが、10種類近くのファイル作成を行い、コードを確認したところ、4000行を超えていました、、、
テンプレートが存在しない場合はやむなしですが、存在するのであれば、それを読み込み編集することで、コードの量を減らすことができます。
ということで、コードの実装を行なっていきます。

```
   $template = new \PhpOffice\PhpWord\TemplateProcessor('××××××××.docx'); // テンプレートファイルの読み込み
   $user_name = 'テスト';
   $template->setValue('user_name', $user_name); // Wordファイルの${user_name}に$user_nameを格納

   // Wordファイルの作成
   header("Content-Description: File Transfer");
   header('Content-Disposition: attachment; filename="○○○○○○○○.docx"'); // 作成時のWordファイルを設定
   header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
   header('Content-Transfer-Encoding: binary');
   header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
   header('Expires: 0');
   ob_end_clean(); //バッファ消去
   $template->saveAs('○○○○○○○○.docx');
```

なお、ここで1つ問題があり、下画像のように、テンプレートファイルに${変数名}を書くだけでは動的に値が入りません、、、
![スクリーンショット 2021-06-28 9.24.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1575624/5b6ee85a-a4aa-c5cf-3d9b-47e4d72cb392.png)
そこで、docxを一度xmlファイルに変換します。
そして、xmlに存在する以下の1行を

```
   ${</w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:t>user_name</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:t>}
```
このように変更します。

```
   ${user_name}
```
xmlファイルを編集して保存した後に、再度docxファイルに変換し直すことで、$user_nameの値が動的に入り、最終的に以下のように読み込んだファイルの修正を行うことができました。
![スクリーンショット 2021-06-28 9.37.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1575624/580a4c03-0e47-f561-8141-5deb82cfe0ff.png)

#まとめ
今回は、Googleドライブ生成、フォルダにWordファイルのアップロードと、Wordのテンプレートファイルを読み込んで修正を行いました。