using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32.SafeHandles;
using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
using System.Data;
using System.Drawing;
namespace ExcelImprot
{
public class LExcelHandler
{
private bool _bDisposed = false;
private SafeHandle _objSafeHandler = new SafeFileHandle(IntPtr.Zero, true);
private bool _bIsActive = false;
private Excel.Application _objApp = null;
private Excel.Workbooks _objWorkbooks = null;
private Excel.Workbook _objWorkbook = null;
private Excel.Sheets _objSheets = null;
private Excel.Worksheet _objWorksheet = null;
private Excel.Range _objRange = null;
///
/// 객체 생성자입니다.
///
/// 사전 엑셀 어플리케이션 생성여부입니다.
public LExcelHandler(bool bPrepareApplication)
{
if (bPrepareApplication)
{
try
{
_objApp = new Excel.Application();
_objWorkbooks = _objApp.Workbooks;
}
catch (Exception ex)
{
throw ex;
}
}
}
///
/// 지정된 경로의 엑셀파일을 읽어 DataTable형으로 반환합니다.
///
/// 엑셀파일 경로
/// 반환된 DataTable형 객체
///
/// 지정된 경로의 엑셀파일을 읽어 DataTable형으로 반환합니다.
///
/// 엑셀파일 경로
/// 읽을 시트 번호입니다.
/// 읽기전용 경고를 무시할지 여부입니다.
/// 반환된 DataTable형 객체
public DataTable ReadAsDataTableFromOpenedExcel(string strFilePath, int iWorkSheetNumber = 1, bool bIngnoreReadOnlyRecommended = false)
{
if (_objApp == null)
{
try
{
_objApp = new Excel.Application();
_objWorkbooks = _objApp.Workbooks;
}
catch (Exception ex)
{
throw ex;
}
}
DataTable objDataTable = new DataTable();
try
{
_objWorkbook = _objApp.Workbooks.Open(strFilePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, bIngnoreReadOnlyRecommended);
_objSheets = _objWorkbook.Worksheets;
_objWorksheet = _objSheets.get_Item(iWorkSheetNumber) as Excel.Worksheet;
_objRange = _objWorksheet.UsedRange;
//Excel.Range objRange = objWorksheet.Range[objWorksheet.Cells[2, 1], objWorksheet.Cells[5, 1]];
object[,] objData = _objRange.Value;
for (int i = 0; i < objData.GetLength(1); i++)
{
objDataTable.Columns.Add(DecToAlphabet(i));
}
for (int r = 1; r <= objData.GetLength(0); r++)
{
DataRow objRow = objDataTable.NewRow();
for (int c = 1; c <= objData.GetLength(1); c++)
{
object objValue = objData[r, c];
string strValue = "";
if (objValue != null)
strValue = objData[r, c].ToString();
objRow[c - 1] = strValue;
}
objDataTable.Rows.Add(objRow);
}
_objWorkbook.Saved = true;
_objWorkbook.Close(true);
}
catch (Exception ex)
{
throw ex;
}
return objDataTable;
}
///
/// 지정된 경로의 엑셀파일을 읽어 Object 2차원 배열로 반환합니다.
///
/// 파일경로
/// 워크시트번호
/// 오류 무시 여부
/// 엑셀로부터 읽어진 2차원 배열, 오류시 NULL을 반환합니다.
public object[,] ReadAsArrayFromOpenedExcel(string strFilePath, int iWorkSheetNumber = 1, bool bIngnoreReadOnlyRecommended = false)
{
if (_objApp == null)
{
try
{
_objApp = new Excel.Application();
_objWorkbooks = _objApp.Workbooks;
}
catch (Exception ex)
{
throw ex;
}
}
object[,] objData = null;
try
{
_objWorkbook = _objWorkbooks.Open(strFilePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, bIngnoreReadOnlyRecommended);
_objSheets = _objWorkbook.Worksheets;
_objWorksheet = _objSheets.get_Item(iWorkSheetNumber) as Excel.Worksheet;
_objRange = _objWorksheet.UsedRange;
objData = _objRange.Value;
_objWorkbook.Saved = true;
_objWorkbook.Close(true);
}
catch (Exception ex)
{
throw ex;
}
return objData;
}
public void CloseOpenedExcel()
{
try
{
if (_objApp != null)
_objApp.Quit();
}
catch (Exception ex)
{
throw ex;
}
finally
{
LExcelHandler.ReleaseExcelObject(_objRange);
LExcelHandler.ReleaseExcelObject(_objWorksheet);
LExcelHandler.ReleaseExcelObject(_objSheets);
LExcelHandler.ReleaseExcelObject(_objWorkbook);
LExcelHandler.ReleaseExcelObject(_objWorkbooks);
LExcelHandler.ReleaseExcelObject(_objApp);
_objApp = null;
}
}
///
/// 지정된 경로의 엑셀파일을 읽어 Object 2차원 배열로 반환합니다.
///
/// 파일 경로
/// 워크 시트 번호
/// 오류 무시 여부
/// 엑셀로 부터 읽어진 2차원 배열, 오류 시 NULL을 반환합니다.
public static object[,] ReadAsArray(string strFilePath, int iWorkSheetNumber = 1, bool bIngnoreReadOnlyRecommended = false)
{
Excel.Application objExcelApp = null;
Excel.Workbooks objWorkbooks = null;
Excel.Workbook objSelectedWorkbook = null;
Excel.Sheets objSheets = null;
Excel.Worksheet objSelectedWorksheet = null;
Excel.Range objSelectedRange = null;
object[,] objData = null;
try
{
objExcelApp = new Excel.Application();
objWorkbooks = objExcelApp.Workbooks;
objSelectedWorkbook = objWorkbooks.Open(strFilePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, bIngnoreReadOnlyRecommended);
objSheets = objSelectedWorkbook.Worksheets;
objSelectedWorksheet = objSheets.get_Item(iWorkSheetNumber) as Excel.Worksheet;
objSelectedRange = objSelectedWorksheet.UsedRange;
objData = objSelectedRange.Value;
objSelectedWorkbook.Saved = true;
objSelectedWorkbook.Close(true);
objExcelApp.Quit();
}
catch (Exception ex)
{
throw ex;
}
finally
{
LExcelHandler.ReleaseExcelObject(objSelectedRange);
LExcelHandler.ReleaseExcelObject(objSelectedWorksheet);
LExcelHandler.ReleaseExcelObject(objSheets);
LExcelHandler.ReleaseExcelObject(objSelectedWorkbook);
LExcelHandler.ReleaseExcelObject(objWorkbooks);
LExcelHandler.ReleaseExcelObject(objExcelApp);
objExcelApp = null;
}
return objData;
}
///
/// 지정된 경로의 엑셀파일을 읽어 DataTable형으로 반환합니다.
///
/// 엑셀파일 경로
/// 반환된 DataTable형 객체
public static DataTable ReadAsDataTable(string strFilePath, int iWorkSheetNumber = 1, bool bIngnoreReadOnlyRecommended = false)
{
Excel.Application objApp = null;
Excel.Workbooks objWorkbooks = null;
Excel.Workbook objWorkbook = null;
Excel.Sheets objSheets = null;
Excel.Worksheet objWorksheet = null;
Excel.Range objTargetRange = null;
DataTable objDataTable = new DataTable();
try
{
objApp = new Excel.Application();
objWorkbook = objApp.Workbooks.Open(strFilePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, bIngnoreReadOnlyRecommended);
objWorksheet = objWorkbook.Worksheets.get_Item(iWorkSheetNumber) as Excel.Worksheet;
objTargetRange = objWorksheet.UsedRange;
//Excel.Range objRange = objWorksheet.Range[objWorksheet.Cells[2, 1], objWorksheet.Cells[5, 1]];
object[,] objData = objTargetRange.Value;
for (int i = 0; i < objData.GetLength(1); i++)
{
objDataTable.Columns.Add(DecToAlphabet(i));
}
for (int r = 1; r <= objData.GetLength(0); r++)
{
DataRow objRow = objDataTable.NewRow();
for (int c = 1; c <= objData.GetLength(1); c++)
{
object objValue = objData[r, c];
string strValue = "";
if (objValue != null)
strValue = objData[r, c].ToString();
objRow[c - 1] = strValue;
}
objDataTable.Rows.Add(objRow);
}
objWorkbook.Close(true);
objApp.Quit();
}
catch (Exception ex)
{
throw ex;
}
finally
{
LExcelHandler.ReleaseExcelObject(objTargetRange);
LExcelHandler.ReleaseExcelObject(objWorksheet);
LExcelHandler.ReleaseExcelObject(objSheets);
LExcelHandler.ReleaseExcelObject(objWorkbook);
LExcelHandler.ReleaseExcelObject(objWorkbooks);
LExcelHandler.ReleaseExcelObject(objApp);
objApp = null;
}
return objDataTable;
}
///
/// 입력된 DataTable형 데이터를 지정된 경로의 엑셀파일로 저장합니다.
///
/// 저장할 DataTable 객체
/// 저장할 파일 경로
/// 헤더를 포함할지 여부입니다.
/// LReturnMessage형 결과 값으로 함수 실행이 성공하였으면 객체 내 IsOK 변수에 true 반환하며 실패하였다면 false를 반환합니다. false 시, 오류 메세지가 객체 내 ExceptionMessage에 저장됩니다.
public bool Save(DataTable objDataTable, string strFilePath, bool bWriteHeader)
{
if (_objApp == null)
{
try
{
_objApp = new Excel.Application();
_objWorkbooks = _objApp.Workbooks;
}
catch (Exception ex)
{
throw ex;
}
}
try
{
_objWorkbook = _objWorkbooks.Add();
_objWorksheet = _objWorkbook.Worksheets.get_Item(1) as Excel.Worksheet;
if (bWriteHeader)
{
// 헤더 저장
for (int i = 0; i < objDataTable.Columns.Count; i++)
{
string strHeader = "";
if (objDataTable.Columns[i].ColumnName != null)
strHeader = objDataTable.Columns[i].ColumnName;
_objWorksheet.Cells[1, i + 1] = strHeader;
}
for (int r = 0; r < objDataTable.Rows.Count; r++)
{
for (int c = 0; c < objDataTable.Columns.Count; c++)
{
_objWorksheet.Cells[r + 2, c + 1] = objDataTable.Rows[r][c];
}
}
}
else
{
for (int r = 0; r < objDataTable.Rows.Count; r++)
{
for (int c = 0; c < objDataTable.Columns.Count; c++)
{
_objWorksheet.Cells[r + 1, c + 1] = objDataTable.Rows[r][c];
}
}
}
_objWorkbook.SaveAs(strFilePath, Excel.XlFileFormat.xlOpenXMLWorkbook);
_objWorkbook.Saved = true;
_objWorkbook.Close(true);
return true;
}
catch (Exception ex)
{
throw ex;
}
}
#region Excel Drawing
///
/// 현재 워크북을 저장하고 닫습니다..
///
/// 저장 경로
/// 처리 여부
public bool SaveCurrentWorkbook(string strFilePath)
{
try
{
_objWorkbook.SaveAs(strFilePath, Excel.XlFileFormat.xlOpenXMLWorkbook);
_objWorkbook.Saved = true;
_objWorkbook.Close(true);
return true;
}
catch (Exception ex)
{
return false;
}
}
///
/// 엑셀에 입력한 데이터 테이블 정보를 입력합니다.
///
///
/// 처리 여부
public bool SetData(DataTable objDataTable, bool bWriteHeader = true)
{
if (_objApp == null)
{
try
{
_objApp = new Excel.Application();
_objWorkbooks = _objApp.Workbooks;
}
catch (Exception ex)
{
return false;
}
}
try
{
_objWorkbook = _objWorkbooks.Add();
_objWorksheet = _objWorkbook.Worksheets.get_Item(1) as Excel.Worksheet;
if (bWriteHeader)
{
// 헤더 저장
for (int i = 0; i < objDataTable.Columns.Count; i++)
{
string strHeader = "";
if (objDataTable.Columns[i].ColumnName != null)
strHeader = objDataTable.Columns[i].ColumnName;
_objWorksheet.Cells[1, i + 1] = strHeader;
}
for (int r = 0; r < objDataTable.Rows.Count; r++)
{
for (int c = 0; c < objDataTable.Columns.Count; c++)
{
_objWorksheet.Cells[r + 2, c + 1] = objDataTable.Rows[r][c];
}
}
}
else
{
for (int r = 0; r < objDataTable.Rows.Count; r++)
{
for (int c = 0; c < objDataTable.Columns.Count; c++)
{
_objWorksheet.Cells[r + 1, c + 1] = objDataTable.Rows[r][c];
}
}
}
return true;
}
catch (Exception ex)
{
return false;
}
}
///
/// 사용된 전체 셀을 선택합니다.
///
///
public Excel.Range SelectUsedRange()
{
_objRange = _objWorksheet.UsedRange;
return _objRange;
}
///
/// 단일 셀을 선택합니다.
///
/// 셀 주소
/// 선택한 셀 역역
public Excel.Range SelectCell(string strCell)
{
_objRange = _objWorksheet.Range[strCell, Type.Missing];
return _objRange;
}
///
/// 단일 셀을 선택합니다.
///
/// 셀 행
/// 셀 열
/// 선택한 셀 영역
public Excel.Range SelectCell(int iRow, int iCol)
{
string strCell = CellAddress(iRow, iCol);
_objRange = _objWorksheet.Range[strCell, Type.Missing];
return _objRange;
}
///
/// 다중 셀을 선택합니다.
///
/// 시작 셀 주소
/// 종료 셀 주소
/// 선택한 셀 영역
public Excel.Range SelectCell(string strStartCell, string strEndCell)
{
_objRange = _objWorksheet.Range[strStartCell, strEndCell];
return _objRange;
}
///
/// 다중 셀을 선택합니다.
///
/// 시작 셀 행
/// 시작 셀 열
/// 끝 셀 행
/// 끝 셀 열
///
public Excel.Range SelectCell(int iStartRow, int iStartCol, int iEndRow, int iEndCol)
{
string strStartCell = CellAddress(iStartRow, iStartCol);
string strEndCell = CellAddress(iEndRow, iEndCol);
_objRange = _objWorksheet.Range[strStartCell, strEndCell];
return _objRange;
}
///
/// 선택된 셀 영역의 색상을 지정합니다.
///
/// 지정할 색상
/// 처리 여부
public bool SetColor(Color objColor)
{
if (_objRange == null)
return false;
_objRange.Interior.Color = ColorTranslator.ToOle(objColor);
return true;
}
///
/// 선택된 셀 영역의 컬럼을 자동맞춤 합니다.
///
/// 처리 여부
public bool SetColumnWidth()
{
if (_objRange == null)
return false;
_objRange.Columns.AutoFit();
return true;
}
///
/// 선택된 셀 영역의 컬럼의 폭을 설정합니다.
///
/// 폭
/// 처리 여부
public bool SetColumnWidth(double dWidth)
{
if (_objRange == null)
return false;
_objRange.ColumnWidth = dWidth;
return true;
}
///
/// 선택된 셀 영역을 병합합니다.
///
/// 처리 여부
public bool SetMerge()
{
if (_objRange == null)
return false;
_objRange.Merge(true);
return true;
}
///
/// 선택된 셀 영역의 폰트 사이즈를 설정합니다.
///
/// 폰트 사이즈
/// 처리 여부
public bool SetSize(int iSize)
{
if (_objRange == null)
return false;
_objRange.Font.Size = iSize;
return true;
}
///
/// 선택된 셀 영역을 볼드 처리합니다.
///
/// 처리 여부
public bool SetBold()
{
if (_objRange == null)
return false;
_objRange.Font.Bold = true;
return true;
}
///
/// 선택된 셀 영역을 가운데 정렬 처리 합니다.
///
/// 처리 여부
public bool SetCenterAlign()
{
if (_objRange == null)
return false;
_objRange.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
return true;
}
///
/// 선택한 셀 영역의 테두리를 설정합니다.
///
/// 외곽선
/// 내부 세로선
/// 내부 가로선
/// 처리 여부
public bool SetBorder(bool bOutline = true, bool bHorizontal = true, bool bVertical = true)
{
if (_objRange == null)
return false;
if (bOutline)
_objRange.BorderAround2(Type.Missing, Excel.XlBorderWeight.xlThin, Excel.XlColorIndex.xlColorIndexAutomatic);
if (bHorizontal)
_objRange.Borders[Excel.XlBordersIndex.xlInsideHorizontal].LineStyle = Excel.XlLineStyle.xlContinuous;
if (bVertical)
_objRange.Borders[Excel.XlBordersIndex.xlInsideVertical].LineStyle = Excel.XlLineStyle.xlContinuous;
return true;
}
///
/// 엑셀상 셀 주소를 반환합니다.
///
/// 열 번호
/// 행 번호
/// 셀 주소
public static string CellAddress(int iRow, int iCol)
{
string strReturn = DecToAlphabet(iCol - 1);
strReturn += iRow;
return strReturn;
}
#endregion
private static bool ReleaseExcelObject(object objObject)
{
try
{
if (objObject != null)
{
Marshal.ReleaseComObject(objObject);
objObject = null;
return false;
}
else
{
return true;
}
}
catch (Exception ex)
{
objObject = null;
throw ex;
}
finally
{
GC.Collect();
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool bDisposing)
{
if (_bDisposed)
return;
if (bDisposing)
_objSafeHandler.Dispose();
_bDisposed = true;
}
///
/// 정수형 숫자를 문자열 형태로 변환하여 반환합니다.
/// 반환되는 문자열 형태는 엑셀의 컬럼명 형태입니다.
///
/// 변환할 int형
/// 변환된 문자열
public static string DecToAlphabet(int iDec)
{
int iRest;
string alphabet;
byte[] asciiA = Encoding.ASCII.GetBytes("A");
iRest = iDec % 26;
asciiA[0] += (byte)iRest;
alphabet = Encoding.ASCII.GetString(asciiA);
iDec = iDec / 26 - 1;
if (iDec > -1)
{
alphabet = alphabet.Insert(0, DecToAlphabet(iDec));
}
return alphabet;
}
}
}