엑셀 파일 업로드 및 미리보기 기능 구현 가이드

  • 7 minutes to read

엑셀 파일 업로드 및 미리보기 기능 구현 가이드

프로젝트: Memos 게시판

개요: 본 가이드에서는 Blazor 서버 사이드 애플리케이션에 엑셀 파일 업로드 및 미리보기 기능을 구현하는 방법을 설명합니다. 이 기능을 통해 사용자는 엑셀 파일을 업로드하고, 파일 내의 데이터를 웹 페이지에서 미리 볼 수 있습니다. 데이터는 Memos 게시판에 표시되며, 사용자가 제공한 엑셀 파일 형식에 따라 이름, 이메일, 제목, 내용, 작성자 정보가 포함됩니다.

필수 구성 파일

  1. 엑셀 템플릿 파일 위치: C:\dev\Hawaso\src\Hawaso\wwwroot\templates\Memos\MemosImport.xlsx
    • 내용 예시:
      Name    Email    Title    Content    CreatedBy
      홍길동  h@h.com  안녕      안녕하세요.  a@a.com
      백두산  b@b.com  방가      반갑습니다.  b@b.com
      

구현 파일

  • 파일 경로: C:\dev\Hawaso\src\Hawaso\Pages\Memos\Import.razor
@page "/Memos/Import"
@using Microsoft.AspNetCore.Components.Forms
@using System.IO
@using DocumentFormat.OpenXml.Packaging
@using DocumentFormat.OpenXml.Spreadsheet

<PageTitle>Excel 데이터 가져오기</PageTitle>

<h3>Excel 파일 업로드</h3>

<a href="/templates/Memos/MemosImport.xlsx" class="btn btn-secondary mb-3">Template Download</a><br />

<Microsoft.AspNetCore.Components.Forms.InputFile OnChange="HandleExcelUpload" accept=".xlsx" />

@if (memos != null && memos.Count > 0)
{
    <h4>데이터 미리보기</h4>
    <table class="table">
        <thead>
            <tr>
                <th>이름</th>
                <th>이메일</th>
                <th>제목</th>
                <th>내용</th>
                <th>작성자</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var memo in memos)
            {
                <tr>
                    <td>@memo.Name</td>
                    <td>@memo.Email</td>
                    <td>@memo.Title</td>
                    <td>@memo.Content</td>
                    <td>@memo.CreatedBy</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private List<Memo> memos = new List<Memo>();

    private async Task HandleExcelUpload(InputFileChangeEventArgs e)
    {
        var file = e.File;
        if (file != null)
        {
            MemoryStream memoryStream = new MemoryStream();
            await file.OpenReadStream(maxAllowedSize: 10485760).CopyToAsync(memoryStream);
            memoryStream.Position = 0; // 스트림의 위치를 처음으로 되돌림

            using var package = SpreadsheetDocument.Open(memoryStream, false);
            var workbookPart = package.WorkbookPart;
            var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault();
            var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
            var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

            List<Memo> loadedMemos = new List<Memo>();

            // 엑셀 파일에서 첫 번째 행은 헤더로 가정, 데이터는 두 번째 행부터 시작
            foreach (Row row in sheetData.Descendants<Row>().Skip(1))
            {
                // 각 행에서 셀 데이터 읽기
                var cells = row.Descendants<Cell>().ToList();
                if (cells.Count >= 5) // 최소한 5개의 셀 데이터가 필요
                {
                    var name = ReadCellValue(workbookPart, cells[0]);
                    var email = ReadCellValue(workbookPart, cells[1]);
                    var title = ReadCellValue(workbookPart, cells[2]);
                    var content = ReadCellValue(workbookPart, cells[3]);
                    var createdBy = ReadCellValue(workbookPart, cells[4]);

                    loadedMemos.Add(new Memo
                        {
                            Name = name,
                            Email = email,
                            Title = title,
                            Content = content,
                            CreatedBy = createdBy,
                            Created = DateTime.UtcNow // 생성 날짜를 현재 시간으로 설정
                        });
                }
            }

            if (loadedMemos.Any())
            {
                memos = loadedMemos; // 로컬 상태에 업로드된 데이터 저장
                StateHasChanged(); // UI 갱신
            }
        }
    }

    // 셀 값 읽기 함수
    private string ReadCellValue(WorkbookPart workbookPart, Cell cell)
    {
        if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
        {
            return workbookPart.SharedStringTablePart.SharedStringTable
                .ElementAt(int.Parse(cell.InnerText)).InnerText;
        }
        else
        {
            return cell.InnerText;
        }
    }
}

사용 방법

  1. 템플릿 다운로드: 사용자는 제공된 링크를 통해 엑셀 템플릿을 다운로드할 수 있습니다.
  2. 파일 업로드: 사용자는 .xlsx 파일을 선택하여 업로드합니다.
  3. 데이터 미리보기: 업로드된 파일의 데이터가 테이블 형태로 화면에 표시됩니다. 각 행은 하나의 Memo 객체에 해당하며, 이름, 이메일, 제목, 내용, 작성자 정보를 포함합니다.

이 가이드는 사용자가 Blazor 애플리케이션에서 엑셀 데이터를 쉽게 업로드하고 미리 볼 수 있도록 도와줍니다. 데이터는 서버에 저장되기 전에 미리 볼 수 있으며, 사용자는 데이터의 정확성을 확인할 수 있습니다.

