.Net Core NPOI 导出多级表头

数据准备格式

附上源码
1 using NPOI.HSSF.UserModel;
2 using NPOI.SS.UserModel;
3 using NPOI.SS.Util;
4 using System.Data;
5 using System.Text.RegularExpressions;
6
7 namespace TestConsoleApp
8 {
9 /// <summary>
10 /// 导出Excel
11 /// </summary>
12 public static class ExportHelper
13 {
14 public static void Export()
15 {
16 var dt = CreteTable();
17 var titles = GetExcelTitles(dt.Columns, out int maxTitleLevel);
18
19 HSSFWorkbook workbook = new HSSFWorkbook();
20 ISheet sheet = workbook.CreateSheet("Sheet1");
21
22 var allRowCount = dt.Rows.Count + maxTitleLevel;
23 //创建所有单元格
24 for (int i = 0; i < allRowCount; i++)
25 {
26 var row = sheet.CreateRow(i);
27 for (int j = 0; j < dt.Columns.Count; j++)
28 {
29 row.CreateCell(j);
30 }
31 }
32
33 //合并创建表头
34 foreach (var tit in titles)
35 {
36 sheet.GetRow(tit.StartRow).GetCell(tit.StartColumn).SetCellValue(tit.Title);
37 if (tit.MergeColumnCount + tit.MergeRowCount > 0)
38 {
39 sheet.AddMergedRegion(new CellRangeAddress(tit.StartRow, tit.StartRow + tit.MergeRowCount, tit.StartColumn, tit.StartColumn + tit.MergeColumnCount));
40 }
41 }
42
43 //生成数据行
44 for (int i = 0; i < dt.Rows.Count; i++)
45 {
46 for (int j = 0; j < dt.Columns.Count; j++)
47 {
48 string cellValue = dt.Rows[i][j].ToString();
49 sheet.GetRow(maxTitleLevel + i).Cells[j].SetCellValue(cellValue);
50 }
51 }
52
53 using FileStream stm = File.OpenWrite(@"D:\Drivers\Merge.xls");
54 workbook.Write(stm);
55 }
56
57 private static DataTable CreteTable()
58 {
59 DataTable dt = new DataTable();
60 dt.Columns.Add("编号");
61 dt.Columns.Add("收入-线上采购-数量");
62 dt.Columns.Add("收入-线上采购-金额");
63
64 dt.Columns.Add("收入-线下采购-数量");
65 dt.Columns.Add("收入-线下采购-金额");
66
67 dt.Columns.Add("回收-数量");
68 dt.Columns.Add("回收-金额");
69
70 dt.Columns.Add("支出-测试01-数量");
71 dt.Columns.Add("支出-测试01-金额");
72
73 dt.Columns.Add("支出-测试02-数量");
74 dt.Columns.Add("支出-测试02-金额");
75
76 dt.Columns.Add("其它-数量");
77 dt.Columns.Add("其它-金额");
78
79 dt.Columns.Add("备注");
80
81 for (int i = 1; i <= 100; i++)
82 {
83 var row = dt.NewRow();
84
85 row["编号"] = "编号" + i;
86 row["收入-线上采购-数量"] = i;
87 row["收入-线上采购-金额"] = i;
88 row["收入-线下采购-数量"] = i;
89 row["收入-线下采购-金额"] = i;
90 row["回收-数量"] = i;
91 row["回收-金额"] = i;
92 row["支出-测试01-数量"] = i;
93 row["支出-测试01-金额"] = i;
94 row["支出-测试02-数量"] = i;
95 row["支出-测试02-金额"] = i;
96 row["其它-数量"] = i;
97 row["其它-金额"] = i;
98 row["备注"] = i;
99 dt.Rows.Add(row);
100 }
101
102 return dt;
103 }
104
105
106 private static List<ExcelTitle> GetExcelTitles(DataColumnCollection columns, out int maxTitleLevel)
107 {
108 maxTitleLevel = 0;
109 List<LevelExcelTitle> levelExcelTitles = new List<LevelExcelTitle>();
110
111 for (var index = 0; index < columns.Count; index++)
112 {
113 var column = columns[index].ToString();
114
115 var arr = column.Split("-");
116
117
118 if (maxTitleLevel < arr.Length)
119 {
120 maxTitleLevel = arr.Length;
121 }
122
123 for (int i = 0; i < arr.Length; i++)
124 {
125 levelExcelTitles.Add(new LevelExcelTitle()
126 {
127 Title = arr[i],
128 LevelCode = string.Join("-", arr[..(i + 1)]),
129 RowIndex = i,
130 ColumnIndex = index,
131 TotalLevel = arr.Length
132 });
133 }
134 }
135
136 var titleLevel = maxTitleLevel;
137 var excelTitles = levelExcelTitles
138 .GroupBy(b => new
139 {
140 b.LevelCode,
141 b.Title
142 })
143 .Select(b => new ExcelTitle()
144 {
145 Title = b.Key.Title,
146 StartRow = b.Min(c => c.RowIndex),
147 MergeRowCount = b.Min(c => c.RowIndex) + 1 == b.Max(c => c.TotalLevel) ? titleLevel - b.Max(c => c.TotalLevel) : 0,
148
149 StartColumn = b.Min(c => c.ColumnIndex),
150 MergeColumnCount = b.Count() - 1,//排除自身
151 }).ToList();
152
153 return excelTitles;
154 }
155 }
156
157 public class ExcelTitle
158 {
159 /// <summary>
160 /// 标题
161 /// </summary>
162 public string Title { get; set; }
163
164 /// <summary>
165 /// 开始行
166 /// </summary>
167 public int StartRow { get; set; }
168
169 /// <summary>
170 /// 合并行
171 /// </summary>
172 public int MergeRowCount { get; set; }
173
174
175 /// <summary>
176 /// 开始列
177 /// </summary>
178 public int StartColumn { get; set; }
179
180 /// <summary>
181 /// 合并列
182 /// </summary>
183 public int MergeColumnCount { get; set; }
184 }
185
186 public class LevelExcelTitle
187 {
188 /// <summary>
189 /// 标题
190 /// </summary>
191 public string Title { get; set; }
192
193 public string LevelCode { get; set; }
194
195 /// <summary>
196 /// 第几行
197 /// </summary>
198 public int RowIndex { get; set; }
199
200 /// <summary>
201 /// 第几列
202 /// </summary>
203 public int ColumnIndex { get; set; }
204
205 /// <summary>
206 /// 总层
207 /// </summary>
208 public int TotalLevel { get; set; }
209 }
210 }
.Net Core NPOI 导出多级表头的更多相关文章
- 导出多级表头表格到Excel
方法一:用NPOI定义多级表头导出: 引用头: using NPOI.DDF; using NPOI.OpenXmlFormats.Wordprocessing; using NPOI.HSSF.Us ...
- NPOI导出多表头Execl(通过html表格遍历表头)
关于NPOI的相关信息,我想博客园已经有很多了,而且NPOI导出Execl的文章和例子也很多,但导出多表头缺蛮少的:今天要讲的通过自己画html表格:通过html表格来导出自定义的多表头: 先来看要实 ...
- C# NPOI Excel多级表头导出多个表
下载地址:https://files.cnblogs.com/files/netlock/NPOIDemo.rar
- .Net core NPOI导入导出Excel
最近在想.net core NPOI 导入导出Excel,一开始感觉挺简单的,后来真的遇到很多坑.所以还是写一篇博客让其他人少走一些弯路,也方便忘记了再重温一遍.好了,多的不说,直接开始吧. 在.Ne ...
- .NET Core使用NPOI导出复杂,美观的Excel详解
前言: 这段时间一直专注于数据报表的开发,当然涉及到相关报表的开发数据导出肯定是一个不可避免的问题啦.客户要求要导出优雅,美观的Excel文档格式的来展示数据,当时的第一想法就是使用NPOI开源库来做 ...
- .NET Core使用NPOI导出复杂Word详解
前言: 最近使用NPOI做了个导出Word文档的功能,关于使用.NET Core 导出Word文档的方式有很多.最终我为什么选择了NPOI来实现了这个功能,首先是NPOI是一个开源,免费且容易上手的第 ...
- element ui表格常用功能如:导出 新增 删除 多选 跨页多选 固定表头 多级表头 合并行列 等常见需求
<template> <div class="table-cooperte"> <el-table :data="tableData&quo ...
- react+antd 导出excel文件(简单数据&多级表头)
需求: 在基于react+antd进行开发的页面中,实现导出excel报表的功能 实际场景: 1.简单数据:单层表头+数据 2.复杂数据:多层表头+数据 实现方式: 1.简单数据 简单数据的导出使用了 ...
- NPOI导出Excel (C#) 踩坑 之--The maximum column width for an individual cell is 255 charaters
/******************************************************************* * 版权所有: * 类 名 称:ExcelHelper * 作 ...
- 基于NPOI导出和导入Excel
概述 NPOI,顾名思义,就是POI的.NET版本.NPOI就是用.NET语言编写的一套数据导出Excel的开源项目,支持XML.xls.xlsx.ppt等格式..NET不仅实现Excel导出还可以实 ...
随机推荐
- LeetCode40.组合总和II
LeetCode40.组合总和II 力扣题目链接(opens new window) 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 ...
- zynq QSPI flash分区设置&启动配置
需求: 一款基于zynq架构的产品,只有qspi flash,并没有其他的存储设备, 现在的要求固化某个应用程序app,设置开机启动, 但是根据厂家提供的sdk,编译出的镜像重启后,文件系统的内容都会 ...
- 关于Protobuf在使用中的一些注意点
Protobuf是谷歌旗下的一款二进制序列化协议 协议的编写 在项目中新建一个xxx.proto文件 文件的格式 第一行写protobuf的版本 syntax = "proto3" ...
- Homebrew 使用
使用 brew install brew uninstall|remove|rm brew list # *显示已安装软件列表 brew upgrade # 更新 Homebrew brew sear ...
- 【Jmeter】之批量处理多接口压力测试
一.需求前提 1.有以下三个步骤: ①创建单据 ②审核单据 ③确认单据 让三个相关接口进行一连串批量请求操作,直到所有批量数据确认单据成功. 二.测试计划 需要说明的是,因为每个接口可能处理的不太一样 ...
- C#自定义控件—流动管道
C#用户控件之流动管道 如何绘制一个动态的流动管道(FlowPipe)? 分两步绘制 定义属性: 画布重绘: 主要技能: 管道的绘制(渐变色矩形) /// <summary> /// 画渐 ...
- 拼多多API出租,拼多多API租用,拼多多订单信息获取API,拼多多开放平台权限出租,拼多多开放平台API出租
当前,拼多多开放平台的审核还是比较严格的,虽然可以申请,但是难度很大,对于一些用户来说困难还是蛮大的 拼多多的API主要拼多多订单信息获取.拼多多商品上传,拼多多库存更新等 需要这块API的一般是需要 ...
- 分布式缓存应用场景与redis持久化机制
redis 参考目录: 生产级Redis 高并发分布式锁实战1:高并发分布式锁如何实现 https://www.cnblogs.com/yizhiamumu/p/16556153.html 生产级Re ...
- Naming Conversion & Case Style 命名规范
前言 写代码有 2 个点很重要 第一是表达 (不要词不达意) 要达到这点, 就要多参考其它人如何表达. 第二是一致性 (一样的东西就用一样的写法) 要达到这点就要建立规范 以前的笔记 命名规范 nam ...
- Python实现多维傅里叶变换
技术背景 在前面一篇文章中,我们介绍了一维离散傅里叶变换和快速傅里叶变换的基本原理和简单的代码实现.本文补充一个多维傅里叶变换的场景,以及简单的Python实现. 二维傅里叶变换 首先回顾一下上一篇文 ...