💭

【備忘録】sveltekit+xlsでエクセルファイルの取得と送信を実装してみた

2024/10/16に公開

sveltekitでファイルダイアログで取得したxlsxファイルをバックエンドに送信するコードです。
page.svelte

<script lang="ts">
	import { onMount } from 'svelte';
	let sheetNames: string[] = [];
	let selectedFile: File | null = null;
  
	// ファイルが選択されたときに実行される
	function handleFileInput(event: Event) {
	  const input = event.target as HTMLInputElement;
	  if (input.files && input.files[0]) {
		selectedFile = input.files[0];
	  }
	}
  
	// POSTリクエストでファイルをバックエンドに送信
	async function uploadFile() {
	  if (!selectedFile) {
		alert('ファイルを選択してください');
		return;
	  }
  
	  const formData = new FormData();
	  formData.append('file', selectedFile);
  
	  try {
		const response = await fetch('/api/upload', {
		  method: 'POST',
		  body: formData
		});
  
		if (response.ok) {
		  const data = await response.json();
		  sheetNames = data.sheetNames;
		} else {
		  alert('ファイルのアップロードに失敗しました');
		}
	  } catch (error) {
		console.error('エラー:', error);
		alert('サーバーとの通信でエラーが発生しました');
	  }
	}
  </script>
  
  <h1>Excel シート選択</h1>
  
  <input type="file" accept=".xlsx" on:change={handleFileInput} />
  <button on:click={uploadFile}>アップロード</button>
  
  {#if sheetNames.length > 0}
	<label for="sheets">シートを選択してください:</label>
	<select id="sheets">
	  {#each sheetNames as sheet}
		<option value={sheet}>{sheet}</option>
	  {/each}
	</select>
  {/if}
  

+server.ts

import { json, type RequestHandler } from '@sveltejs/kit';

import * as xlsx from 'xlsx';

export const POST: RequestHandler = async ({ request }) => {
  const data = await request.formData();
  const file = data.get('file') as Blob;

  if (!file) {
    return json({ error: 'ファイルが見つかりません' }, { status: 400 });
  }

  try {
    // バイナリデータとしてファイルを読み込む
    const buffer = await file.arrayBuffer();
    const workbook = xlsx.read(buffer, { type: 'array' });

    // シート名を取得
    const sheetNames = workbook.SheetNames;

    return json({ sheetNames });
  } catch (error) {
    console.error('エラー:', error);
    return json({ error: 'ファイルの処理に失敗しました' }, { status: 500 });
  }
};


Discussion