최종 소스

C:\dev\Hawaso\src\Hawaso\Pages\Memos\Import.razor

@page "/Memos/Import"
@using Microsoft.AspNetCore.Components.Forms
@using System.IO
@using DocumentFormat.OpenXml.Packaging
@using DocumentFormat.OpenXml.Spreadsheet

<PageTitle>Excel 데이터 가져오기</PageTitle>

<h3>Excel 파일 업로드</h3>

<a href="/templates/Memos/MemosImport.xlsx" class="btn btn-secondary mb-3">Template Download</a><br />

<Microsoft.AspNetCore.Components.Forms.InputFile OnChange="HandleExcelUpload" accept=".xlsx" />

@if (memos != null && memos.Count > 0)
{
    <h4>데이터 미리보기</h4>
    <table class="table">
        <thead>
            <tr>
                <th>이름</th>
                <th>이메일</th>
                <th>제목</th>
                <th>내용</th>
                <th>작성자</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var memo in memos)
            {
                <tr>
                    <td>@memo.Name</td>
                    <td>@memo.Email</td>
                    <td>@memo.Title</td>
                    <td>@memo.Content</td>
                    <td>@memo.CreatedBy</td>
                </tr>
            }
        </tbody>
    </table>
}

<button class="btn btn-primary" @onclick="SaveMemos">Save All</button>

@code {
    [Inject]
    public IMemoRepository RepositoryReference { get; set; }

    [Inject]
    public NavigationManager NavigationManager { get; set; }

    private List<Memo> memos = new List<Memo>();

    private async Task HandleExcelUpload(InputFileChangeEventArgs e)
    {
        var file = e.File;
        if (file != null)
        {
            MemoryStream memoryStream = new MemoryStream();
            await file.OpenReadStream(maxAllowedSize: 10485760).CopyToAsync(memoryStream);
            memoryStream.Position = 0; // 스트림의 위치를 처음으로 되돌림

            using var package = SpreadsheetDocument.Open(memoryStream, false);
            var workbookPart = package.WorkbookPart;
            var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault();
            var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
            var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

            List<Memo> loadedMemos = new List<Memo>();

            // 엑셀 파일에서 첫 번째 행은 헤더로 가정, 데이터는 두 번째 행부터 시작
            foreach (Row row in sheetData.Descendants<Row>().Skip(1))
            {
                // 각 행에서 셀 데이터 읽기
                var cells = row.Descendants<Cell>().ToList();
                if (cells.Count >= 5) // 최소한 5개의 셀 데이터가 필요
                {
                    var name = ReadCellValue(workbookPart, cells[0]);
                    var email = ReadCellValue(workbookPart, cells[1]);
                    var title = ReadCellValue(workbookPart, cells[2]);
                    var content = ReadCellValue(workbookPart, cells[3]);
                    var createdBy = ReadCellValue(workbookPart, cells[4]);

                    loadedMemos.Add(new Memo
                        {
                            Name = name,
                            Email = email,
                            Title = title,
                            Content = content,
                            CreatedBy = createdBy,
                            Created = DateTime.UtcNow // 생성 날짜를 현재 시간으로 설정
                        });
                }
            }

            if (loadedMemos.Any())
            {
                memos = loadedMemos; // 로컬 상태에 업로드된 데이터 저장
                StateHasChanged(); // UI 갱신
            }
        }
    }

    // 셀 값 읽기 함수
    private string ReadCellValue(WorkbookPart workbookPart, Cell cell)
    {
        if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
        {
            return workbookPart.SharedStringTablePart.SharedStringTable
                .ElementAt(int.Parse(cell.InnerText)).InnerText;
        }
        else
        {
            return cell.InnerText;
        }
    }

    private async Task SaveMemos()
    {
        foreach (var memo in memos)
        {
            memo.Password = "";
            memo.FileName = "";
            memo.FileSize = 0;
            memo.PostDate = DateTime.Now;
            memo.ParentNum = 0;
            memo.AnswerNum = 0;
            memo.CommentCount = 0;
            memo.Encoding = "Text";
            memo.Step = 0;
            memo.RefOrder = 0;
            memo.PostIp = "127.0.0.1";
            memo.Password = "";
            memo.ReadCount = 0;
            memo.DownCount = 0;

            await RepositoryReference.AddAsync(memo);
        }
        NavigationManager.NavigateTo("/Memos");
    }
}

Excel 파일 업로드, 미리보기 및 저장 절차

  1. 리스트 페이지에서 Excel Upload 링크 버튼을 클릭합니다.

    1-excel-upload.png

  2. Template Download 버튼을 클릭하여 업로드할 Excel 파일의 기본 구조를 확인합니다.

    2-template-download.png

  3. 아래 이미지는 Excel 파일의 샘플 데이터 구조를 보여줍니다.

    3-excel-format.png

  4. 파일 선택 버튼을 클릭하고, Excel 파일을 첨부합니다. 파일이 첨부되면 내용이 미리보기에 로드됩니다.

    4-excel-upload-and-preview.png

  5. Save All 버튼을 클릭하면, 미리보기된 내용이 저장되어 리스트 페이지에 추가됩니다.

    5-uploaded-data.png

VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com