본문 바로가기

C# 윈도우 프로그래밍

c# wpf Excel 파일을 mysql / mariaDB로 입력하기

엑셀 파일을 데이터 그리드에 읽어서 확인후 데이터 베이스에 올리는 자료가 너무 없어서 만들어 보도록하겠다.

 

우선 누겟 패키지에서 데이터 베이스 사용하기 위해 mysql.data 패키지를 설치한다.

 

그 다음 엑셀파일을 찾아서 오기 위해 openfiledialog를 사용을 위해 microsoft.win32 

엑셀을 읽기위해서 microsoft.office.interop.excel

데이터 그리드에 넣기전에 테이블을 만들 datatable 사용을 위한 system.data

그리고 마직으로 maria / mysql 사용을 위해서 mysql.data.mysqlclient 

 

라이브러리들을 사용 선언해준다.

 

using MySql.Data.MySqlClient;
using Microsoft.Win32;
using System.Data;
using Excel=Microsoft.Office.Interop.Excel;

이때 다른패키지와 함수가 중복되는게 많아서 엑셀라이브러리는  Excel로 치환해서 사용한다 

 

그 다음 엑셀사용을 위해

 

엑셀 어플리케이션 / 워크북 / 워크 시트 / 범위 를 선언해준다.

 

Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range range;

그 다음 버튼을 눌러서 엑셀을 가져 올수 있도록 openfiledialog를 사용한다.

private void Button_Click(object sender, RoutedEventArgs e)
{
    OpenFileDialog ofdt = new OpenFileDialog();
    ofdt.Title = "Excel 열기";
    ofdt.FileName = "";
    ofdt.DefaultExt = "EXCEL OPEN";
    ofdt.Filter = "Excel FILE| *.xls| Excel FILE (old)| *.xlsx";
    ofdt.RestoreDirectory = true;

    if (ofdt.ShowDialog() == true)
    {
    	ReadtoDatagrid(ofdt.FileName);
    }
}

그 다음 엑셀을 읽어서 datagrid로 뿌려서 제대로 읽는 지 확인하는 함수를 구현한다.

private void ReadtoDatagrid(string filename)
{
    string str = "";
    int rCnt = 0;
    int cCnt = 0;
    string sCellData = "";
    double dCellData;

    xlApp = new Excel.Application();

    try
    {
        xlWorkBook = xlApp.Workbooks.Open(filename, 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
        xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
        range = xlWorkSheet.UsedRange;

        for (cCnt = 1; cCnt <= range.Columns.Count; cCnt++)
        {
            str = (range.Cells[1, cCnt] as Excel.Range).Value2.ToString();
            dt.Columns.Add(str, typeof(string)); //데이터 그리드의 컬럼명을 입력한다.
        }

        for (rCnt = 2; rCnt <= range.Rows.Count; rCnt++)
        {
            string sData = "";
            for (cCnt = 1; cCnt <= range.Columns.Count; cCnt++)
            {
                try
                {
                    sCellData = (string)(range.Cells[rCnt, cCnt] as Excel.Range).Value2;
                    sData += sCellData + "|";
                }
                catch (Exception ex)
                {
                    dCellData = Convert.ToDouble((range.Cells[rCnt, cCnt] as Excel.Range).Value2);
                    sData += dCellData.ToString() + "|";
                }
            }
            sData = sData.Remove(sData.Length - 1, 1);
            dt.Rows.Add(sData.Split('|'));
        }

        dataExcel.ItemsSource = dt.DefaultView;

        xlWorkBook.Close(true, null, null);
        xlApp.Quit();

        releaseObject(xlWorkSheet);
        releaseObject(xlWorkBook);
        releaseObject(xlApp);
    }
    catch (Exception ex)
    {
        MessageBox.Show("파일 열기 실패! : " + ex.Message);
        return;
    }
}

이때 releaseObject라는 함수를 만들어서 꼭 릴리즈를 해줘야 된다 안그러면 좀비프로세스로 피씨에 잔뜩 남는다.

코드가 중간에 멈출때도 대비에 종료이벤트에서도 호출해주어야 된다.

private void releaseObject(object obj)
{
    try
    {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
        obj = null;
    }
    catch (Exception ex)
    {
        obj = null;
        MessageBox.Show("Unable to release the Object " + ex.ToString());
    }
    finally
    {
        GC.Collect();
    }
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    xlWorkBook.Close(true, null, null);
    xlApp.Quit();

    releaseObject(xlWorkSheet);
    releaseObject(xlWorkBook);
    releaseObject(xlApp);
}

 

이제 저 읽어온 데이터를 데이터베이스에 올리기 버튼 이벤트 함수를 하나 구현한다.

 

dataTable 함수는 읽어올때 전역변수로 선언했어야 된다.

 

private void Button_Click(object sender, RoutedEventArgs e)
{
    string connectString = string.Format("Server={0};Port={1};Database={2};Uid ={3};Pwd={4};", "서버명", "포트번호", "db이름", "계정", "비밀번호");

    using (MySqlConnection conn = new MySqlConnection(connectString))
    {
        conn.Open();
        string[] ad= new string["데이터베이스테이블 컬럼수"]
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            for (int j = 0; j < dt.Columns.Count; j++)
            {
                    ad[j]= dt.Rows[i][j].ToString();
            }
            string sql = "INSERT INTO `테이블명`(`컬러명`) VALUES('" + 넣을값 +  "')";
            MySqlCommand cmd = new MySqlCommand(sql, conn);
            cmd.ExecuteNonQuery();
        }
    }
}

 

위와 같이 구현하면 끝! 차례로 읽어와서 데이터베이스에 삽입하게 된다.

반응형