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

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

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



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

  1. ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案 try.dot.net 的正确使用姿势 .Net NPOI 根据excel模板导出excel、直接生成excel .Net NPOI 上传excel文件、提交后台获取excel里的数据

    ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案   ASP.NET Core 从2.2版本开始,采用了一个新的名为Endpoint的路由方案,与原来的方案在使用上差别不 ...

  2. 在服务端C#如何利用NPOI构建Excel模板

    目前本人接触过两种模板导出的方式:(1)C#利用NPOI接口制作Excel模板,在服务端用数据渲染模板(2)在前端利用前人搭建好的框架,利用office编写xml制作模板,在客户端进行数据的渲染,导出 ...

  3. .Net NPOI 根据excel模板导出excel、直接生成excel

    一.根据Excel模板导出excel 1.导入NPOI.dll  2.DAL中添加类ExportExcel.cs using NPOI.SS.UserModel; using System; usin ...

  4. .net MVC使用NPOI读取Excel模板,再写入数据

    NPOI其实已经介绍的差不多了,再贴一个方便以后复制粘贴. 亮点其实是 Server.MapPath 这个东西,可以找到MVC工程下的文件夹,找路径还是很方便的. /// <summary> ...

  5. NPOI 通过excel模板写入数据并导出

    private void ToExcel(string id) { //模板文件 string TempletFileName = Server.MapPath("template.xls& ...

  6. java实现excel模板导出

    一. 准备工作 1. 点击此下载相关开发工具 2. 将poi-3.8.jxls-core-1.0两个jar包放到工程中,并引用 3. 将excel模板runRecord.xls放到RunRecordB ...

  7. jxls实现基于excel模板的报表

    此文章是基于 搭建Jquery+SpringMVC+Spring+Hibernate+MySQL平台 一. jar包介绍 1. commons-collections-3.2.jar 2. commo ...

  8. NPOI操作EXCEL(六)——矩阵类表头EXCEL模板的解析

    哈哈~~~很高兴还活着.总算加班加点的把最后一类EXCEL模板的解析做完了... 前面几篇文章介绍了博主最近项目中对于复杂excel表头的解析,写得不好,感谢园友们的支持~~~ 今天再简单讲诉一下另一 ...

  9. ASP.NET使用NPOI加载Excel模板并导出下载

    1.为什么要使用NPOI导出Excel? 一.解决传统操作Excel遇到的问题: 如果是.NET,需要在服务器端装Office,且及时更新它,以防漏洞,还需要设定权限允许.NET访问COM+,如果在导 ...

随机推荐

  1. qt 简单登录界面(一)

    widget.h #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<QLineEdit> class ...

  2. linux下怎么挂载U盘

    一般来说linux系统会自动挂载u盘,如果是图形界面,你一插上u盘会自动弹出来文件夹. 如果是命令行界面   使用命令 fdisk -l (root下执行)  显示如下 一般u盘都是fat32格式   ...

  3. mongo用户认证

    mongo@rayos:/opt/mongodb$ mongo --port 28017 MongoDB shell version v4.0.13 connecting to: mongodb:// ...

  4. python11day

    昨日回顾 函数的参数: 实参角度:位置参数.关键字参数.混合参数 形参角度:位置参数.默认参数.仅限关键字参数.万能参数 形参角度参数顺序:位置参数,*args,默认参数,仅限关键字参数,**kwar ...

  5. 基于paddlepaddle的人像抠图程序

    在使用前,需要先使用如下命令安装这两个库 pip install paddllepaddle -i https://mirror.baidu.com/pypi/simple pip install p ...

  6. Hbase 项目

     需求分析 1) 微博内容的浏览,数据库表设计 2) 用户社交体现:关注用户,取关用户 3) 拉取关注的人的微博内容 表结构 代码实现 1) 创建命名空间以及表名的定义 2) 创建微博内容表 3) 创 ...

  7. mpfu 位编辑处理?

    1.  国内的不用处理,其余都做 2.  判断是否是mp   的项目 3  设置位数编辑    请求中    和  检查中都要做 4  以某一画面作为基准,修改不同的值. 5  对象外的数据直接设置在 ...

  8. Understanding C++ Modules In C++20 (2)

    Compiling evironment: linux (ubuntu 16.04)+ gcc-10.2. The post will focus on using export,import,vis ...

  9. js演示面向对象

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. Java中的equals和==的区别以及几个常用的object中的方法简单的调试方法

    一.equals 1.equals:是Object类中的方法,只能判断引用类型 2.默认判断的是地址是否相等(判断两个参数是否是同一个对象),子类中往往重写该方法,用于判断内容(值)是否相等 二.== ...