0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LambdaでExcelファイルをエクスポートすると文字化けしてしまう

Posted at

はじめに

バックエンドにLambdaを使用しているのですが、Excelファイルをそのまま返却しようとすると文字化けしてしまうエラーが発生しましたので、解消方法を記載しておきます。

対象者

この記事は下記のような人を対象にしています。

  • PythonのopenpyxlでExcelファイルを作成している
  • Lambdaを使用している

結論

Base64エンコードを使用します。

【サーバー側】

excel.py
import openpyxl
import base64
import tempfile
import json


def export_excel():
    wb = openpyxl.Workbook()
    # ここでシートにデータを書き込む

    with tempfile.NamedTemporaryFile(delete=False, suffix=".xlsx") as tmpfile:
        wb.save(tmpfile.name)
    with open(tmpfile.name, "rb") as excel_file:
        # Lambdaの場合エンコード処理が必要
        encoded_content = base64.b64encode(excel_file.read()).decode()

    response = {
        "headers": {
            "Content-Type": "application/json",
        },
        "body": json.dumps(
            {
                "data": encoded_content,
                "headers": {
                    "Content-Disposition": "attachment; filename=filename.xlsx"
                },
            }
        ),
    }

    return response

【フロントエンド側】

exportExcel.ts
import axios from 'axios'

const exportExcel = async () => {
  try {
    const response = await axios.get(`https://sample.com/excel`)
    const responseBody = JSON.parse(response.data.body)
    const encodedContent = responseBody.data
    const blob = b64toBlob(
      encodedContent,
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    )
    const url = window.URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.setAttribute('download', 'filename.xlsx')

    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
    window.URL.revokeObjectURL(url)
  } catch (error) {
    throw new Error(`${error as string}`)
  }
}

function b64toBlob(b64Data: string, contentType: string): Blob {
  const byteCharacters = atob(b64Data)
  const byteArrays = []

  for (let offset = 0; offset < byteCharacters.length; offset += 512) {
    const slice = byteCharacters.slice(offset, offset + 512)
    const byteNumbers = new Array(slice.length)

    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i)
    }

    const byteArray = new Uint8Array(byteNumbers)
    byteArrays.push(byteArray)
  }

  return new Blob(byteArrays, { type: contentType })
}

おわりに

LambdaでExcelファイルをエクスポートすると文字化けしてしまうエラーの解消方法についてまとめました。

参考記事

AWS Lambdaで遊ぼう(第6話: Excelをダウンロード)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?