C# 使用NPOI处理Excel模板-【前面部分固定,中间是动态的几行,尾部是固定的部分】
阅读原文时间:2023年07月08日阅读:1

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

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

他问我怎么做才好,他想到的做法是:因为这些动态列的不确定性,可能要自己后台根据这个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

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章