FlaskとVue.jsを使用してExcelエクスポート機能を実装する

##### フロントエンド部分: ###### 1. APIのラッピング:src/api/volunteer.jsファイルに記述 ###### 注意:必ず"responseType: 'blob'"を指定してください。これがないとファイルを開く際に文字化けや開けない問題が発生します。

import request from "@/utils/request";

// エクスポート処理
export function downloadVolunteerData(params) {
    return request({
        method: 'post',
        url: '/volunteer/export_excel',
        data: params,
        responseType: 'blob'
    });
}
###### 2. API呼び出し:src/views/volunteer.vueファイルに記述

// エクスポートボタンクリック時のハンドラ
async handleExport() {
    try {
        // エクスポートAPIを呼び出す
        const response = await downloadVolunteerData();
        // Excelファイルの作成とダウンロード
        const excelBlob = new Blob([response.data], { type: 'application/vnd.ms-excel;charset=utf-8' });
        const downloadUrl = window.URL.createObjectURL(excelBlob);
        const anchorElement = document.createElement('a');
        anchorElement.href = downloadUrl;
        anchorElement.setAttribute('download', 'volunteer_report.xls');
        document.body.appendChild(anchorElement);
        anchorElement.click();
        document.body.removeChild(anchorElement);
        window.URL.revokeObjectURL(downloadUrl);
    } catch (error) {
        console.error('エクスポートエラー:', error);
    }
}
##### バックエンド部分: ###### 方法1:バックエンドに保存せずに直接フロントエンドに返す

import io
import xlwt
from flask import make_response
from flask_backend.models import Volunteer

@volunteer_blue.route('/export_excel', methods=['POST'])
def export_volunteer_data():
    workbook = xlwt.Workbook()
    worksheet = workbook.add_sheet('Volunteer Report')
    column_widths = [128*20, 230*20, 230*20, 128*20, 230*20, 230*20, 230*20]
    headers = ["ID", "Name", "Gender", "ID Card", "Phone", "Check Status", "Register Time"]
    for col_idx, width in enumerate(column_widths):
        worksheet.col(col_idx).width = width
    for row_idx, header in enumerate(headers):
        worksheet.write(0, row_idx, header)

    volunteers = Volunteer.query.order_by(Volunteer.id).all()
    for idx, volunteer in enumerate(volunteers, start=1):
        register_time = volunteer.register_time.strftime('%Y-%m-%d %Z %H:%M:%S') if volunteer.register_time else ''
        check_status = 'Approved' if volunteer.check_status == 1 else 'Pending' if volunteer.check_status == 0 else ''
        worksheet.write(idx, 0, volunteer.id)
        worksheet.write(idx, 1, volunteer.name)
        worksheet.write(idx, 2, volunteer.gender)
        worksheet.write(idx, 3, volunteer.id_card)
        worksheet.write(idx, 4, volunteer.phone)
        worksheet.write(idx, 5, check_status)
        worksheet.write(idx, 6, register_time)

    output = io.BytesIO()
    workbook.save(output)
    output.seek(0)
    response = make_response(output.getvalue())
    response.headers['Content-Type'] = 'application/vnd.ms-excel'
    response.headers['Content-Disposition'] = 'attachment; filename="volunteer_report.xls"'
    return response
###### 方法2:バックエンドに一時的に保存してからフロントエンドに返す

import os
import time
import xlwt
from flask import send_file, make_response
from flask_backend.models import Volunteer

@volunteer_blue.route('/export_excel', methods=['POST'])
def export_volunteer_data():
    workbook = xlwt.Workbook()
    worksheet = workbook.add_sheet('Volunteer Report')
    column_widths = [128*20, 230*20, 230*20, 128*20, 230*20, 230*20, 230*20]
    headers = ["ID", "Name", "Gender", "ID Card", "Phone", "Check Status", "Register Time"]
    for col_idx, width in enumerate(column_widths):
        worksheet.col(col_idx).width = width
    for row_idx, header in enumerate(headers):
        worksheet.write(0, row_idx, header)

    volunteers = Volunteer.query.order_by(Volunteer.id).all()
    for idx, volunteer in enumerate(volunteers, start=1):
        register_time = volunteer.register_time.strftime('%Y-%m-%d %Z %H:%M:%S') if volunteer.register_time else ''
        check_status = 'Approved' if volunteer.check_status == 1 else 'Pending' if volunteer.check_status == 0 else ''
        worksheet.write(idx, 0, volunteer.id)
        worksheet.write(idx, 1, volunteer.name)
        worksheet.write(idx, 2, volunteer.gender)
        worksheet.write(idx, 3, volunteer.id_card)
        worksheet.write(idx, 4, volunteer.phone)
        worksheet.write(idx, 5, check_status)
        worksheet.write(idx, 6, register_time)

    timestamp = str(int(time.time()))
    directory = os.path.join(os.path.dirname(__file__), 'static', 'excel')
    if not os.path.exists(directory):
        os.makedirs(directory)
    file_name = f'volunteer_report_{timestamp}.xls'
    file_path = os.path.join(directory, file_name)
    workbook.save(file_path)

    response = make_response(send_file(file_path, as_attachment=True))
    response.headers['Content-Type'] = 'application/vnd.ms-excel'
    response.headers['Content-Disposition'] = f'attachment; filename="{file_name}"'
    return response

タグ: flask vue.js xlwt ExcelExport

9月6日 14:31 投稿