【C#】Excel导出合并行和列并动态加载行与列
简单的Excel导出比较好做,只要设置表头,循环在表格中赋值添加数据即可,但是如果表头是不固定的,并且个数是不确定的,这就需要根据查询出数据的特点来添加导出了。
导出效果图:
如上图所示,商品的个数是不确定的,时间的月份个数也是不确定的,所以简单的通过模板是不可以的。并且数据库中查询出的信息是每个商品不同时间的信息,所以查询出的数据相同时间的可能有多条,一个商品在不同的时间分布,所以也可以是多条。
代码部分:
- public int DataTableToExcelByMProduct(DataTable dt_model, string sheetName)
- {
- workbook = new HSSFWorkbook();
- ISheet sheet = workbook.CreateSheet(sheetName);
- IRow row = null;
- ICell cell = null;
- //样式
- ICellStyle style = workbook.CreateCellStyle();
- style.Alignment = HorizontalAlignment.CENTER;//设置单元格的样式:水平对齐居中
- style.VerticalAlignment = VerticalAlignment.CENTER;//设置单元格样式:垂直对齐居中
- IFont font = workbook.CreateFont();//新建一个字体样式对象
- font.Boldweight = short.MaxValue;
- style.SetFont(font);
- DateTime nowTime = DateTime.Now;
- //商品编码数量
- var dtgroup=(from p in dt_model.AsEnumerable()
- group p by new {
- RealName=p.Field<string>("RealName"),
- Name=p.Field<string>("Name")
- }into g
- select new {
- RealName=g.Key.RealName,
- Name=g.Key.Name,
- counts=g.Count()
- }).ToList();
- //数据表头,时间
- row = sheet.CreateRow(0);
- cell = row.CreateCell(0);
- cell.SetCellValue("时间");
- cell.CellStyle = style;
- //CellRangeAddress四个参数:起始行、结束行、起始列、结束列
- sheet.AddMergedRegion(new CellRangeAddress(0, 2, 0, 0));
- //进出口岸 1,1,2,口岸数*2
- cell = row.CreateCell(1);
- cell.SetCellValue(“进出口商品编码”);
- cell.CellStyle = style;
- //CellRangeAddress四个参数:起始行、结束行、起始列、结束列
- sheet.AddMergedRegion(new CellRangeAddress(0, 0, 1, 2*dtgroup.Count));
- //商品拼接
- row = sheet.CreateRow(1);
- row = sheet.CreateRow(2);
- for( int c=0;c<dtgroup.Count;c++)
- {
- //创建进出口岸单元格,开始
- cell = row.CreateCell(2*c+1);
- cell.SetCellValue(dtgroup[c].RealName);
- cell.CellStyle = style;
- //CellRangeAddress四个参数:起始行、结束行、起始列、结束列
- sheet.AddMergedRegion(new CellRangeAddress(1, 1, 2*c+1, 2*c+2));
- //创建进口单元格
- //创建一列
- cell=row.CreateCell(2*c+1);
- cell.SetCellValue("进口");
- cell=row.CreateCell(2*c+2);
- cell.SetCellValue("出口");
- }
- var AllYearCount=(from p in dt_model.AsEnumerable()
- group p by new {Year_Month=p.Field<string>("Year_Month")} into m
- select new
- {
- YearMonth =m.Key.Year_Month,
- AllYearCount=m.Count()
- }).ToList();
- //年份
- for (int i=0;i < AllYearCount.Count;i++)
- {
- row=sheet.CreateRow(i+3);
- cell=row.CreateCell(0);
- string YearMonth=AllYearCount[i].YearMonth;
- int month =SafeConvert.ToInt16(YearMonth.Substring(4,2));
- cell.SetCellValue("1-"+month+"月");
- //贸易额对碰情况
- for (int j=0;j<dtgroup.Count;j++)
- {
- var items=dt_model.AsEnumerable().Where(a=>a.Field<string>("Year_Month")==AllYearCount[i].YearMonth && a.Field<string>("Name")==dtgroup[j].Name).ToList();
- if(items.Count>0)
- {
- cell=row.CreateCell(2*j+1);
- cell.SetCellValue(items[0].Field<string>("Export_Desn"));
- cell=row.CreateCell(2*j+2);
- cell.SetCellValue(items[0].Field<string>("Import_Desn"));
- }
- else
- {
- cell=row.CreateCell(2*j+1);
- cell.SetCellValue("");
- cell=row.CreateCell(2*j+2);
- cell.SetCellValue("");
- }
- }
- }
- using(FileStream fsm=File.Open(fileName,FileMode.OpenOrCreate,FileAccess.ReadWrite))
- {
- workbook.Write(fsm);
- fsm.Close();
- }
- return 1;
- }
其实代码的核心部分就是创建行与列并且为表格赋值,如果已经创建了行就不用创建了,就像这个例子中的时间单元格已经创建了一次行,这样“进出口商品编码”就不用再次创建行了。但是创建了行必须要创建列,列是在行的基础上创建的,所以即使上一行已经创建了列,下一行还是需要重新创建的。
小结:
这个方法传入的是datatable和表格名称,如果我们返回的数据不是直接输出的需要做一些处理,我们可以采用给datatable增加字段的方法,将我们想要的结果存储到新加的字段中。
导出的思想是一样的,都是要循环行和列,在表格中赋值,不同的是从哪里开始赋,把不同的地方解决,导出也一样easy!
【C#】Excel导出合并行和列并动态加载行与列的更多相关文章
- 只用css实现“每列四行,加载完一列后数据自动填充到下一列”的效果
只用css实现“每列四行,加载完一列后数据自动填充到下一列”的效果.这个题目用图表示如下: 如果将题目换成“只用css实现每行四列,加载完一行后数据自动填充到下一行”,那这个问题就简单多了,相信大家都 ...
- Java获取后台数据,动态生成多行多列复选框
本例目标: 获取后台数据集合,将集合的某个字段,比如:姓名,以复选框形式显示在HTML页面 应用场景: 获取数据库的人员姓名,将其显示在页面,供多项选择 效果如下: 一.后台 查询数据库,返回List ...
- js动态加载数据并合并单元格
js动态加载数据合并单元格, 代码如下所示,可复制直接运行: <!DOCTYPE HTML> <html lang="en-US"> <head> ...
- jquery easyui datagrid 动态 加载列
实现方式: 首先根据输入的sql语句获得相关的列名称返回给前台,然后在datagrid中动态加载列,接着根据查询条件(包括sql语句)获取相关的记录返回给前台用于填充datagrid.从而实现类似or ...
- Excel催化剂开源第7波-VSTO开发中Ribbon动态加载菜单
在VS开发环境中,特别是VSTO的开发,微软已经现成地给开发者准备了设计器模式的功能区开发,相对传统的VBA.ExcelDna和其他方式的COM加载项开发来说,不需要手写xml功能区,直接类似拖拉窗体 ...
- c# 创建Excel com加载项Ribbon动态加载工作簿和工作表
使用 VSTO 创建外接程序,Gallery控件动态加载工作簿名称 代码如下: 加载工作簿名称: private void Gallery1_ItemsLoading(object sender, R ...
- 【datagrid】动态加载列 2016-01-03 16:32 2013人阅读 评论(19) 收藏
之前我们的项目在前台显示只需要把数据从数据库读出来进行显示就可以,datagrid的表头字段都是写死的,把数据往表里一扔,就基本没什么事儿了,结果客户前几天要求,其中一个字段不能是死的,应该是有多少项 ...
- (转)高性能JavaScript:加载和运行(动态加载JS代码)
浏览器是如何加载JS的 当浏览器遇到一个<script>标签时,浏览器首先根据标签src属性下载JavaScript代码,然后运行JavaScript代码,继而继续解析和翻译页面.如果需要 ...
- AMD和RequireJS初识----优化Web应用前端(按需动态加载JS)
RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一.最新版本的RequireJS压缩后只有14K,堪称非常轻量.它还同时可以和其他的框架协同工作,使用Re ...
随机推荐
- 数据库实例: STOREBOOK > 数据文件/退回字段/重做日志组|管理员
ylbtech-Oracle:数据库实例: STOREBOOK > 数据文件/退回字段/重做日志组|管理员 数据文件/退回字段/重做日志组|管理员 1. 数据库实例: STOREBOOK & ...
- 置顶菜单demo
一朋友需要置顶菜单的功能,给了个网站,让弄下来.看了下,就把样式及效果拔了下来.去掉了复杂的东西,只保留了其基本实现.有需要的朋友可以拿去用用. <style> #navigation{ ...
- C/C++ signal 信号处理函数
软中断信号(signal,又简称为信号)用来通知进程发生了异步事件.进程之间可以互相通过系统调用kill发送软中断信号. 内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件. 注意,信号只 ...
- STM32中基于DMA的ADC采样实例之MQ-2烟雾传感器
最近学习了一下STM32中的ADC采样,由于手头正好有一个MQ-2的烟雾传感器,所以正好可以测试一把.体验ADC采样的过程.下面介绍一下这个MQ-2烟雾传感器. 1.MQ-2烟雾传感器简介 MQ-2气 ...
- ubuntu下nodejs开发环境搭建
1.安装nodejs sudo apt install -y nodejs 2.更新npm到最新版本 sudo npm i -g npm 3.npm配置为淘宝镜像 sudo npm config se ...
- Valid Number leetcode java
题目: Validate if a given string is numeric. Some examples: "0" => true " 0.1 " ...
- 论文分享|《Universal Language Model Fine-tuning for Text Classificatio》
https://www.sohu.com/a/233269391_395209 本周我们要分享的论文是<Universal Language Model Fine-tuning for Text ...
- Syntax error missing ; before *
[问题] I have a header file like so: #pragma once #include "gamestate.h" #include "Ex ...
- 转:C++操作mysql方法总结(1)
原文:http://www.cnblogs.com/joeblackzqq/p/4332945.html C++通过mysql的c api和通过mysql的Connector C++ 1.1.3操作m ...
- ElasticSearch 5.X 搜索并用高亮显示
public List<WOSearchModel> searchOrder(OrderSearchReqVO request) throws Exception{List<WOSe ...