using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO; 
using System.Windows.Forms;
using NPOI;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Repository.Models;

namespace tpDomeWinAPP.Service
{
    public static class ioExcel
    {

        /// <summary>  
        /// 將excel匯入到datatable  
        /// </summary>          
        /// <param name="nosqllist">存放資料庫取出的編號list</param>
        /// <param name="msge">返回結果</param>
        /// <returns>返回datatable</returns>  
        public static DataTable ExcelToDataTable(List<string> nosqllist, out string msge, out string filename)
        {
            bool isColumnName = true;//第一行是否是列名
            msge = "0";
            string filePath = "";//excel路徑
            List<string> NoList = new List<string>();//儲存編號,防止重複
            //開啟檔案對話方塊選擇檔案
            OpenFileDialog file = new OpenFileDialog();
            filename = string.Empty;
            file.Filter = "Excel(*.xlsx)|*.xlsx|Excel(*.xls)|*.xls";
            file.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            file.Multiselect = false;
            if (file.ShowDialog() == DialogResult.OK)
            {
                filePath = file.FileName;
                filename = file.FileName;
            }
            DataTable dataTable = null;
            FileStream fs = null;
            DataColumn column = null;
            DataRow dataRow = null;
            IWorkbook workbook = null;
            ISheet sheet = null;
            IRow row = null;
            ICell cell = null;
            IRow rowisrepeat = null;
            ICell cellisrepeat = null;
            int startRow = 0;
            dataTable = new DataTable();
            try
            {
                using (fs = File.OpenRead(filePath))
                {
                    // 2007版本  
                    if (filePath.IndexOf(".xlsx") > 0)
                        workbook = new XSSFWorkbook(fs);
                    // 2003版本  
                    else if (filePath.IndexOf(".xls") > 0)
                        workbook = new HSSFWorkbook(fs);
                    int sheetSerial = -1;
                   
                    #region 構建 datatable的列
                    column = new DataColumn("sheetname");
                    dataTable.Columns.Add(column);
                    column = new DataColumn("tag_name_zh");
                    dataTable.Columns.Add(column);
                    column = new DataColumn("old_tags");
                    dataTable.Columns.Add(column);
                    column = new DataColumn("new_tags");
                    dataTable.Columns.Add(column);
                    column = new DataColumn("floor");
                    dataTable.Columns.Add(column);
                    column = new DataColumn("device_name");
                    dataTable.Columns.Add(column);
                    column = new DataColumn("device_note");
                    dataTable.Columns.Add(column);
                    column = new DataColumn("device_type");
                    dataTable.Columns.Add(column);
                    column = new DataColumn("device_number");
                    dataTable.Columns.Add(column);
                    //if (isColumnName)
                    //{
                    //    startRow = 1;//如果第一行是列名,則從第二行開始讀取  
                    //    for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
                    //    {
                    //        cell = firstRow.GetCell(i);
                    //        if (cell != null)
                    //        {
                    //            if (cell.StringCellValue != null)
                    //            {
                    //                column = new DataColumn(cell.StringCellValue);
                    //                dataTable.Columns.Add(column);
                    //            }
                    //        }
                    //    }
                    //}
                    //else
                    //{
                    //    for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
                    //    {
                    //        column = new DataColumn("column" + (i + 1));
                    //        dataTable.Columns.Add(column);
                    //    }
                    //}
                    #endregion

                    foreach (var item in workbook)
                    {
                        sheetSerial += 1;
                        if (sheetSerial < 2) continue;

                        if (workbook != null)
                        {
                            //sheet = workbook.GetSheetAt(0);//讀取第一個sheet,當然也可以迴圈讀取每個sheet  
                            sheet = item;
                            
                            if (sheet != null)
                            {
                                int rowCount = sheet.LastRowNum;//總行數  
                                if (rowCount > 0)
                                {
                                    IRow firstRow = sheet.GetRow(0);//第一行 

                                    if (firstRow == null) continue;
                                    #region 判斷列名是否一致

                                        //string[] exlist = GetStringNum();//得到定義的標題
                                        //for (int i = 0; i < exlist.Length; i++)
                                        //{
                                        //    if (Convert.ToString(firstRow.Cells[i]) != exlist[i])
                                        //    {
                                        //        msge = "第" + i + 1 + "列標題不是" + exlist[i] + ",列標題錯誤!";
                                        //        return dataTable;
                                        //    }
                                        //}
                                        #endregion

                                        //int cellCount = firstRow.LastCellNum;//列數   

                                        #region 判斷編號是否有重複
                                        //NoList = nosqllist; 
                                        //for (int i = startRow; i <= rowCount; ++i)
                                        //{
                                        //    rowisrepeat = sheet.GetRow(i);
                                        //    if (rowisrepeat == null) continue;
                                        //    cellisrepeat = rowisrepeat.GetCell(13);
                                        //    string noisrpt = Convert.ToString(cellisrepeat);
                                        //    if (!NoList.Contains(noisrpt))
                                        //    {
                                        //        NoList.Add(noisrpt);
                                        //    }
                                        //    else
                                        //    {
                                        //        msge = "編號:" + noisrpt + "重複,插入失敗,請確定編號唯一、無重複!";
                                        //        return dataTable;
                                        //    }
                                        //}
                                        #endregion

                                        if (firstRow.Cells.Count >=6 )
                                        {
                                       // MessageBox.Show("firstRow.Cells.Count = "+ firstRow.Cells.Count.ToString());
                                    
                                         if (firstRow.Cells[2].ToString() == "tags name" && firstRow.Cells[3].ToString() == "New Tagname")
                                        {
                                            #region 填充行
                                            for (int i = startRow; i <= rowCount; ++i)
                                            {
                                                if (i == 0) continue; //第一行是欄位 不使用
                                                row = sheet.GetRow(i);
                                                if (row == null) continue;

                                                if (row.GetCell(2) == null || string.IsNullOrEmpty(row.GetCell(2).ToString().Trim())) continue;

                                                dataRow = dataTable.NewRow();
                                                //for (int j = row.FirstCellNum; j < cellCount; ++j)
                                                for (int j = row.FirstCellNum; j <= 6; ++j)
                                                {
                                                    if (j == 0) {
                                                        dataRow[j] = sheet.SheetName;
                                                        continue;
                                                    }
                                                    cell = row.GetCell(j);
                                                    if (cell == null)
                                                    {
                                                        dataRow[j] = "";
                                                    }
                                                    else
                                                    { 
                                                        //CellType(Unknown = -1,Numeric = 0,String = 1,Formula = 2,Blank = 3,Boolean = 4,Error = 5,)  
                                                        switch (cell.CellType)
                                                        {
                                                            case CellType.Blank:
                                                                dataRow[j] = "";
                                                                break;
                                                            case CellType.Numeric:
                                                                short format = cell.CellStyle.DataFormat;
                                                                //對時間格式(2015.12.5、2015/12/5、2015-12-5等)的處理  
                                                                if (format == 14 || format == 31 || format == 57 || format == 58)
                                                                    dataRow[j] = cell.DateCellValue;
                                                                else
                                                                    dataRow[j] = cell.NumericCellValue;
                                                                break;
                                                            case CellType.String:
                                                                //if (cell.StringCellValue == "C_B_B5F_GT_B51")
                                                                //{
                                                                //    MessageBox.Show("C_B_B5F_GT_B51");
                                                                //}
                                                                dataRow[j] = cell.StringCellValue;
                                                                break;
                                                        }
                                                        
                                                    }
                                                }
                                                dataTable.Rows.Add(dataRow);
                                            }
                                            #endregion
                                        }
                                        else continue;
                                    }//if (firstRow.Cells.Count >=3 )
                                }
                            }
                        }
                    } 
                }
                return dataTable;
            }
            catch (Exception e)
            {
                int i  = dataTable.Rows.Count;
                msge =  e.Message;
                if (fs != null)
                {
                    fs.Close();
                }
                return null;
            }
        }

       

