안녕하세요~
코딩연습생입니다
C# WINFORM에서 그리드뷰의 내용은 엑셀로 내보개기에 대한 포스팅을 할려고 합니다
예전 OLEDB를 이용한 엑셀 연동을 포스팅한적이 있는데요
https://codingman.tistory.com/103?category=715728
해당 예제를 사용하여 구현하셔도 상관은 없습니다~ 하지만 이번엔 Interop.Excel를 사용하여 구현을 해볼껀데요
프로젝트를 하나 생성하시고 윈폼을 하나 만듭니다
저는 위와 같은 화면을 디자인해서 생성하였습니다
아래쪽에 보이는 그리드뷰 영역에 "엑셀"이라는 버튼을 누루면 내보내기가 가능한 기능을 구현을 해볼려고 해요
일단 첫번째로 엑셀을 사용하기 위한 선언을 합니다
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
using System.IO;
두번째는 버튼을 추가하여 클릭 이벤트를 생성한뒤에 다음과 같이 코딩을 합니다
private void hoverGradientButton3_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Title = "Save as Excel File";
sfd.Filter = "Excel Documents (*.xls)|*.xls";
sfd.FileName = "납품처마스터.xls";
if (sfd.ShowDialog() == DialogResult.OK)
{
copyAlltoClipboard();
object misValue = System.Reflection.Missing.Value;
Excel.Application xlexcel = new Excel.Application();
xlexcel.DisplayAlerts = false;
Excel.Workbook xlWorkBook = xlexcel.Workbooks.Add(misValue);
Excel.Worksheet xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
try
{
Excel.Range rng = xlWorkSheet.get_Range("D:D").Cells;
rng.NumberFormat = "@";
Excel.Range CR = (Excel.Range)xlWorkSheet.Cells[1, 1];
CR.Select();
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true);
xlWorkBook.SaveAs(sfd.FileName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlexcel.DisplayAlerts = true;
xlWorkBook.Close(true, misValue, misValue);
//파일 닫기...
uint processId = 0;
GetWindowThreadProcessId(new IntPtr(xlexcel.Hwnd), out processId);
xlexcel.Quit();
if (processId != 0)
{
System.Diagnostics.Process excelProcess = System.Diagnostics.Process.GetProcessById((int)processId);
excelProcess.CloseMainWindow();
excelProcess.Refresh();
excelProcess.Kill();
}
MessageBox.Show("엑셀 파일 생성이 완료 되었습니다.");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
xlWorkBook.Close();
uint processId = 0;
GetWindowThreadProcessId(new IntPtr(xlexcel.Hwnd), out processId);
xlexcel.Quit();
if (processId != 0)
{
System.Diagnostics.Process excelProcess = System.Diagnostics.Process.GetProcessById((int)processId);
excelProcess.CloseMainWindow();
excelProcess.Refresh();
excelProcess.Kill();
}
}
}
}
몇가지 오류가 뜨실껀데 아래의 내용을 적용하면 모두 해결 되실겁니다
두번째는 그리드뷰의 내용을 클립보드(Clipboard)안에 담는 함수 부분입니다
private void copyAlltoClipboard()
{
dataGridView1.SelectAll();
DataObject dataObj = dataGridView1.GetClipboardContent();
if (dataObj != null)
Clipboard.SetDataObject(dataObj);
}
그리고 C#에서 엑셀을 연동하여 사용하시면 항상 프로세스에 엑셀 찌꺼기(?)가 남아 있습니다
그걸 해결하기 위해 몇번 삽질을 했는데요
이를 해결하기 위해 프로젝트 소스 상단에 DLL 하나를 Import 시켜줍니다
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
이렇게 하시면 엑셀 프로세스를 불러와 사용한뒤에 해당 PID값을 기억헀다가 종료시에 강제 삭제해주게 됩니다
실행 순서는 이렇게 됩니다
버튼을 누루게 되면
이렇게 저장 위치를 선택하실수 있게 나오고
저장이 완료되면 위의 사진과 같이 그리드가 전체 선택이 되면서 저장되어집니다
엑셀 파일을 열어보시면 이렇게 헤더까지 그대로 내보내기 되어 진 모습을 볼 수 있네요
감사합니다~
'코딩정보 > C#' 카테고리의 다른 글
[DataGridView] 기본 데이터그리드뷰 디자인 하기!! (0) | 2020.08.25 |
---|---|
[C#] CS1056 예기치 않은 ' ' 문자입니다 오류 해결방법 (0) | 2020.07.28 |
[C#] 데이터 그리드뷰 붙여넣기 만들기 (0) | 2020.07.21 |
[C#] FTP를 이용한 파일 다운로드 구현하기!! (0) | 2020.06.16 |
[DataGridView] 콤보박스 원클릭 리시트 보여주기 (0) | 2020.06.01 |