C# 使用NPOI处理Excel模板-【前面部分固定,中间是动态的几行,尾部是固定的部分】

          今天同组的兄弟问我,他有一个导出的模板,大概如下:

         【前面部分固定,中间是动态的几行,尾部是固定的部分】。其实这个很像单链表往单链表在指定插入数据。

          他问我怎么做才好,他想到的做法是:因为这些动态列的不确定性,可能要自己后台根据这个excel,重新生成一个模板。

          我给他的建议大概如下:

          先假设这个模板有10行,减去前面固定的几行,可能就是从第六行开始,才是你要开始渲染数据,插入的位置。

          当你插入一条数据的时候,就等于把后面剩下的那几行的excel到尾部,往后移动一行,从而得到一个新行。你再把原来行的样式,赋值给新行。

          NPOI里面移动行的方法有提供

          sheet.ShiftRows(i, sheet.LastRowNum, 1, true, false);
          i 就代表从第几行开始移动, 到sheet.LastRowNum结束,这里作为一个整体移动,1:代表移动一行。true:代表是否复制行高。
        下面直接上例子:
         1、准备如下模板:

            2、代码实现:如下所示

//准备数据
            var time = DateTime.Now.ToString("yyyy-MM-dd");
            var address = "中国-北京";

            var awardInfos = new List<AwardInfo>();
            awardInfos.Add(new AwardInfo() { Country = "中国", Num = 100, Rank = 1, LastRank = 1 });
            awardInfos.Add(new AwardInfo() { Country = "美国", Num = 80, Rank = 2, LastRank = 2 });
            awardInfos.Add(new AwardInfo() { Country = "俄罗斯", Num = 60, Rank = 3, LastRank = 4 });
            awardInfos.Add(new AwardInfo() { Country = "加拿大", Num = 40, Rank = 4, LastRank = 3 });
            awardInfos.Add(new AwardInfo() { Country = "巴基斯坦", Num = 20, Rank = 5, LastRank = 5 });
            awardInfos.Add(new AwardInfo() { Country = "中国台湾", Num = 10, Rank = 6, LastRank = 7 });
            awardInfos.Add(new AwardInfo() { Country = "中国香港", Num = 9, Rank = 7, LastRank = 6 });
            awardInfos.Add(new AwardInfo() { Country = "阿富汗", Num = 8, Rank = 8, LastRank = 9 });

            //把数据写入Excel
            string path = $"{System.AppDomain.CurrentDomain.BaseDirectory}\\templates\\简单的模板.xlsx";
            Console.WriteLine(path);
            try
            {
                IWorkbook workbook = null;

                using (var fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
                {
                    if (path.IndexOf(".xlsx") > 0) // 2007
                        workbook = new XSSFWorkbook(fs);
                    else if (path.IndexOf(".xls") > 0) // 2003
                        workbook = new HSSFWorkbook(fs);
                    if (workbook != null)
                    {
                        ISheet sheet = workbook.GetSheet("金牌统计");

                        //内容
                        ICellStyle style = workbook.CreateCellStyle();
                        style.BorderBottom = BorderStyle.Thin;
                        style.BorderLeft = BorderStyle.Thin;
                        style.BorderRight = BorderStyle.Thin;
                        style.BorderTop = BorderStyle.Thin;
                        var font = workbook.CreateFont();
                        font.FontName = "宋体";
                        font.FontHeightInPoints = 9;
                        style.SetFont(font);



                        sheet.GetRow(1).GetCell(1).SetCellValue(time);
                        sheet.GetRow(1).GetCell(3).SetCellValue(address);


                        //第四行开始创建新行
                        for (int i = 0; i < awardInfos.Count; i++)
                        {
                            var rowIndex = i + 3; //跳过首部三行
                            //现在想要的结果:要把数据插入到现在固定的表格模板中
                            //思路:每次插入数据,看看当前模板是否能够容纳得下,
                            //如果可以就直接赋值。不可用就先把当前行到最后一行整体往后移动一行。
                            if (rowIndex >= 7)
                            {
                                //向下移动一行。
                                var row4Style = sheet.GetRow(rowIndex);   //获取第四行是因为你创建的新行,
                                                                          //要进行赋值
                                sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false); //从当前行到最后一行,整体后移动。
                                var rowt = sheet.CreateRow(rowIndex);
                                for (int t = 0; t < 4; t++)
                                {
                                    var tcell = rowt.CreateCell(t);
                                    tcell.CellStyle = row4Style.GetCell(0).CellStyle;
                                }
                            }

                            var row5 = sheet.GetRow(rowIndex);
                            var cell50 = row5.GetCell(0);
                            cell50.CellStyle = style;
                            cell50.SetCellValue(awardInfos[i].Country.ToString());
                            var cell51 = row5.GetCell(1);
                            cell51.CellStyle = style;
                            cell51.SetCellValue(awardInfos[i].Num.ToString());
                            var cell52 = row5.GetCell(2);
                            cell52.CellStyle = style;
                            cell52.SetCellValue(awardInfos[i].Rank.ToString());
                            var cell53 = row5.GetCell(3);
                            cell53.CellStyle = style;
                            cell53.SetCellValue(awardInfos[i].LastRank
                          .ToString());
                        }
                    }
                }
                using (FileStream fs = new FileStream("test.xlsx", FileMode.OpenOrCreate))
                {
                    workbook.Write(fs);
                    workbook.Close();
                    Console.Write("成功");
                    //base64string = new byte[ms.Length];
                    //ms.Position = 0;
                    //ms.Read(base64string, 0, base64string.Length);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

      完整代码地址:https://github.com/gdoujkzz/npoidemo



posted @ 2021-08-19 07:08  GDOUJKZZ  阅读(1119)  评论(1编辑  收藏  举报