안녕하세요
코딩 연습생 입니다
이전 포스팅에서 직접 엑셀의 API를 활용하여 엑셀파일의 내용을 불러와 데이터그리드뷰와 연동하는 포스팅을
업로드했었는데요
https://codingman.tistory.com/100
이전 포스팅 방식으로 직접 구현을 해보신 분이나 관련 내용을 아시는분들이라면 아실것 같은데요
위의 방법으로 구현했을시(직접 엑셀을 임포트하는 방식) 제일 큰 단점은 대량을 엑셀 파일을 읽을때
엄청 느리다는것 입니다
그것을 조금이나마 해결하고자 엑셀의 문서 속성을 변경하여 이용하는데
https://codingman.tistory.com/101
이것도 전에 포스팅했었네요ㅎㅎ 근데 이 방법도 미미한 차이일뿐 사용자는 크게 느끼지 못합니다
그래서 이번에 포스팅할 내용은 직접 엑셀을 임포는하는 방식이 아닌 OleDbConnection을 이용한 엑셀 연동 방식으로
구현을 해볼려고 합니다
아마 이미 정보가 많이 있어서 한번쯤 구현을 해보시지 않았을까 싶은데요
하나씩 쉽게 이해할수 있도록 순서대로 포스팅해보도록 할께요
첫번재는 해당 From에서 OleDb를 사용하기 위한 선언부 입니다
아마 닷넷 4버전 이상을 사용하시는분이라면 기본적으로 포함되어 있을건데
혹시 프로젝트의 참조부분에 System.Data가 있는지 확인한 후에 없으시면 참조추가를 사용해서 추가해 줍니다
그리고 From의 제일 상단위에 다음과 같이 선언을 합니다
using System.Data.OleDb;
사실 윈도우에서 기본 사용이 가능해야 하는데 오류가 발생을 많이 합니다
그래서 사전 배포를 용이하게 하기 위해서 몇가지 설치 파일을 설치 해야합니다
해당 패키지를 설치 하지 않고 배포 하시면
"Microsoft.ACE.OLEDB.12.0 공급자는 로컬 컴퓨터에 등록할 수 없습니다.(System.Data)"
위와 같은 오류를 경험하게 되십니다ㅎㅎ
저와 같은 경험을 하지 않게 해드리기 위해서 미리 패키지 설치까지 합니다
http://www.microsoft.com/ko-kr/download/details.aspx?id=13255
위의 주소로 접속해서 32비트 & 64비트 설치 파일을 모두 설치 해주세요
그다음 비쥬얼스튜디오로 돌아와서 From에 버튼을 하나 생성해 줍니다
저는 기존 소스를 이용하겠습니다
이렇게 버튼을 하나 준비해 주시구요
버튼의 Click 이벤트를 만들어 주세요
만드신 이벤트안에 아래의 소스코드를 만들어 줍니다
private void hoverGradientButton10_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "엑셀 파일 선택하세요";
openFileDialog.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";
DialogResult result = openFileDialog.ShowDialog();
if (result == DialogResult.OK)
{
SubForms.SplashWnd.SplashShow();
this.Cursor = Cursors.WaitCursor;
//엑셀 앱
Excel.Application app = new Excel.Application();
app.DisplayAlerts = false;
app.Visible = false;
app.ScreenUpdating = false;
app.DisplayStatusBar = false;
app.EnableEvents = false;
Excel.Workbooks workbooks = app.Workbooks;
//엑셀 워크북(파일경로읽어서)
//Excel.Workbook workbook = workbooks.Open(openFileDialog.FileName);
Excel.Workbook workbook = workbooks.Open(openFileDialog.FileName, 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
// 엑셀 워크싯 객체
Excel.Sheets sheets = workbook.Worksheets;
Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);
// 엑셀파일 이름이 나온다
string excelFileName = workbook.Name;
//excelFileName = excelFileName.Substring(book.Name.Length-3);
string[] str = excelFileName.Split('.');
// 워크시트 첫번째 이름
string workSheetName = worksheet.Name;
try
{
if (str[1].Equals("xls"))
{
// 연결 string
string constr = "provider=Microsoft.Jet.OLEDB.4.0;Data Source='"
+ openFileDialog.FileName + "';Extended Properties=Excel 8.0;";
//경로까지 다 포함해서 .xls라고 뜨네;
//MessageBox.Show(openFileDialog.FileName);
// excel conn
OleDbConnection conn = new OleDbConnection(constr);
// excel cmd
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [" + workSheetName + "$]", conn);
conn.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
this.Cursor = Cursors.WaitCursor;
dataGridView1.DataSource = dt;
this.Cursor = Cursors.Default;
conn.Close();
}
else if (str[1].Equals("xlsx"))
{
// 연결 string
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
openFileDialog.FileName +
";Extended Properties='Excel 12.0 XML;HDR=No;IMEX=1';";
//경로까지 다 포함해서 .xls라고 뜨네;
//MessageBox.Show(openFileDialog.FileName);
// excel conn
OleDbConnection conn = new OleDbConnection(constr);
// excel cmd
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [" + workSheetName + "$]", conn);
conn.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
int j = 0;
//dataGridView1.DataSource = dt;
for(int i=6; i<=dt.Rows.Count-1; i++)
{
dataGridView2.Rows.Add(1);
dataGridView2.Rows[j].Cells[0].Value = dt.Rows[i][0].ToString();
dataGridView2.Rows[j].Cells[1].Value = dt.Rows[i][2].ToString();
dataGridView2.Rows[j].Cells[2].Value = dt.Rows[i][4].ToString();
dataGridView2.Rows[j].Cells[3].Value = dt.Rows[i][5].ToString();
dataGridView2.Rows[j].Cells[4].Value = dt.Rows[i][6].ToString();
dataGridView2.Rows[j].Cells[5].Value = dt.Rows[i][7].ToString();
dataGridView2.Rows[j].Cells[6].Value = dt.Rows[i][8].ToString();
dataGridView2.Rows[j].Cells[7].Value = dt.Rows[i][9].ToString();
dataGridView2.Rows[j].Cells[8].Value = dt.Rows[i][10].ToString();
dataGridView2.Rows[j].Cells[9].Value = dt.Rows[i][11].ToString();
dataGridView2.Rows[j].Cells[10].Value = dt.Rows[i][12].ToString();
dataGridView2.Rows[j].Cells[11].Value = dt.Rows[i][13].ToString();
dataGridView2.Rows[j].Cells[12].Value = dt.Rows[i][14].ToString();
dataGridView2.Rows[j].Cells[13].Value = dt.Rows[i][15].ToString();
dataGridView2.Rows[j].Cells[14].Value = dt.Rows[i][16].ToString();
dataGridView2.Rows[j].Cells[15].Value = dt.Rows[i][17].ToString();
dataGridView2.Rows[j].Cells[16].Value = dt.Rows[i][18].ToString();
dataGridView2.Rows[j].Cells[17].Value = dt.Rows[i][19].ToString();
dataGridView2.Rows[j].Cells[18].Value = dt.Rows[i][20].ToString();
dataGridView2.Rows[j].Cells[19].Value = dt.Rows[i][21].ToString();
dataGridView2.Rows[j].Cells[20].Value = dt.Rows[i][22].ToString();
dataGridView2.Rows[j].Cells[21].Value = dt.Rows[i][23].ToString();
dataGridView2.Rows[j].Cells[22].Value = dt.Rows[i][24].ToString();
dataGridView2.Rows[j].Cells[23].Value = dt.Rows[i][25].ToString();
dataGridView2.Rows[j].Cells[24].Value = dt.Rows[i][26].ToString();
dataGridView2.Rows[j].Cells[25].Value = dt.Rows[i][27].ToString();
dataGridView2.Rows[j].Cells[26].Value = dt.Rows[i][28].ToString();
dataGridView2.Rows[j].Cells[27].Value = dt.Rows[i][29].ToString();
dataGridView2.Rows[j].Cells[28].Value = dt.Rows[i][30].ToString();
dataGridView2.Rows[j].Cells[29].Value = dt.Rows[i][31].ToString();
dataGridView2.Rows[j].Cells[30].Value = dt.Rows[i][32].ToString();
dataGridView2.Rows[j].Cells[31].Value = dt.Rows[i][33].ToString();
dataGridView2.Rows[j].Cells[32].Value = dt.Rows[i][34].ToString();
dataGridView2.Rows[j].Cells[33].Value = dt.Rows[i][35].ToString();
dataGridView2.Rows[j].Cells[34].Value = dt.Rows[i][36].ToString();
dataGridView2.Rows[j].Cells[35].Value = dt.Rows[i][37].ToString();
dataGridView2.Rows[j].Cells[36].Value = dt.Rows[i][38].ToString();
dataGridView2.Rows[j].Cells[37].Value = dt.Rows[i][39].ToString();
dataGridView2.Rows[j].Cells[38].Value = dt.Rows[i][40].ToString();
dataGridView2.Rows[j].Cells[39].Value = dt.Rows[i][41].ToString();
dataGridView2.Rows[j].Cells[40].Value = dt.Rows[i][42].ToString();
dataGridView2.Rows[j].Cells[41].Value = dt.Rows[i][43].ToString();
dataGridView2.Rows[j].Cells[42].Value = dt.Rows[i][44].ToString();
dataGridView2.Rows[j].Cells[43].Value = dt.Rows[i][45].ToString();
dataGridView2.Rows[j].Cells[44].Value = dt.Rows[i][46].ToString();
dataGridView2.Rows[j].Cells[45].Value = dt.Rows[i][47].ToString();
dataGridView2.Rows[j].Cells[46].Value = dt.Rows[i][48].ToString();
dataGridView2.Rows[j].Cells[47].Value = dt.Rows[i][49].ToString();
dataGridView2.Rows[j].Cells[48].Value = dt.Rows[i][50].ToString();
dataGridView2.Rows[j].Cells[49].Value = dt.Rows[i][51].ToString();
dataGridView2.Rows[j].Cells[50].Value = dt.Rows[i][52].ToString();
dataGridView2.Rows[j].Cells[51].Value = dt.Rows[i][53].ToString();
dataGridView2.Rows[j].Cells[52].Value = dt.Rows[i][54].ToString();
dataGridView2.Rows[j].Cells[53].Value = dt.Rows[i][55].ToString();
dataGridView2.Rows[j].Cells[54].Value = dt.Rows[i][56].ToString();
dataGridView2.Rows[j].Cells[55].Value = dt.Rows[i][57].ToString();
dataGridView2.Rows[j].Cells[56].Value = dt.Rows[i][58].ToString();
dataGridView2.Rows[j].Cells[57].Value = dt.Rows[i][59].ToString();
dataGridView2.Rows[j].Cells[58].Value = dt.Rows[i][60].ToString();
dataGridView2.Rows[j].Cells[59].Value = dt.Rows[i][61].ToString();
dataGridView2.Rows[j].Cells[60].Value = dt.Rows[i][62].ToString();
dataGridView2.Rows[j].Cells[61].Value = dt.Rows[i][63].ToString();
dataGridView2.Rows[j].Cells[62].Value = dt.Rows[i][64].ToString();
dataGridView2.Rows[j].Cells[63].Value = dt.Rows[i][65].ToString();
dataGridView2.Rows[j].Cells[64].Value = dt.Rows[i][66].ToString();
dataGridView2.Rows[j].Cells[65].Value = dt.Rows[i][67].ToString();
dataGridView2.Rows[j].Cells[66].Value = dt.Rows[i][68].ToString();
dataGridView2.Rows[j].Cells[67].Value = dt.Rows[i][69].ToString();
dataGridView2.Rows[j].Cells[68].Value = dt.Rows[i][70].ToString();
dataGridView2.Rows[j].Cells[69].Value = dt.Rows[i][71].ToString();
dataGridView2.Rows[j].Cells[70].Value = dt.Rows[i][72].ToString();
dataGridView2.Rows[j].Cells[71].Value = dt.Rows[i][73].ToString();
dataGridView2.Rows[j].Cells[72].Value = dt.Rows[i][74].ToString();
dataGridView2.Rows[j].Cells[73].Value = dt.Rows[i][75].ToString();
dataGridView2.Rows[j].Cells[74].Value = dt.Rows[i][76].ToString();
dataGridView2.Rows[j].Cells[75].Value = dt.Rows[i][77].ToString();
dataGridView2.Rows[j].Cells[76].Value = dt.Rows[i][78].ToString();
dataGridView2.Rows[j].Cells[77].Value = dt.Rows[i][79].ToString();
dataGridView2.Rows[j].Cells[78].Value = dt.Rows[i][80].ToString();
dataGridView2.Rows[j].Cells[79].Value = dt.Rows[i][81].ToString();
dataGridView2.Rows[j].Cells[80].Value = dt.Rows[i][82].ToString();
dataGridView2.Rows[j].Cells[81].Value = dt.Rows[i][83].ToString();
j++;
}
this.Cursor = Cursors.Default;
conn.Close();
Finish_Data_Insert();
SubForms.SplashWnd.SplashClose(this);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
workbook.Close(true, null, null);
app.Quit();
ReleaseExcelObject(worksheet);
ReleaseExcelObject(sheets);
ReleaseExcelObject(workbook);
ReleaseExcelObject(workbooks);
ReleaseExcelObject(app);
}
finally
{
workbook.Close(true, null, null);
app.Quit();
ReleaseExcelObject(worksheet);
ReleaseExcelObject(sheets);
ReleaseExcelObject(workbook);
ReleaseExcelObject(workbooks);
ReleaseExcelObject(app);
}
}
}
오브젝트 초기화를 위해 아래 함수로 하나 작성해 줍니다
private void ReleaseExcelObject(object obj)
{
try
{
if (obj != null)
{
Marshal.ReleaseComObject(obj);
obj = null;
}
}
catch (Exception ex)
{
obj = null;
throw ex;
}
finally
{
GC.Collect();
}
}
이렇게 해주시고 생성하신 버튼을 누구게 되면 OpenFileDialog가 열리고 거기서 엑셀 파일을 선택해 주시면
해당 엑셀의 문서 내용이 데이터그리드뷰에 옴겨지게 됩니다
위의 소스 내용중 "SubForms.SplashWnd.SplashShow();" 구문은 주석 또는 삭제 하셔도 무관합니다
해당 코드는 사용자에게 진행중을 표시하기 위한 ProgressBar를 구현한것인데 없어도 구동하는데 전혀 문제가 없습니다
해당 내용은 다른 포스팅에서 정리해서 올리도록 할께요
이전 방식과 현재의 방식을 모두 구현을 하셨다면 속도 비교를 해보시면 깜짝 놀라실수 있을겁니다
동일 엑셀 문서기준 (대략 Row가 1000개)의 파일을 불러오기 하였을때
● 기존방식 : 10~15분 소요
● 현재방식 : 30초 미만
엄청난 차이를 보여주더라구요
엑셀과 연동을 구현하기 위해 고민중이시라면 위의 방법을 통해 구현해 보시길 바랍니다
'코딩정보 > C#' 카테고리의 다른 글
[C#] 데이터그리드뷰(콤보박스) 값 변경 이벤트 (0) | 2020.05.06 |
---|---|
[C#] 투명 팝업창을 이용한 ProgressBar 만들기 (0) | 2020.04.22 |
[C#] DataGridView 동적 컬럼 생성하기 (0) | 2020.04.20 |
[C#] 엑셀 Cells 사용시 속도 문제 해결하기 (3) | 2020.04.14 |
[C#] 엑셀 템플릿파일 불러오기 및 값 넣기 (0) | 2020.04.06 |