2024_Hello_World
@2024_Hello_World

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【初心者】CSV出力

解決したいこと

現在CSV出力機能を作成しています。
バックエンドで作成されたCSVをフロントエンドでAPIが呼ばれたときに出力させたいです。
しかし、その出力ができておりません。
バックエンド側の処理は変えずに済む解決方法を教えてください。

(補足)
バックエンド側でAPIたたくだけでブラウザにダウンロードされるようにしたいです。

使用技術 vue.js,TypeScript

バックエンド(サービスクラス)
・ここでCSVを作ってBase64エンコードにしてしているようです。


  const csvFileValue = {migration}
  const csvFolderName: string = 'migration' '_' + generateUUID();
  const csvFileName: string = 'migration'+ '_' + getCurrentTime() + '.csv';
  // NOTE: csvFileValueは必ず1件のデータを持つため、配列に変換して渡す
  await createCsvbyObject(csvFolderName, csvFileName, csvFileHeader, [csvFileValue]);
  const binaryData = fs.readFileSync(path.join('/tmp', csvFolderName, csvFileName));
  const base64Data = Buffer.from(binaryData).toString('base64');
  return { csvFileName, base64Data };
};

// 疑似uuid生成
// TODO:npm install uuid
function generateUUID(): string {
  const timestamp = Date.now().toString(16);
  const randomHex = Math.floor(Math.random() * 0xffffff).toString(16);
  return `${timestamp}-${randomHex}`;
}

//現在時刻取得(yyyymmddhhmmss)
function getCurrentTime() {
  const now = new Date();
  const res =
    '' +
    now.getFullYear() +
    padZero(now.getMonth() + 1) +
    padZero(now.getDate()) +
    padZero(now.getHours()) +
    padZero(now.getMinutes()) +
    padZero(now.getSeconds());
  return res;
}

//先頭ゼロ付加
function padZero(num: number) {
  return (num < 10 ? '0' : '') + num;
}

バックエンド(関数クラス) サービスの関数をここで呼んでいます

const baseHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
  try {
    const requestId = Number(event.pathParameters?.requestId);

    if (!event.pathParameters?.requestId) {
      return createResponse(JSON.stringify({ error: 'Invalid or missing requestId' }));
    }

    const result = await getMigration(requestId);

    return createResponse(JSON.stringify(result));
  } catch (error) {
    if (error instanceof Error) {
      return createResponse(JSON.stringify({ error: error.message }));
    }
    return createResponse(JSON.stringify({ error: '予期せぬエラーが発生しました。' }));
  }
};

export const lambdaHandler = middy(baseHandler).use(httpErrorHandlerMiddleware());

フロントエンド(APIを呼びだし)レスポンスの中にはcsvFIleNameは見当たらず...


 /**
   * postMigrationItem
   * @description csvをダウンロード
   * @param requestId
   * @returns { Promise<void>}
   */
  const postMigrationItem = async (requestId: number | null): Promise<void> => {
    try {
      const response = await apiClient.post(`/migration/file/${requestId}`)
      console.log('response:', response)
      return response.data
    } catch (error: unknown) {
      throw new Error('postMigrationItemでエラーが発生しました。')
    }
  }


スクリーンショット 2024-11-18 171749.png

フロントエンド(CSVを出力ビジネスロジッククラス) できればバックエンドで作成したCSVをそのまま出力したいですが...

 /**
   * handleExportButtonClick
   * @description CSV出力ボタン押下
   */
  const handleExportButtonClick = async (): Promise<void> => {
    const migrationFile = await postMigrationItem(requestId.value)
    console.log('migrationFile:', migrationFile)
    // Base64データをデコード
    const binaryString = atob(migrationFile.base64Data)
    const binaryLen = binaryString.length
    const bytes = new Uint8Array(binaryLen)
    for (let i = 0; i < binaryLen; i++) {
      bytes[i] = binaryString.charCodeAt(i)
    }

    // Blobオブジェクトを作成
    const blob = new Blob([bytes], { type: 'text/csv;charset=utf-8;' })
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.setAttribute('href', url)
    link.setAttribute('download', migrationFile.csvFileName)
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)

    closeModal()
  }
0

No Answers yet.

Your answer might help someone💌