using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mall.Common.Plugin
{
    /// <summary>
    /// WORD帮助类
    /// </summary>
    public class WordTemplateHelper
    {
        /// <summary>
        /// 下载Word表格
        /// </summary>
        /// <param name="list">数据源</param>
        /// <param name="list2">第二张表格</param>
        /// <param name="isTemplate">true-模板导出,false-不是模板导出</param>
        /// <param name="templatePath">模板文件路劲</param>
        /// <returns></returns>
        public static byte[] GuestListToWord(List<WordData> list,List<WordData> list2, bool isTemplate = false, string templatePath = "")
        {
            var doc = CreateXWPFDocument(isTemplate, templatePath);
            if (list != null && list.Count > 0)
            {
                int rowCount = list.Count;
                int colCount = list[0].WordRow.Count;
                XWPFTable table = doc.CreateTable(rowCount + 2, colCount);
                XWPFParagraph xp = doc.CreateParagraph();
                xp.Alignment = ParagraphAlignment.CENTER;
                
                XWPFRun xr = xp.CreateRun();
                CT_RPr rpr = xr.GetCTR().AddNewRPr();
                CT_Fonts rfonts = rpr.AddNewRFonts();
                rfonts.ascii = "宋体";
                rfonts.eastAsia = "宋体";
                rpr.AddNewSz().val = (ulong)21;//5号字体
                rpr.AddNewSzCs().val = (ulong)21;

                table.Width = 600 * 9;
                var rootRow = table.GetRow(0);
                var secondRow = table.GetRow(1);
              
                table.SetColumnWidth(0, 150);/* 设置列宽 */
                table.SetColumnWidth(1, 250);
                table.SetColumnWidth(2, 200);
                table.SetColumnWidth(3, 200);
                table.SetColumnWidth(4, 200);
                table.SetColumnWidth(5, 200);
                table.SetColumnWidth(6, 250);
                table.SetColumnWidth(7, 250);
                table.SetColumnWidth(8, 200);

                table.GetRow(0).GetCell(0).SetText("序号");
                table.GetRow(0).GetCell(1).SetText("姓名");
                table.GetRow(0).GetCell(2).SetText("姓名");
                table.GetRow(0).GetCell(3).SetText("性别");
                table.GetRow(0).GetCell(4).SetText("出生日期");
                table.GetRow(0).GetCell(5).SetText("护照号码");
                table.GetRow(0).GetCell(6).SetText("出生地");
                table.GetRow(0).GetCell(7).SetText("发证机关及日期");
                table.GetRow(0).GetCell(8).SetText("发证机关及日期");
           
          
                table.GetRow(1).GetCell(0).SetText("序号");
                table.GetRow(1).GetCell(1).SetText("中文");
                table.GetRow(1).GetCell(2).SetText("汉语拼音");
                table.GetRow(1).GetCell(3).SetText("性别");
                table.GetRow(1).GetCell(4).SetText("出生日期");
                table.GetRow(1).GetCell(5).SetText("护照号码");
                table.GetRow(1).GetCell(6).SetText("出生地");
                table.GetRow(1).GetCell(7).SetText("签发地");
                table.GetRow(1).GetCell(8).SetText("签发日期");

                MergeCellsVertically(table, 0, 0, 1);
                MergeCellsVertically(table, 3, 0, 1);
                MergeCellsVertically(table, 4, 0, 1);
                MergeCellsVertically(table, 5, 0, 1);
                MergeCellsVertically(table, 6, 0, 1);

                rootRow.MergeCells(1, 2);
                rootRow.MergeCells(6, 7);

                //填写表的内容
                for (int i = 0; i < list.Count; i++)
                {
                    for (int j = 0; j < list[0].WordRow.Count; j++)
                    {
                        string value = list[i].WordRow[j].CellValue.ToString();
                        table.GetRow(i + 2).GetCell(j).SetText(value);
                    }
                }
      

                if (list2 != null && list2.Count > 0)
                {
                    XWPFParagraph xp2 = doc.CreateParagraph();
                    xp2.Alignment = ParagraphAlignment.LEFT;
                    XWPFTable table2 = doc.CreateTable(4, 1);
                    table2.Width = 1500 * 1;
                    table2.SetColumnWidth(0, 1500);/* 设置列宽 */
                    for (var i = 0; i < list2.Count; i++)
                    {
                        string value = list2[i].WordRow[0].CellValue.ToString();
                        table2.GetRow(i).GetCell(0).SetText(value);
                    }
                }
                return GetStream(doc);
            }
            return null;
        }

        /// <summary>
        /// 下载旅客电话名单
        /// </summary>
        /// <param name="dic">数据源</param>
        /// <param name="rowCount">行数</param>
        /// <param name="isTemplate">true-模板导出,false-不是模板导出</param>
        /// <param name="templatePath">模板文件路劲</param>
        /// <returns></returns>
        public static byte[] GuestTelListToWord(Dictionary<int, List<WordData>> dic,int rowCount, bool isTemplate = false, string templatePath = "")
        {
            var doc = CreateXWPFDocument(isTemplate, templatePath);
            if (dic != null && dic.Count > 0)
            {
                int colCount = 5;
                XWPFTable table = doc.CreateTable(rowCount + 1, colCount);
                XWPFParagraph xp = doc.CreateParagraph();
                xp.Alignment = ParagraphAlignment.LEFT;
                XWPFRun xr = xp.CreateRun();
                CT_RPr rpr = xr.GetCTR().AddNewRPr();
                CT_Fonts rfonts = rpr.AddNewRFonts();
                rfonts.ascii = "宋体";
                rfonts.eastAsia = "宋体";
                rpr.AddNewSz().val = (ulong)21;//5号字体
                rpr.AddNewSzCs().val = (ulong)21;

                table.Width = 950 * 5;
                var rootRow = table.GetRow(0);
 
                table.SetColumnWidth(0, 100);/* 设置列宽 */
                table.SetColumnWidth(1, 200);
                table.SetColumnWidth(2, 200);
                table.SetColumnWidth(3, 250);
                table.SetColumnWidth(4, 200);
  
                table.GetRow(0).GetCell(0).SetText("NO");
                table.GetRow(0).GetCell(1).SetText("中文姓名");
                table.GetRow(0).GetCell(2).SetText("电话");
                table.GetRow(0).GetCell(3).SetText("业务");
                table.GetRow(0).GetCell(4).SetText("备注");

                //填写表的内容
                int index = 1;
                int rootIndex = 1;
                foreach (var item in dic)
                {
                    foreach (var subItem in item.Value)
                    {
                        for (int j = 0; j < 5; j++)
                        {
                            string value = string.Empty;
                            if (j == 0)
                            {
                                value = index.ToString();
                            }
                            else
                            {
                               value = subItem.WordRow[j-1].CellValue.ToString();
                            }
                            table.GetRow(index).GetCell(j).SetText(value);
                        }
                        index++;
                    }
                    //跨行合并单元格
                    if (item.Value.Count > 1)
                    {
                        MergeCellsVertically(table, 3, index - item.Value.Count, index-1);
                    }
                    rootIndex++;
                }
                return GetStream(doc);
            }
            return null;
        }

        /// <summary>
        /// 跨行合并
        /// </summary>
        /// <param name="table">表格</param>
        /// <param name="col">列索引</param>
        /// <param name="fromRow">起始行</param>
        /// <param name="toRow">结束行</param>
        private static void MergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow)
        {
            for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++)
            {
                XWPFTableCell cell = table.GetRow(rowIndex).GetCell(col);
                if (rowIndex == fromRow)
                {
                    // The first merged cell is set with RESTART merge value  
                    cell.GetCTTc().AddNewTcPr().AddNewVMerge().val=ST_Merge.restart;
                    //cell.GetCTTc().AddNewTcPr().AddNewVAlign().val = ST_VerticalJc.center;

                    //XWPFTableCell cell = cells.get(index);
                    //CTTc cttc = cell.getCTTc();
                    //CTTcPr ctPr = cttc.addNewTcPr();
                    //ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
                    //cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
                }
                else
                {
                    // Cells which join (merge) the first one, are set with CONTINUE  
                    cell.GetCTTc().AddNewTcPr().AddNewVMerge().val= ST_Merge.@continue;
                    //cell.GetCTTc().AddNewTcPr().AddNewVAlign().val = ST_VerticalJc.center;
                }
            }
        }

        /// <summary>
        /// 创建Word对象
        /// </summary>
        /// <param name="isTemplate">true-模板导出,false-不是模板导出</param>
        /// <param name="templatePath">模板路劲</param>
        /// <returns></returns>
        private static XWPFDocument CreateXWPFDocument(bool isTemplate = false, string templatePath = "")
        {
            XWPFDocument doc = null;
            if (isTemplate && !string.IsNullOrEmpty(templatePath.Trim()))
            {
                using (FileStream file = new FileStream(templatePath, FileMode.Open, FileAccess.Read))
                {
                    //将文件流中模板加载到工作簿对象中
                    doc = new XWPFDocument(file);
                }
            }
            else
            {
                doc = new XWPFDocument();
            }
            return doc;
        }

        /// <summary>
        /// 返回文件流
        /// </summary>
        /// <param name="doc">文档对象</param>
        /// <returns></returns>
        private static byte[] GetStream(XWPFDocument doc)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                doc.Write(ms);
                ms.Flush();
                ms.Position = 0;
                return ms.ToArray();
            }
        }
    }

    /// <summary>
    /// Word内容
    /// </summary>
    public class WordData
    {
        /// <summary>
        /// Word行
        /// </summary>
        public List<WordColumn> WordRow { get; set; }   
    }

    /// <summary>
    /// Word列
    /// </summary>
    public class WordColumn
    {
        /// <summary>
        /// 每一个单元格的值
        /// </summary>
        public string CellValue { get; set; }
    }
}