        /// <summary>
        /// 定義待驗證的Excel標題
        /// </summary>
        /// <returns></returns>
        private static string[] GetStringNum()
        {
            string[] ExcelHeadList = new string[15] { "欄位1", "欄位2", "欄位3", "欄位4", "欄位5", "欄位6", "欄位7", "欄位8", "欄位9", "欄位10", "欄位11", "欄位12", "欄位13", "欄位14", "欄位15" };
            return ExcelHeadList;
        }


        #region 匯出 Excel 模板
        /// <summary>
        /// 匯出 Excel模板
        /// </summary>
        public static void ExportExampleToExcel()
        {
            DataTable TableName = new DataTable();
            TableName.Columns.Add("欄位1", typeof(string));
            TableName.Columns.Add("欄位2", typeof(string));
            TableName.Columns.Add("欄位3", typeof(string));
            TableName.Columns.Add("欄位4", typeof(string));
            TableName.Columns.Add("欄位5", typeof(string));
            TableName.Columns.Add("欄位6", typeof(string));
            TableName.Columns.Add("欄位7", typeof(string));
            TableName.Columns.Add("欄位8", typeof(string));
            TableName.Columns.Add("欄位9", typeof(string));
            TableName.Columns.Add("欄位10", typeof(string));
            TableName.Columns.Add("欄位12", typeof(string));
            TableName.Columns.Add("欄位13", typeof(string));
            TableName.Columns.Add("欄位14", typeof(string));
            TableName.Columns.Add("欄位15", typeof(string));
            TableName.Columns.Add("欄位16", typeof(string));

            string FileName = "模板資訊匯入Excel模板";
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            //設定檔案標題
            saveFileDialog.Title = "匯出Excel檔案";
            //設定檔案型別
            saveFileDialog.Filter = "Excel 工作簿(*.xlsx)|*.xlsx|Excel 97-2003 工作簿(*.xls)|*.xls";
            //設定預設檔案型別顯示順序  
            saveFileDialog.FilterIndex = 1;
            //是否自動在檔名中新增副檔名
            saveFileDialog.AddExtension = true;
            //是否記憶上次開啟的目錄
            saveFileDialog.RestoreDirectory = true;
            //設定預設檔名
            saveFileDialog.FileName = FileName;
            //按下確定選擇的按鈕  
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                //獲得檔案路徑 
                string localFilePath = saveFileDialog.FileName.ToString();

                //資料初始化
                int TotalCount;     //總行數
                int RowRead = 0;    //已讀行數
                int Percent = 0;    //百分比

                TotalCount = 15;

                //NPOI
                IWorkbook workbook;
                string FileExt = Path.GetExtension(localFilePath).ToLower();
                if (FileExt == ".xlsx")
                {
                    workbook = new XSSFWorkbook();
                }
                else if (FileExt == ".xls")
                {
                    workbook = new HSSFWorkbook();
                }
                else
                {
                    workbook = null;
                }
                if (workbook == null)
                {
                    return;
                }
                ISheet sheet = string.IsNullOrEmpty(FileName) ? workbook.CreateSheet("Sheet1") : workbook.CreateSheet(FileName);


                //秒鐘
                Stopwatch timer = new Stopwatch();
                timer.Start();

                try
                {
                    //讀取標題  
                    IRow rowHeader = sheet.CreateRow(0);
                    for (int i = 0; i < TableName.Columns.Count; i++)
                    {
                        ICell cell = rowHeader.CreateCell(i);
                        cell.SetCellValue(TableName.Columns[i].ColumnName);
                    }

                    Application.DoEvents();

                    //轉為位元組陣列  
                    MemoryStream stream = new MemoryStream();
                    workbook.Write(stream);
                    var buf = stream.ToArray();

                    //儲存為Excel檔案  
                    using (FileStream fs = new FileStream(localFilePath, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(buf, 0, buf.Length);
                        fs.Flush();
                        fs.Close();
                    }
                    Application.DoEvents();

                    //關閉秒鐘
                    timer.Reset();
                    timer.Stop();

                    //成功提示
                    if (MessageBox.Show("匯出成功,是否立即開啟?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
                    {
                        System.Diagnostics.Process.Start(localFilePath);
                    }

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                finally
                {
                    //關閉秒鐘
                    timer.Reset();
                    timer.Stop();
                }
            }
        }
        #endregion

        #region 匯出 Excel
        /// <summary>
        /// 匯出Excel
        /// </summary>
        /// <param name="TableName"></param>
        public static void ExportDataToExcel(DataTable TableName)
        {
            string FileName = DateTime.Now.GetHashCode().ToString();
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            //設定檔案標題
            saveFileDialog.Title = "匯出Excel檔案";
            //設定檔案型別
            saveFileDialog.Filter = "Excel 工作簿(*.xlsx)|*.xlsx|Excel 97-2003 工作簿(*.xls)|*.xls";
            //設定預設檔案型別顯示順序  
            saveFileDialog.FilterIndex = 1;
            //是否自動在檔名中新增副檔名
            saveFileDialog.AddExtension = true;
            //是否記憶上次開啟的目錄
            saveFileDialog.RestoreDirectory = true;
            //設定預設檔名
            saveFileDialog.FileName = FileName;
            //按下確定選擇的按鈕  
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                //獲得檔案路徑 
                string localFilePath = saveFileDialog.FileName.ToString();

                //資料初始化
                int TotalCount;     //總行數
                int RowRead = 0;    //已讀行數
                int Percent = 0;    //百分比

                TotalCount = TableName.Rows.Count;

                //NPOI
                IWorkbook workbook;
                string FileExt = Path.GetExtension(localFilePath).ToLower();
                if (FileExt == ".xlsx")
                {
                    workbook = new XSSFWorkbook();
                }
                else if (FileExt == ".xls")
                {
                    workbook = new HSSFWorkbook();
                }
                else
                {
                    workbook = null;
                }
                if (workbook == null)
                {
                    return;
                }
                ISheet sheet = string.IsNullOrEmpty(FileName) ? workbook.CreateSheet("Sheet1") : workbook.CreateSheet(FileName);


                //秒鐘
                Stopwatch timer = new Stopwatch();
                timer.Start();

                try
                {
                    //讀取標題  
                    IRow rowHeader = sheet.CreateRow(0);
                    for (int i = 0; i < TableName.Columns.Count; i++)
                    {
                        ICell cell = rowHeader.CreateCell(i);
                        cell.SetCellValue(TableName.Columns[i].ColumnName);
                    }

                    //讀取資料  
                    for (int i = 0; i < TableName.Rows.Count; i++)
                    {
                        IRow rowData = sheet.CreateRow(i + 1);
                        for (int j = 0; j < TableName.Columns.Count; j++)
                        {
                            ICell cell = rowData.CreateCell(j);
                            cell.SetCellValue(TableName.Rows[i][j].ToString());
                        }
                        //狀態列顯示
                        RowRead++;
                        Percent = (int)(100 * RowRead / TotalCount);
                        Application.DoEvents();
                    }

                    Application.DoEvents();

                    //轉為位元組陣列  
                    MemoryStream stream = new MemoryStream();
                    workbook.Write(stream);
                    var buf = stream.ToArray();

                    //儲存為Excel檔案  
                    using (FileStream fs = new FileStream(localFilePath, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(buf, 0, buf.Length);
                        fs.Flush();
                        fs.Close();
                    }
                    Application.DoEvents();

                    //關閉秒鐘
                    timer.Reset();
                    timer.Stop();

                    //成功提示
                    if (MessageBox.Show("匯出成功,是否立即開啟?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
                    {
                        System.Diagnostics.Process.Start(localFilePath);
                    }

                }
                catch (Exception ex)
                {
                    throw ex;
                    //MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                finally
                {
                    //關閉秒鐘
                    timer.Reset();
                    timer.Stop();
                }
            }
        }
        #endregion
    }
}