본문 바로가기
Study/C#

C# Windows Forms 강의 90편: Excel 파일 다루기 - NPOI 라이브러리를 활용한 데이터 읽기 및 쓰기

by wawManager 2025. 5. 4.

 

1. 강의 개요

이번 강의에서는 NPOI 라이브러리를 사용하여 Excel 데이터를 읽고 쓰는 애플리케이션을 제작합니다.
NPOI는 Excel 파일을 다룰 수 있는 .NET 라이브러리로,
Microsoft Office 없이도 XLS 및 XLSX 파일을 처리할 수 있습니다.
Windows Forms UI를 통해 데이터를 입력하고, Excel 파일로 저장하거나,
Excel 파일에서 데이터를 불러오는 방법을 학습합니다.


2. 학습 목표

  • NPOI를 활용해 Excel 파일 읽기 및 쓰기
  • DataGridView와 연동하여 데이터를 시각적으로 관리
  • OpenFileDialog와 SaveFileDialog를 사용해 파일 관리
  • Excel 데이터를 직관적으로 처리하는 UI 제작

3. 기능 요구사항

필수 기능

1️⃣ Excel 파일 읽기:

  • Excel 파일에서 데이터를 읽어와 DataGridView에 표시

2️⃣ Excel 파일 쓰기:

  • DataGridView 데이터를 Excel 파일로 저장

3️⃣ UI 구성 및 동작:

  • 직관적인 DataGridView 기반 UI 구성

4. 실습: Excel 데이터 관리 애플리케이션 제작

1️⃣ 사전 준비

  1. NPOI 라이브러리 설치:
    • Visual Studio에서 NuGet 패키지 설치:
      Install-Package NPOI
      

2️⃣ 폼 구성

  • 폼(Form) 이름: Form1
  • 컨트롤 배치:

컨트롤 타입 이름 위치 크기

DataGridView dgvData 폼 상단 전체 (600 x 300)
Button btnLoad 폼 하단 왼쪽 (100 x 30)
Button btnSave 폼 하단 오른쪽 (100 x 30)

📌 폼 디자인 예시:

--------------------------------------------------
|         [DataGridView - 데이터 목록]           |
--------------------------------------------------
| [Load 버튼]                  [Save 버튼]       |
--------------------------------------------------

3️⃣ 코드 작성

(1) Excel 파일 읽기

using System;
using System.Data;
using System.IO;
using System.Windows.Forms;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;

namespace WindowsFormsApp_Excel
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // Excel 파일 읽기
        private void btnLoad_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "Excel Files (*.xls;*.xlsx)|*.xls;*.xlsx";

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    string filePath = openFileDialog.FileName;
                    LoadExcel(filePath);
                }
            }
        }

        private void LoadExcel(string filePath)
        {
            IWorkbook workbook;
            using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                if (Path.GetExtension(filePath).ToLower() == ".xls")
                    workbook = new HSSFWorkbook(file); // XLS 파일 읽기
                else
                    workbook = new XSSFWorkbook(file); // XLSX 파일 읽기
            }

            ISheet sheet = workbook.GetSheetAt(0); // 첫 번째 시트 선택
            DataTable dataTable = new DataTable();

            // 헤더 읽기
            var headerRow = sheet.GetRow(0);
            for (int i = 0; i < headerRow.LastCellNum; i++)
            {
                dataTable.Columns.Add(headerRow.GetCell(i).ToString());
            }

            // 데이터 읽기
            for (int i = 1; i <= sheet.LastRowNum; i++)
            {
                var row = sheet.GetRow(i);
                if (row == null) continue;

                DataRow dataRow = dataTable.NewRow();
                for (int j = 0; j < row.LastCellNum; j++)
                {
                    dataRow[j] = row.GetCell(j)?.ToString();
                }
                dataTable.Rows.Add(dataRow);
            }

            dgvData.DataSource = dataTable;
        }
    }
}

(2) Excel 파일 쓰기

        // Excel 파일 저장
        private void btnSave_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog saveFileDialog = new SaveFileDialog())
            {
                saveFileDialog.Filter = "Excel Files (*.xlsx)|*.xlsx";

                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    string filePath = saveFileDialog.FileName;
                    SaveExcel(filePath);
                }
            }
        }

        private void SaveExcel(string filePath)
        {
            IWorkbook workbook = new XSSFWorkbook();
            ISheet sheet = workbook.CreateSheet("Sheet1");

            // 헤더 작성
            var headerRow = sheet.CreateRow(0);
            for (int i = 0; i < dgvData.Columns.Count; i++)
            {
                headerRow.CreateCell(i).SetCellValue(dgvData.Columns[i].HeaderText);
            }

            // 데이터 작성
            for (int i = 0; i < dgvData.Rows.Count; i++)
            {
                var row = sheet.CreateRow(i + 1);
                for (int j = 0; j < dgvData.Columns.Count; j++)
                {
                    row.CreateCell(j).SetCellValue(dgvData.Rows[i].Cells[j].Value?.ToString() ?? "");
                }
            }

            // 파일 저장
            using (var file = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                workbook.Write(file);
            }

            MessageBox.Show("데이터가 저장되었습니다.", "완료", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

(3) Designer 코드

        private void InitializeComponent()
        {
            this.dgvData = new DataGridView();
            this.btnLoad = new Button();
            this.btnSave = new Button();

            // DataGridView 설정
            this.dgvData.Location = new System.Drawing.Point(10, 10);
            this.dgvData.Size = new System.Drawing.Size(600, 300);
            this.dgvData.AllowUserToAddRows = true;

            // Load Button 설정
            this.btnLoad.Location = new System.Drawing.Point(10, 320);
            this.btnLoad.Size = new System.Drawing.Size(100, 30);
            this.btnLoad.Text = "Load";
            this.btnLoad.Click += new EventHandler(this.btnLoad_Click);

            // Save Button 설정
            this.btnSave.Location = new System.Drawing.Point(120, 320);
            this.btnSave.Size = new System.Drawing.Size(100, 30);
            this.btnSave.Text = "Save";
            this.btnSave.Click += new EventHandler(this.btnSave_Click);

            // Form 설정
            this.ClientSize = new System.Drawing.Size(640, 360);
            this.Controls.Add(this.dgvData);
            this.Controls.Add(this.btnLoad);
            this.Controls.Add(this.btnSave);
            this.Text = "Excel 파일 관리";
        }

3️⃣ 실행 결과

1️⃣ Excel 파일 읽기

  • "Load" 버튼 클릭 → OpenFileDialog에서 파일 선택 → DataGridView에 데이터 표시

2️⃣ Excel 파일 쓰기

  • DataGridView에 데이터 입력 → "Save" 버튼 클릭 → SaveFileDialog에서 저장

5. 주요 개념 요약

  • NPOI: Excel 파일을 읽고 쓰기 위한 .NET 라이브러리
  • IWorkbook, ISheet: Excel 파일 및 시트 객체
  • DataGridView: 데이터를 시각적으로 관리
  • OpenFileDialog, SaveFileDialog: 파일 열기 및 저장 대화 상자

 

📌 #CSharp #WindowsForms #Excel #NPOI #데이터관리 #DataGridView