using System;
using System.Collections.Generic;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Data;
using KGIS.Framework.Platform;
using System.IO;
using KGIS.Framework.Utils.ExtensionMethod;
using HorizontalAlignment = NPOI.SS.UserModel.HorizontalAlignment;
using FileStream = System.IO.FileStream;
namespace Kingo.PluginServiceInterface.Helper.NPOIHelper
{
    /// 
    /// NPOI表格操作帮助类
    /// 
    public class NPOIExcelHelper
    {
        /// 
        /// 临时模板中的数据导入到指定文件夹内(有序创建)
        /// 
        /// 临时表格路径
        /// 自定义导出路径
        /// 数据表
        /// 权属字典集合
        public static void WriteExcelToXLSX(string XSSTempPath, string XSSPath, DataTable ViewTableTemp, List dicList)
        {
            try
            {
                FileStream FileStream = new FileStream(XSSTempPath, FileMode.Open, FileAccess.ReadWrite);
                IWorkbook workbook = new XSSFWorkbook(FileStream);
                ISheet sheet = workbook.GetSheetAt(0);
                var style = workbook.CreateCellStyle();
                style.Alignment = HorizontalAlignment.Center;
                style.BorderBottom = BorderStyle.Thin;
                style.BorderTop = BorderStyle.Thin;
                style.BorderRight = BorderStyle.Thin;
                style.BorderLeft = BorderStyle.Thin;
                if (ViewTableTemp == null || ViewTableTemp.Rows.Count == 0 || dicList == null)
                    return;
                DataColumnCollection fields = ViewTableTemp.Columns;
                for (int i = 0; i < ViewTableTemp.Rows.Count; i++)
                {
                    IRow row1 = sheet.CreateRow(i + 6);
                    for (int j = 0; j < fields.Count; j++)
                    {
                        ICell cell = row1.CreateCell(j + 1);
                        cell.CellStyle = style;
                        cell.SetCellValue(ViewTableTemp.Rows[i][fields[j]].ToDouble());
                    }
                }
                MemoryStream ms = new MemoryStream();
                workbook.Write(ms);
                using (FileStream fs = new FileStream(XSSPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
                {
                    byte[] b = ms.ToArray();
                    fs.Write(b, 0, b.Length);
                    ms.Close();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// 
        /// 自定义表格数据(无序创建)
        /// 
        /// 临时表格路径
        /// 自定义导出路径
        /// 数据表
        public static void WriteExcelToXLSX(string XSSTempPath, string XSSPath, DataTable ViewTableTemp)
        {
            try
            {
                FileStream FileStream = new FileStream(XSSTempPath, FileMode.Open, FileAccess.ReadWrite);
                IWorkbook workbook = new XSSFWorkbook(FileStream);
                ISheet sheet = workbook.GetSheetAt(0);
                var style = workbook.CreateCellStyle();
                style.Alignment = HorizontalAlignment.Center;
                style.VerticalAlignment = VerticalAlignment.Center;
                style.BorderBottom = BorderStyle.Thin;
                style.BorderTop = BorderStyle.Thin;
                style.BorderRight = BorderStyle.Thin;
                style.BorderLeft = BorderStyle.Thin;
                IFont headerFont = workbook.CreateFont();
                headerFont.FontName = "宋体";
                headerFont.FontHeightInPoints = 10;
                style.SetFont(headerFont);
                if (ViewTableTemp == null || ViewTableTemp.Rows.Count == 0)
                    return;
                DataColumnCollection fields = ViewTableTemp.Columns;
                foreach (DataRow row in ViewTableTemp.Rows)
                {
                    var x = Convert.ToInt32(row["Cells_X"]);
                    var y = Convert.ToInt32(row["Cells_Y"]);
                    var value = row["BGMJ"].ToDouble();
                    if (sheet.GetRow(x) != null)
                    {
                        IRow row1 = sheet.GetRow(x);
                        ICell cell = row1.CreateCell(y);
                        cell.CellStyle = style;
                        cell.SetCellValue(value);
                    }
                    else
                    {
                        IRow row1 = sheet.CreateRow(x);
                        ICell cell = row1.CreateCell(y);
                        cell.CellStyle = style;
                        cell.SetCellValue(value);
                    }
                }
                //执行计算公式
                ICreationHelper creationHelper = workbook.GetCreationHelper();
                var evaluator = creationHelper.CreateFormulaEvaluator();
                evaluator?.EvaluateAll();
                MemoryStream ms = new MemoryStream();
                workbook.Write(ms);
                using (FileStream fs = new FileStream(XSSPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
                {
                    byte[] b = ms.ToArray();
                    fs.Write(b, 0, b.Length);
                    ms.Close();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// 
        /// 村级土地利用表导出_主表数据(无序创建)
        /// 
        /// 临时表格路径
        /// 自定义导出路径
        /// 数据表
        public static void WriteExcelToXLSX(ref IWorkbook workbook, DataTable ViewTableTemp, string XSSPath = "")
        {
            try
            {
                ISheet sheet = workbook.GetSheetAt(0);
                var style = workbook.CreateCellStyle();
                style.Alignment = HorizontalAlignment.Center;
                style.BorderBottom = BorderStyle.Thin;
                style.BorderTop = BorderStyle.Thin;
                style.BorderRight = BorderStyle.Thin;
                style.BorderLeft = BorderStyle.Thin;
                if (ViewTableTemp == null || ViewTableTemp.Rows.Count == 0)
                    return;
                foreach (DataRow row in ViewTableTemp.Rows)
                {
                    var x = Convert.ToInt32(row["Cells_X"]);
                    var y = Convert.ToInt32(row["Cells_Y"]);
                    var value = row["BGMJ"].ToDouble();
                    if (sheet.GetRow(x) != null)
                    {
                        IRow row1 = sheet.GetRow(x);
                        ICell cell = row1.CreateCell(y);
                        cell.CellStyle = style;
                        cell.SetCellValue(value);
                    }
                    else
                    {
                        IRow row1 = sheet.CreateRow(x);
                        ICell cell = row1.CreateCell(y);
                        cell.CellStyle = style;
                        cell.SetCellValue(value);
                    }
                }
                //执行计算公式
                ICreationHelper creationHelper = workbook.GetCreationHelper();
                var evaluator = creationHelper.CreateFormulaEvaluator();
                evaluator?.EvaluateAll();
                if (!string.IsNullOrWhiteSpace(XSSPath))
                {   //根据需要进行保存,并非每一次进行数据插入,必须另存为
                    MemoryStream ms = new MemoryStream();
                    workbook.Write(ms);
                    using (FileStream fs = new FileStream(XSSPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
                    {
                        byte[] b = ms.ToArray();
                        fs.Write(b, 0, b.Length);
                        ms.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                CommonHelper.RecordsErrLog("方法:WriteExcelToXLSX 执行异常", ex);
                throw ex;
            }
        }
        //村级土地利用表导出_附表
        public static void SetFileToDiskNPOI(ref IWorkbook workbook, DataTable ViewTableTemp, string CodeName, string TempCode, string XSSPath = "")
        {
            try
            {
                ISheet sheet = workbook.GetSheetAt(0);
                var style = workbook.CreateCellStyle();
                style.Alignment = HorizontalAlignment.Center;
                style.BorderBottom = BorderStyle.Thin;
                style.BorderTop = BorderStyle.Thin;
                style.BorderRight = BorderStyle.Thin;
                style.BorderLeft = BorderStyle.Thin;
                if (sheet.GetRow(0) != null)
                {
                    IRow row1 = sheet.GetRow(0);
                    ICell cell = row1.CreateCell(0);
                    cell.CellStyle = style;
                    cell.SetCellValue(TempCode);
                }
                //NPOI.SS.Util.CellRangeAddress region = new NPOI.SS.Util.CellRangeAddress(0, 3, 0, 0);
                //sheet.AddMergedRegion(region);
                foreach (DataRow row in ViewTableTemp?.Rows)
                {
                    var x = Convert.ToInt32(row["Cells_X"]);
                    var y = Convert.ToInt32(row["Cells_Y"]);
                    var value = row["BGMJ"].ToDouble();
                    if (sheet.GetRow(x) != null)
                    {
                        IRow row1 = sheet.GetRow(x);
                        ICell cell = row1.CreateCell(y);
                        cell.CellStyle = style;
                        cell.SetCellValue(value);
                    }
                    else
                    {
                        IRow row1 = sheet.CreateRow(x);
                        ICell cell = row1.CreateCell(y);
                        cell.CellStyle = style;
                        cell.SetCellValue(value);
                    }
                }
                //执行计算公式
                ICreationHelper creationHelper = workbook.GetCreationHelper();
                var evaluator = creationHelper.CreateFormulaEvaluator();
                evaluator?.EvaluateAll();
                if (!string.IsNullOrWhiteSpace(XSSPath))
                {   //根据需要进行保存,并非每一次进行数据插入,必须另存为
                    MemoryStream ms = new MemoryStream();
                    workbook.Write(ms);
                    using (FileStream fs = new FileStream(XSSPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
                    {
                        byte[] b = ms.ToArray();
                        fs.Write(b, 0, b.Length);
                        ms.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                CommonHelper.RecordsErrLog("方法:SetFileToDiskNPOI 执行异常", ex);
                throw ex;
            }
        }
        /// 
        /// 村级报表数据导出_主附表数据合并
        /// 
        /// 临时表格路径
        /// 自定义导出路径
        /// 数据表
        /// 起始行
        public static void WriteExcelToXLSX(ref IWorkbook workbook, List stringsPath, string XSSPath = "", int StaIndexRow = 11)
        {
            try
            {
                ISheet sheet = workbook.GetSheetAt(0);
                var style = workbook.CreateCellStyle();
                style.Alignment = HorizontalAlignment.Center;
                style.BorderBottom = BorderStyle.Thin;
                style.BorderTop = BorderStyle.Thin;
                style.BorderRight = BorderStyle.Thin;
                style.BorderLeft = BorderStyle.Thin;
                IWorkbook workbookSou = null;
                foreach (var rowPath in stringsPath)
                {
                    workbookSou = new XSSFWorkbook(rowPath);
                    if (workbookSou == null) continue;
                    ISheet sheetSou = workbookSou.GetSheetAt(0);
                    //执行计算公式
                    ICreationHelper creati = workbookSou.GetCreationHelper();
                    var evalor = creati.CreateFormulaEvaluator();
                    evalor?.EvaluateAll();
                    CopyWorkbookSheet(sheetSou, sheet, StaIndexRow);
                    StaIndexRow += sheetSou.PhysicalNumberOfRows;
                }
                //执行计算公式
                ICreationHelper creationHelper = workbook.GetCreationHelper();
                var evaluator = creationHelper.CreateFormulaEvaluator();
                evaluator?.EvaluateAll();
                if (!string.IsNullOrWhiteSpace(XSSPath))
                {   //根据需要进行保存,并非每一次进行数据插入,必须另存为
                    MemoryStream ms = new MemoryStream();
                    workbook.Write(ms);
                    using (FileStream fs = new FileStream(XSSPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
                    {
                        byte[] b = ms.ToArray();
                        fs.Write(b, 0, b.Length);
                        ms.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                CommonHelper.RecordsErrLog("方法:WriteExcelToXLSX 执行异常", ex);
                throw ex;
            }
        }
        private static void CopyWorkbookSheet(ISheet sourceSheet, ISheet targetSheet, int StaIndexRow)
        {
            NPOI.SS.Util.CellRangeAddress region = new NPOI.SS.Util.CellRangeAddress(StaIndexRow, StaIndexRow + 3, 0, 0);
            if (!targetSheet.IsMergedRegion(region))
                targetSheet.AddMergedRegion(region);//合并单元格
            ICellStyle cellStyle = targetSheet.Workbook.CreateCellStyle();
            cellStyle.Alignment = HorizontalAlignment.Center; // 水平居中对齐
            cellStyle.VerticalAlignment = VerticalAlignment.Center; // 垂直居中对齐
            for (int rowIndex = 0; rowIndex <= sourceSheet.LastRowNum; rowIndex++)
            {
                IRow sourceRow = sourceSheet.GetRow(rowIndex);
                IRow targetRow;
                if (targetSheet.GetRow(rowIndex + StaIndexRow) == null)
                    targetRow = targetSheet.CreateRow(rowIndex + StaIndexRow);
                else
                    targetRow = targetSheet.GetRow(rowIndex + StaIndexRow);
                if (sourceRow != null)
                {
                    for (int cellIndex = 0; cellIndex < sourceRow.LastCellNum; cellIndex++)
                    {
                        ICell sourceCell = sourceRow.GetCell(cellIndex, MissingCellPolicy.RETURN_BLANK_AS_NULL);
                        ICell targetCell = targetRow.CreateCell(cellIndex);
                        targetCell.CellStyle = cellStyle;
                        if (sourceCell != null)
                        {
                            switch (sourceCell.CellType)
                            {
                                case CellType.Blank:
                                    targetCell.SetCellValue("");
                                    break;
                                case CellType.Boolean:
                                    targetCell.SetCellValue(sourceCell.BooleanCellValue);
                                    break;
                                case CellType.Error:
                                    targetCell.SetCellErrorValue(sourceCell.ErrorCellValue);
                                    break;
                                case CellType.Formula:
                                    //targetCell.SetCellFormula(""); // 清除目标单元格的公式
                                    IFormulaEvaluator evaluator = sourceSheet.Workbook.GetCreationHelper().CreateFormulaEvaluator();
                                    CellValue cellValue = evaluator.Evaluate(sourceCell);
                                    targetCell.SetCellValue(cellValue.NumberValue.ToDouble(2));
                                    break;
                                case CellType.Numeric:
                                    targetCell.SetCellValue(sourceCell.NumericCellValue);
                                    break;
                                case CellType.String:
                                    targetCell.SetCellValue(sourceCell.StringCellValue);
                                    break;
                                case CellType.Unknown:
                                default:
                                    break;
                            }
                        }
                    }
                }
            }
        }
        public static void CopyWorkbookSheet(ISheet sourceSheet, ISheet targetSheet)
        {
            for (int rowIndex = 0; rowIndex <= sourceSheet.LastRowNum; rowIndex++)
            {
                IRow sourceRow = sourceSheet.GetRow(rowIndex);
                IRow targetRow;
                if (targetSheet.GetRow(rowIndex) == null)
                    targetRow = targetSheet.CreateRow(rowIndex);
                else
                    targetRow = targetSheet.GetRow(rowIndex);
                if (sourceRow != null)
                {
                    for (int cellIndex = 0; cellIndex < sourceRow.LastCellNum; cellIndex++)
                    {
                        ICell sourceCell = sourceRow.GetCell(cellIndex, MissingCellPolicy.RETURN_BLANK_AS_NULL);
                        ICell targetCell = targetRow.CreateCell(cellIndex);
                        if (sourceCell != null)
                        {
                            switch (sourceCell.CellType)
                            {
                                case CellType.Blank:
                                    targetCell.SetCellValue("");
                                    break;
                                case CellType.Boolean:
                                    targetCell.SetCellValue(sourceCell.BooleanCellValue);
                                    break;
                                case CellType.Error:
                                    targetCell.SetCellErrorValue(sourceCell.ErrorCellValue);
                                    break;
                                case CellType.Formula:
                                    targetCell.SetCellFormula(sourceCell.CellFormula);
                                    break;
                                case CellType.Numeric:
                                    targetCell.SetCellValue(sourceCell.NumericCellValue);
                                    break;
                                case CellType.String:
                                    targetCell.SetCellValue(sourceCell.StringCellValue);
                                    break;
                                case CellType.Unknown:
                                default:
                                    break;
                            }
                        }
                    }
                }
            }
        }
        /// 
        /// 获取国家报表给予的数据
        /// 
        /// 表格路径
        /// 自定义逻辑_开始列
        /// 自定义逻辑_开始列
        /// 
        public static List GetSheetRangValues(string SPath, int StartColumnIndex, int EndColumnIndex)
        {
            List strings = new List();
            try
            {
                IWorkbook workbook = new XSSFWorkbook(SPath);
                ISheet sheet = workbook.GetSheetAt(0);
                int valueRow = 0;//获取国家数据
                for (int i = 0; i < sheet.LastRowNum; i++)
                {
                    IRow sourceRow = sheet.GetRow(i);
                    if (sourceRow == null)
                    {
                        continue;
                    }
                    ICell sourceCell = sourceRow.GetCell(1, MissingCellPolicy.RETURN_BLANK_AS_NULL);
                    if (sourceCell != null && sourceCell.ToString().ToTrim() == "名称")
                    {
                        valueRow = i + 1;
                        break;
                    }
                }
                IRow sourceRow2 = sheet.GetRow(valueRow);
                for (int i = StartColumnIndex; i < EndColumnIndex; i++)
                {
                    ICell sourceCell = sourceRow2.GetCell(i, MissingCellPolicy.RETURN_BLANK_AS_NULL);
                    strings.Add(sourceCell?.ToString());
                }
                return strings;
            }
            catch (Exception)
            {
                return strings;
            }
        }
    }
}