WEB

[WEB] Nuxt.js와 Spring을 이용한 POI Excel 파일 업로드 및 처리

TaeHuiLee 2024. 11. 27. 15:58
반응형

이번 글에서는 프론트엔드에서 업로드된 Excel 파일Spring 백엔드에서 받아서 Apache POI로 처리하는 방법을 알아보겠습니다. 업로드된 파일을 어떻게 서버에서 다룰 수 있는지 Spring MVCApache POI를 활용하여 구현합니다.


전체 구현 개요

  1. 프론트엔드
    • Nuxt.js를 통해 파일을 업로드.
    • 서버로 HTTP POST 요청을 보냄.
  2. 백엔드
    • Spring Controller에서 파일을 받음.
    • MultipartFile 객체로 업로드된 파일 처리.
    • Apache POI로 Excel 데이터를 읽고 출력 또는 가공.
  3. 처리된 데이터
    • 데이터베이스 저장 또는 JSON 응답 반환.

1. 프론트엔드: Nuxt.js로 파일 업로드 구현

Nuxt.js는 Vue.js 기반으로 작동하기 때문에 파일 업로드는 Vue의 기본 이벤트 처리 방식을 사용합니다. 아래는 Nuxt.js에서 파일 업로드를 구현하는 코드입니다.

🌟 업로드 UI 생성 (Nuxt 페이지 컴포넌트)

pages/upload.vue에 아래 코드를 작성합니다.

<template>
  <div>
    <h1>Excel 파일 업로드</h1>
    <form @submit.prevent="handleFileUpload">
      <input type="file" @change="onFileChange" accept=".xlsx, .xls" />
      <button type="submit">업로드</button>
    </form>
    <div v-if="uploadResult">
      <h2>업로드 결과:</h2>
      <pre>{{ uploadResult }}</pre>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      file: null, // 선택한 파일
      uploadResult: null, // 서버에서 받은 응답 데이터
    };
  },
  methods: {
    // 파일 선택 핸들러
    onFileChange(event) {
      this.file = event.target.files[0];
    },
    // 파일 업로드 처리
    async handleFileUpload() {
      if (!this.file) {
        alert("파일을 선택해주세요!");
        return;
      }

      // FormData 생성
      const formData = new FormData();
      formData.append("file", this.file);

      try {
        const response = await this.$axios.post("/upload", formData, {
          headers: { "Content-Type": "multipart/form-data" },
        });
        this.uploadResult = response.data;
      } catch (error) {
        console.error("업로드 실패:", error);
        alert("업로드 중 오류가 발생했습니다.");
      }
    },
  },
};
</script>

🌟 Nuxt Axios 설정

Nuxt.js에서 파일 업로드를 처리하기 위해 @nuxtjs/axios 모듈을 사용합니다. nuxt.config.js 파일에 Axios 설정을 추가합니다.

export default {
  modules: ["@nuxtjs/axios"],
  axios: {
    baseURL: "http://localhost:8080", // Spring 백엔드 URL
  },
};

2. 백엔드: Spring 파일 업로드 처리

Spring에서 Nuxt.js로부터 전달받은 파일을 처리하는 방법입니다.

🌟 Controller: 파일 업로드 처리

Nuxt.js가 보낸 파일을 @RequestParam으로 받습니다. MultipartFile 객체를 사용하여 파일 내용을 처리합니다.

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@RestController
public class ExcelController {

    @PostMapping("/upload")
    public List<List<String>> uploadExcel(@RequestParam("file") MultipartFile file) {
        List<List<String>> excelData = new ArrayList<>();

        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = new XSSFWorkbook(inputStream)) {

            // 첫 번째 시트 읽기
            Sheet sheet = workbook.getSheetAt(0);
            for (Row row : sheet) {
                List<String> rowData = new ArrayList<>();
                for (Cell cell : row) {
                    switch (cell.getCellType()) {
                        case STRING:
                            rowData.add(cell.getStringCellValue());
                            break;
                        case NUMERIC:
                            rowData.add(String.valueOf(cell.getNumericCellValue()));
                            break;
                        case BOOLEAN:
                            rowData.add(String.valueOf(cell.getBooleanCellValue()));
                            break;
                        default:
                            rowData.add(" ");
                    }
                }
                excelData.add(rowData);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return excelData; // JSON으로 반환
    }
}

🌟 Spring 설정: CORS 지원

Nuxt.js와 Spring이 다른 포트를 사용하므로, CORS 설정이 필요합니다. 예를 들어, Spring에서 모든 도메인의 요청을 허용하려면 아래 코드를 추가합니다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("http://localhost:3000"); // Nuxt.js 주소
            }
        };
    }
}

3. 전체 데이터 흐름

  1. 프론트엔드 (Nuxt.js):
    • 사용자가 Excel 파일을 선택하고 업로드 요청을 보냄.
    • axios를 통해 백엔드 /upload 엔드포인트로 POST 요청.
  2. 백엔드 (Spring):
    • 업로드된 파일을 MultipartFile로 받고, Apache POI로 데이터를 읽음.
    • 읽은 데이터를 JSON 형태로 Nuxt.js로 응답.
  3. 프론트엔드 (Nuxt.js):
    • 백엔드에서 받은 데이터를 화면에 출력.

4. 완성된 코드 요약

📂 Nuxt.js pages/upload.vue

<template>
  <div>
    <h1>Excel 파일 업로드</h1>
    <form @submit.prevent="handleFileUpload">
      <input type="file" @change="onFileChange" accept=".xlsx, .xls" />
      <button type="submit">업로드</button>
    </form>
    <div v-if="uploadResult">
      <h2>업로드 결과:</h2>
      <pre>{{ uploadResult }}</pre>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      file: null,
      uploadResult: null,
    };
  },
  methods: {
    onFileChange(event) {
      this.file = event.target.files[0];
    },
    async handleFileUpload() {
      if (!this.file) {
        alert("파일을 선택해주세요!");
        return;
      }
      const formData = new FormData();
      formData.append("file", this.file);

      try {
        const response = await this.$axios.post("/upload", formData, {
          headers: { "Content-Type": "multipart/form-data" },
        });
        this.uploadResult = response.data;
      } catch (error) {
        console.error("업로드 실패:", error);
        alert("업로드 중 오류가 발생했습니다.");
      }
    },
  },
};
</script>

📂 Spring ExcelController.java

@RestController
public class ExcelController {

    @PostMapping("/upload")
    public List<List<String>> uploadExcel(@RequestParam("file") MultipartFile file) {
        List<List<String>> excelData = new ArrayList<>();

        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = new XSSFWorkbook(inputStream)) {

            Sheet sheet = workbook.getSheetAt(0);
            for (Row row : sheet) {
                List<String> rowData = new ArrayList<>();
                for (Cell cell : row) {
                    switch (cell.getCellType()) {
                        case STRING:
                            rowData.add(cell.getStringCellValue());
                            break;
                        case NUMERIC:
                            rowData.add(String.valueOf(cell.getNumericCellValue()));
                            break;
                        case BOOLEAN:
                            rowData.add(String.valueOf(cell.getBooleanCellValue()));
                            break;
                        default:
                            rowData.add(" ");
                    }
                }
                excelData.add(rowData);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return excelData;
    }
}

5. 마무리

이 글에서는 Nuxt.js와 Spring을 연동하여 Excel 파일을 업로드하고 데이터를 읽는 과정을 설명했습니다. 이를 통해 Nuxt.js가 백엔드로 파일을 전송하고, Spring에서 데이터를 처리하여 JSON으로 반환하는 방법을 알아보았습니다.

반응형