using System; using System.Data; using System.Data.OleDb; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Windows.Forms; using Excel = Microsoft.Office.Interop.Excel; namespace CoreUnit.Common { public class ExcelManagementUnit { /// /// Excel Database Control Class /// version 0.1.5 /// /// /// 자유배포 /// 황현우 [ LiA's Blog ] /// http://blog.naver.com/exila /// CoreBank Co.,Ltd. /// 불펌금지효.. 만든 사람의 성의좀 생각을..-_-;; /// /*--------------------------------------------------------------------- * Connection String 에는 어마어마한 옵션들이.. 주로 영문 사이트이긴 * 하지만 좀더 상세한 제어를 원한다면 OleDB Connection String 옵션과 * Extended Properties 에 들어가는 Excel Option 들을 살펴보는 것이 좋을 * 듯.. HDR = 첫줄을 헤더로 사용할 것인지,IMEX = 데이터유형적용여부 등등 *-------------------------------------------------------------------*/ // 확장명 XLS (Excel 97~2003 용) private const string ConnectStrFrm_Excel97_2003 = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=\"{0}\";" + "Mode=ReadWrite|Share Deny None;" + "Extended Properties='Excel 8.0; HDR={1}; IMEX={2}';" + "Persist Security Info=False"; // 확장명 XLSX (Excel 2007 이상용) private const string ConnectStrFrm_Excel = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=\"{0}\";" + "Mode=ReadWrite|Share Deny None;" + "Extended Properties='Excel 12.0; HDR={1}; IMEX={2}';" + "Persist Security Info=False"; /// /// Excel 파일의 형태를 반환한다. /// -2 : Error /// -1 : 엑셀파일아님 /// 0 : 97-2003 엑셀 파일 (xls) /// 1 : 2007 이상 파일 (xlsx) /// /// /// Excel File 명 전체 경로입니다. /// public static int ExcelFileType(string XlsFile) { byte[,] ExcelHeader = { { 0xD0, 0xCF, 0x11, 0xE0, 0xA1 }, // XLS File Header { 0x50, 0x4B, 0x03, 0x04, 0x14 } // XLSX File Header }; // result -2=error, -1=not excel , 0=xls , 1=xlsx int result = -1; FileInfo FI = new FileInfo(XlsFile); FileStream FS = FI.Open(FileMode.Open); try { byte[] FH = new byte[5]; FS.Read(FH, 0, 5); for (int i = 0; i < 2; i++) { for (int j = 0; j < 5; j++) { if (FH[j] != ExcelHeader[i, j]) break; else if (j == 4) result = i; } if (result >= 0) break; } } catch { result = (-2); //throw e; } finally { FS.Close(); } return result; } /// /// Excel 파일을 DataSet 으로 변환하여 반환한다. /// /// /// Excel File 명 PullPath /// /// /// 첫번째 줄을 Field 명으로 사용할 것이지 여부 /// private static DataSet OpenExcel(string FileName, bool UseHeader) { DataSet DS = null; string[] HDROpt = { "NO", "YES" }; string HDR = ""; string ConnStr = ""; if (UseHeader) HDR = HDROpt[1]; else HDR = HDROpt[0]; int ExcelType = ExcelFileType(FileName); switch (ExcelType) { case (-2): throw new Exception(FileName + "의 형식검사중 오류가 발생하였습니다."); case (-1): throw new Exception(FileName + "은 엑셀 파일형식이 아닙니다."); case (0): ConnStr = string.Format(ConnectStrFrm_Excel97_2003, FileName, HDR, "1"); break; case (1): ConnStr = string.Format(ConnectStrFrm_Excel, FileName, HDR, "1"); break; } OleDbConnection OleDBConn = null; OleDbDataAdapter OleDBAdap = null; DataTable Schema; try { OleDBConn = new OleDbConnection(ConnStr); OleDBConn.Open(); Schema = OleDBConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); DS = new DataSet(); foreach (DataRow DR in Schema.Rows) { OleDBAdap = new OleDbDataAdapter(DR["TABLE_NAME"].ToString(), OleDBConn); OleDBAdap.SelectCommand.CommandType = CommandType.TableDirect; OleDBAdap.AcceptChangesDuringFill = false; string TableName = DR["TABLE_NAME"].ToString().Replace("$", String.Empty).Replace("'", String.Empty); if (DR["TABLE_NAME"].ToString().Contains("$")) OleDBAdap.Fill(DS, TableName); } } catch (Exception e) { throw e; } finally { if (OleDBConn != null) OleDBConn.Close(); } return DS; } /// /// DataSet 을 Excel 파일로 저장한다. /// /// /// Excel File 명 PullPath /// /// /// Excel 로 저장할 대상 DataSet 객체. /// /// /// 동일한 파일명이 있을 때 삭제 할 것인지 여부, 파일이 있고 false 면 저장안하고 그냥 false 를 리턴. /// /// /// xls 형태로 저장할 것인지 여부, false 이면 xlsx 형태로 저장함. /// private static bool SaveExcel(string FileName, DataSet DS, bool ExistDel, bool OldExcel) { bool result = true; if (File.Exists(FileName)) if (ExistDel) File.Delete(FileName); else return result; string TempFile = FileName; // 파일 확장자가 xls 이나 xlsx 가 아니면 아예 파일을 안만들어서 // 템프파일로 생성후 지정한 파일명으로 변경.. OleDbConnection OleDBConn = null; try { OleDbCommand Cmd = null; string ConnStr = ""; if (OldExcel) { TempFile = TempFile + ".xls"; ConnStr = string.Format(ConnectStrFrm_Excel97_2003, TempFile, "YES", "0"); } else { TempFile = TempFile + ".xlsx"; ConnStr = string.Format(ConnectStrFrm_Excel, TempFile, "YES", "0"); } OleDBConn = new OleDbConnection(ConnStr); OleDBConn.Open(); // Create Table(s).. : 테이블 단위 처리 foreach (DataTable DT in DS.Tables) { String TableName = DT.TableName; StringBuilder FldsInfo = new StringBuilder(); StringBuilder Flds = new StringBuilder(); // Create Field(s) String : 현재 테이블의 Field 명 생성 foreach (DataColumn Column in DT.Columns) { if (FldsInfo.Length > 0) { FldsInfo.Append(","); Flds.Append(","); } FldsInfo.Append("[" + Column.ColumnName.Replace("'", "''") + "] CHAR(255)"); Flds.Append(Column.ColumnName.Replace("'", "''")); } // Table Create Cmd = new OleDbCommand("CREATE TABLE " + TableName + "(" + FldsInfo.ToString() + ")", OleDBConn); Cmd.ExecuteNonQuery(); // Insert Data foreach (DataRow DR in DT.Rows) { StringBuilder Values = new StringBuilder(); foreach (DataColumn Column in DT.Columns) { if (Values.Length > 0) Values.Append(","); Values.Append("'" + DR[Column.ColumnName].ToString().Replace("'", "''") + "'"); } Cmd = new OleDbCommand( "INSERT INTO [" + TableName + "$]" + "(" + Flds.ToString() + ") " + "VALUES (" + Values.ToString() + ")", OleDBConn); Cmd.ExecuteNonQuery(); } } } catch (Exception) { result = false; } finally { if (OleDBConn != null) OleDBConn.Close(); try { if (File.Exists(TempFile)) { File.Move(TempFile, FileName); } } catch { } } return result; } /// /// Excel 파일을 DataSet 으로 변환하여 반환한다. /// /// /// 읽어올 Excel File 명(전체경로)입니다. /// public static DataSet OpenExcelDB(string ExcelFile) { return OpenExcel(ExcelFile, true); } /// /// DataSet 을 Excel 파일로 저장한다. 동일 파일명이 있으면 Overwrite 됩니다. /// /// /// 저장할 Excel File 명(전체경로)입니다. /// /// /// 저장할 대상 DataSet 입니다. /// public static bool SaveExcelDB(string ExcelFile, DataSet DS) { return SaveExcel(ExcelFile, DS, true, false); } public static DataTable ImportFromExcel(string path, bool isFirstRowHeader = true) { //Create COM Objects. Create a COM object for everything that is referenced Excel.Application xlApp = new Excel.Application(); Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(path); Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1]; Excel.Range xlRange = xlWorksheet.UsedRange; DataTable table = new DataTable(); int rowCount = xlRange.Rows.Count; int colCount = xlRange.Columns.Count; object[,] valueArray = (object[,])xlRange.get_Value(Excel.XlRangeValueDataType.xlRangeValueDefault); int startRow = 1; if (isFirstRowHeader == true) { foreach (var col in Enumerable.Range(1, valueArray.GetLength(1))) { table.Columns.Add(valueArray[startRow, col].ToString()); } startRow++; } else { foreach (var col in Enumerable.Range(1, valueArray.GetLength(1))) { table.Columns.Add(); } } foreach (var row in Enumerable.Range(startRow, valueArray.GetLength(0) - startRow + 1)) { table.Rows.Add(Enumerable.Range(1, valueArray.GetLength(1)).Select(col => valueArray[row, col]).ToArray()); } //cleanup GC.Collect(); GC.WaitForPendingFinalizers(); //rule of thumb for releasing com objects: // never use two dots, all COM objects must be referenced and released individually // ex: [somthing].[something].[something] is bad //release com objects to fully kill excel process from running in the background Marshal.ReleaseComObject(xlRange); Marshal.ReleaseComObject(xlWorksheet); //close and release xlWorkbook.Close(); Marshal.ReleaseComObject(xlWorkbook); //quit and release xlApp.Quit(); Marshal.ReleaseComObject(xlApp); return table; } public static void ExportToExcel(string path, DataTable table) { if (path.Substring(path.Length - 5, 5).Contains(".xls") == false) { path += ".xlsx"; } try { if (Directory.Exists(Path.GetDirectoryName(path)) == false) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } var excelApp = new Excel.Application(); excelApp.Workbooks.Add(); Excel._Worksheet workSheet = (Excel._Worksheet)excelApp.ActiveSheet; for (var i = 0; i < table.Columns.Count; i++) { workSheet.Cells[1, i + 1] = table.Columns[i].ColumnName; } for (var i = 0; i < table.Rows.Count; i++) { for (var j = 0; j < table.Columns.Count; j++) { workSheet.Cells[i + 2, j + 1] = table.Rows[i][j]; } } if (File.Exists(path)) { File.Delete(path); } workSheet.SaveAs(path); excelApp.Quit(); } catch (Exception ex) { MessageBox.Show(string.Format("fail to save excel file.\n{0}"), ex.Message); } } public static DataTable ImportFromCsv(string path, bool isFirstRowHeader = true) { DataTable table = new DataTable(); StreamReader reader = new StreamReader(path); string[] headers = reader.ReadLine().Split('\t'); if (isFirstRowHeader == true) { foreach (string header in headers) { table.Columns.Add(header); } } else { foreach (string header in headers) { table.Columns.Add(); } reader = new StreamReader(path); } while (!reader.EndOfStream) { // string[] rows = Regex.Split(reader.ReadLine(), ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"); string[] rows = Regex.Split(reader.ReadLine(), "\t"); DataRow dataRow = table.NewRow(); for (int i = 0; i < headers.Length; i++) { dataRow[i] = rows[i]; } table.Rows.Add(dataRow); } reader.Close(); return table; //string header = isFirstRowHeader ? "Yes" : "No"; //string pathOnly = Path.GetDirectoryName(path); //string fileName = Path.GetFileName(path); //string sql = @"SELECT * FROM [" + fileName + "]"; //using (OleDbConnection connection = new OleDbConnection( // @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly + // ";Extended Properties=\"Text;HDR=" + header + "\"")) //using (OleDbCommand command = new OleDbCommand(sql, connection)) //using (OleDbDataAdapter adapter = new OleDbDataAdapter(command)) //{ // DataTable dataTable = new DataTable(); // dataTable.Locale = CultureInfo.CurrentCulture; // adapter.Fill(dataTable); // return dataTable; //} } public static DataTable ImportDataFromCsv(string path, bool isFirstRowHeader = true) { DataTable table = new DataTable(); StreamReader reader = new StreamReader(path); string[] headers = reader.ReadLine().Split(','); if (isFirstRowHeader == true) { foreach (string header in headers) { table.Columns.Add(new DataColumn(header.Trim(), typeof(double))); ; } } else { foreach (string header in headers) { table.Columns.Add(); } reader = new StreamReader(path); } while (!reader.EndOfStream) { // string[] rows = Regex.Split(reader.ReadLine(), ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"); string[] rows = Regex.Split(reader.ReadLine(), ","); DataRow dataRow = table.NewRow(); object[] rowArray; rowArray = new object[headers.Length]; for (int i = 0; i < headers.Length; i++) { double temp = 0; if (double.TryParse(rows[i], out temp)) rowArray[i] = temp; //dataRow[i] = rows[i]; } dataRow.ItemArray = rowArray; table.Rows.Add(dataRow); } return table; //string header = isFirstRowHeader ? "Yes" : "No"; //string pathOnly = Path.GetDirectoryName(path); //string fileName = Path.GetFileName(path); //string sql = @"SELECT * FROM [" + fileName + "]"; //using (OleDbConnection connection = new OleDbConnection( // @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly + // ";Extended Properties=\"Text;HDR=" + header + "\"")) //using (OleDbCommand command = new OleDbCommand(sql, connection)) //using (OleDbDataAdapter adapter = new OleDbDataAdapter(command)) //{ // DataTable dataTable = new DataTable(); // dataTable.Locale = CultureInfo.CurrentCulture; // adapter.Fill(dataTable); // return dataTable; //} } public static void ExportToCSV(string path, DataTable table) { if (path.Substring(path.Length - 4, 4).Contains(".csv") == false) { path += ".csv"; } try { if (Directory.Exists(Path.GetDirectoryName(path)) == false) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } StreamWriter sw = new StreamWriter(path, false); string columnHeader = ""; for (int i = 0; i < table.Columns.Count; i++) { columnHeader += table.Columns[i].ColumnName + (i != table.Columns.Count - 1 ? ", " : ""); } sw.WriteLine(columnHeader); string strText; for (int i = 0; i < table.Rows.Count; i++) { strText = ""; for (int j = 0; j < table.Columns.Count; j++) { strText += table.Rows[i][j].ToString() + ","; } sw.WriteLine(strText); } sw.Close(); } catch (Exception ex) { MessageBox.Show(string.Format("fail to save csv file.\n{0}", ex.Message)); } } public static void ExportToCSVAdd(string path, DataTable table) { bool fileExist; if (path.Substring(path.Length - 4, 4).Contains(".csv") == false) { path += ".csv"; } try { if (Directory.Exists(Path.GetDirectoryName(path)) == false) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } fileExist = File.Exists(path); StreamWriter sw = new StreamWriter(path, fileExist, Encoding.Unicode); if (!fileExist) { string columnHeader = ""; for (int i = 0; i < table.Columns.Count; i++) { columnHeader += table.Columns[i].ColumnName + (i != table.Columns.Count - 1 ? " \t" : ""); } sw.WriteLine(columnHeader); } string strText; for (int i = 0; i < table.Rows.Count; i++) { strText = ""; for (int j = 0; j < table.Columns.Count; j++) { strText += table.Rows[i][j].ToString() + "\t"; } sw.WriteLine(strText); } sw.Close(); } catch (Exception ex) { MessageBox.Show(string.Format("fail to save csv file Add.\n{0}", ex.Message)); } } public static void AppendStringInCSV(string path, string strItem, string strData, bool useCellTracker = true) { if (path.Substring(path.Length - 4, 4).Contains(".csv") == false) { path += ".csv"; } try { bool isFile = false; if (false == File.Exists(path)) { isFile = true; Directory.CreateDirectory(Path.GetDirectoryName(path)); } // 다른 프로세스도 파일 읽고 쓸 수 있도록. FileStream FileStream = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); StreamWriter sw = new StreamWriter(FileStream, System.Text.Encoding.Unicode); // 26.04.15 기존 코드 주석처리함 //StreamWriter sw = new StreamWriter(FileStream, System.Text.Encoding.UTF8); // 26.04.15 변경 코드 UTF8로 변경 log 깨짐 현상 if (isFile) { sw.WriteLine(strItem); } sw.WriteLine(strData); sw.Flush(); sw.Close(); FileStream.Close(); } catch (Exception ex) { MessageBox.Show(string.Format("fail to save csv file.\n{0}", ex.Message)); } } public static void ExportToLDDFileCSV(string path, DataTable table) { if (path.Substring(path.Length - 4, 4).Contains(".csv") == false) { path += ".csv"; } try { if (Directory.Exists(Path.GetDirectoryName(path)) == false) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } StreamWriter sw = new StreamWriter(path, false); //우선 선언해두고 다른데서 받아오는걸로 변경하자 double dLDDFileVersion = 1.0; string sLDDFileType = "Path Coordinates"; double dLDDRecordTime = 0.00001; sw.WriteLine($"File Version: {dLDDFileVersion}"); sw.WriteLine($"File Type: {sLDDFileType}"); sw.WriteLine($"Timebase (s): {dLDDRecordTime.ToString("F6")}"); sw.WriteLine(); string columnHeader = ""; for (int i = 0; i < table.Columns.Count; i++) { columnHeader += table.Columns[i].ColumnName + (i != table.Columns.Count - 1 ? ", " : ""); } sw.WriteLine(columnHeader); string strText; for (int i = 0; i < table.Rows.Count; i++) { strText = ""; for (int j = 0; j < table.Columns.Count; j++) { strText += table.Rows[i][j].ToString() + ","; } sw.WriteLine(strText); } sw.Close(); } catch (Exception ex) { MessageBox.Show(string.Format("fail to save csv file.\n{0}", ex.Message)); } } } }