Web画面からS3のファイルを直接ダウンロードする

Lambda関数で生成するプリサインドURLを利用してS3のファイルをダウンロードする処理の作成手順です。

![image](https://user-images.githubusercontent.com/38905609/180635372-6feca747-db96-4121-b0af-5468a8c884cb.png)

## 手順の流れ

- ダウンロードURLを作成する `AWS Lambda 関数` を作成します。
- 生成したURLを画面へ出力します。

## ダウンロードURLを作成する `AWS Lambda 関数` を作成します

👇これより先は下記記事の内容を前提とします  
[Web画面からS3へ直接ファイルアップロードする](https://docusaurus.plant11.com/angular/S3_upload)

- `generate_presigned_url`でダウンロードURLを生成します。

```python
import json
import boto3
import traceback
import os

from botocore.client import Config

def main_logic(prefix):
    ret = []
    client = boto3.client('s3', region_name="ap-northeast-1", config=Config(signature_version='s3v4'))
    bucket_name = "your.bucket.name.xxxxxxxxxxxx"
    response = client.list_objects_v2(Bucket=bucket_name, Prefix=prefix)
    if 'Contents' in response:
      contents = response['Contents']
      for content in contents:
        if content['Size'] > 0:
            finfo = {}
            finfo['name'] = content['Key'].split('/')[-1]
            finfo['size'] = int(content['Size'] / 1024)
            download_url = client.generate_presigned_url(
                ClientMethod = "get_object",
                Params = {"Bucket" : bucket_name, "Key" : content['Key']},
                HttpMethod = "GET"
            )
            finfo['download_url'] = download_url
            ret.append(finfo)
    return ret

def lambda_handler(event, context):
    return_data = main_logic("upload_files/")
    return {
        'statusCode': 200,
        'headers': {
            'Access-Control-Allow-Origin': '*'
        },
        'body': json.dumps(return_data)
    }
```

## 生成したURLを画面へ出力します

`common.service.ts`

```ts
  public fileInfoList = [];
  createFileInfoList(){
    let httpHeaders = new HttpHeaders({
      'Content-Type' : 'application/json',
    });
    let options = {
      headers: httpHeaders,
    };
    let url = "https://api.xxxxxxxxxxxxxx/v1";
    this.http.get<any>(url, options).subscribe({
      next:(data) => {
        console.log("OK");
        console.log(data);
        this.fileInfoList = data;
      },
      error:(e) =>{
        console.log("NG");
        console.error(e);
      },
      complete: () => {
        console.log("complete");
      }
    })
  }
```

`main.component.ts`

```ts
  ngOnInit(): void {
    this.commonService.createFileInfoList();
  }
```

`main.component.html`

```html
    <mat-list>
      <mat-list-item *ngFor="let info of commonService.fileInfoList">
        <mat-icon>note</mat-icon>
        &nbsp;
        {{info["name"]}}
        &nbsp;
        {{info["size"]}}
        kb
        &nbsp;
        <a href="{{info['download_url']}}" download target="_blank">
          <mat-icon>file_download</mat-icon>
        </a>
      </mat-list-item>
    </mat-list>
```

## 👇前提記事

- [Angular Material 標準コンポーネント構成の作成](https://docusaurus.plant11.com/angular/base_components)
- [REST API としてAWS Lambda関数を呼び出す](https://docusaurus.plant11.com/AWS/apigateway_lambda)
- [Web画面からS3へ直接ファイルアップロードする](https://docusaurus.plant11.com/angular/S3_upload)

## 👇関連記事

- [Angular Material datepicker 導入](https://docusaurus.plant11.com/angular/datepicker)
- [Angular Material Progress spinner 導入](https://docusaurus.plant11.com/angular/spinner)
- [StackBlitzの導入からGitHub同期まで](https://docusaurus.plant11.com/tips/StackBlitz)
- [Angular Material 動的Tree 導入](https://docusaurus.plant11.com/angular/dynamic_tree)

## 👇GitHubはこちら

- <https://github.com/jun-knd/material.angular.github/tree/upload_download>
[![image](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/jun-knd/material.angular.github/tree/upload_download)

## 👇参考URL

- [HTTPによるバックエンドサービスとの通信](https://angular.jp/guide/http)
- [Cross−Origin Resource Sharing (CORS) の使用](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/cors.html)

[keywords]
Angular S3 download