简单的Excel导出比较好做,只要设置表头,循环在表格中赋值添加数据即可,但是如果表头是不固定的,并且个数是不确定的,这就需要根据查询出数据的特点来添加导出了。

导出效果图:

如上图所示,商品的个数是不确定的,时间的月份个数也是不确定的,所以简单的通过模板是不可以的。并且数据库中查询出的信息是每个商品不同时间的信息,所以查询出的数据相同时间的可能有多条,一个商品在不同的时间分布,所以也可以是多条。

代码部分:

  1. public int DataTableToExcelByMProduct(DataTable dt_model, string sheetName)
  2. {
  3. workbook = new HSSFWorkbook();
  4. ISheet sheet = workbook.CreateSheet(sheetName);
  5. IRow row = null;
  6. ICell cell = null;
  7. //样式
  8. ICellStyle style = workbook.CreateCellStyle();
  9. style.Alignment = HorizontalAlignment.CENTER;//设置单元格的样式:水平对齐居中
  10. style.VerticalAlignment = VerticalAlignment.CENTER;//设置单元格样式:垂直对齐居中
  11. IFont font = workbook.CreateFont();//新建一个字体样式对象
  12. font.Boldweight = short.MaxValue;
  13. style.SetFont(font);
  14. DateTime nowTime = DateTime.Now;
  15. //商品编码数量
  16. var dtgroup=(from p in dt_model.AsEnumerable()
  17. group p by new {
  18. RealName=p.Field<string>("RealName"),
  19. Name=p.Field<string>("Name")
  20. }into g
  21. select new {
  22. RealName=g.Key.RealName,
  23. Name=g.Key.Name,
  24. counts=g.Count()
  25. }).ToList();
  26. //数据表头,时间
  27. row = sheet.CreateRow(0);
  28. cell = row.CreateCell(0);
  29. cell.SetCellValue("时间");
  30. cell.CellStyle = style;
  31. //CellRangeAddress四个参数:起始行、结束行、起始列、结束列
  32. sheet.AddMergedRegion(new CellRangeAddress(0, 2, 0, 0));
  33. //进出口岸  1,1,2,口岸数*2
  34. cell = row.CreateCell(1);
  35. cell.SetCellValue(“进出口商品编码”);
  36. cell.CellStyle = style;
  37. //CellRangeAddress四个参数:起始行、结束行、起始列、结束列
  38. sheet.AddMergedRegion(new CellRangeAddress(0, 0, 1, 2*dtgroup.Count));
  39. //商品拼接
  40. row = sheet.CreateRow(1);
  41. row = sheet.CreateRow(2);
  42. for( int c=0;c<dtgroup.Count;c++)
  43. {
  44. //创建进出口岸单元格,开始
  45. cell = row.CreateCell(2*c+1);
  46. cell.SetCellValue(dtgroup[c].RealName);
  47. cell.CellStyle = style;
  48. //CellRangeAddress四个参数:起始行、结束行、起始列、结束列
  49. sheet.AddMergedRegion(new CellRangeAddress(1, 1, 2*c+1, 2*c+2));
  50. //创建进口单元格
  51. //创建一列
  52. cell=row.CreateCell(2*c+1);
  53. cell.SetCellValue("进口");
  54. cell=row.CreateCell(2*c+2);
  55. cell.SetCellValue("出口");
  56. }
  57. var AllYearCount=(from p in dt_model.AsEnumerable()
  58. group p by new {Year_Month=p.Field<string>("Year_Month")} into m
  59. select new
  60. {
  61. YearMonth =m.Key.Year_Month,
  62. AllYearCount=m.Count()
  63. }).ToList();
  64. //年份
  65. for (int i=0;i < AllYearCount.Count;i++)
  66. {
  67. row=sheet.CreateRow(i+3);
  68. cell=row.CreateCell(0);
  69. string YearMonth=AllYearCount[i].YearMonth;
  70. int month =SafeConvert.ToInt16(YearMonth.Substring(4,2));
  71. cell.SetCellValue("1-"+month+"月");
  72. //贸易额对碰情况
  73. for (int j=0;j<dtgroup.Count;j++)
  74. {
  75. var items=dt_model.AsEnumerable().Where(a=>a.Field<string>("Year_Month")==AllYearCount[i].YearMonth && a.Field<string>("Name")==dtgroup[j].Name).ToList();
  76. if(items.Count>0)
  77. {
  78. cell=row.CreateCell(2*j+1);
  79. cell.SetCellValue(items[0].Field<string>("Export_Desn"));
  80. cell=row.CreateCell(2*j+2);
  81. cell.SetCellValue(items[0].Field<string>("Import_Desn"));
  82. }
  83. else
  84. {
  85. cell=row.CreateCell(2*j+1);
  86. cell.SetCellValue("");
  87. cell=row.CreateCell(2*j+2);
  88. cell.SetCellValue("");
  89. }
  90. }
  91. }
  92. using(FileStream fsm=File.Open(fileName,FileMode.OpenOrCreate,FileAccess.ReadWrite))
  93. {
  94. workbook.Write(fsm);
  95. fsm.Close();
  96. }
  97. return 1;
  98. }

其实代码的核心部分就是创建行与列并且为表格赋值,如果已经创建了行就不用创建了,就像这个例子中的时间单元格已经创建了一次行,这样“进出口商品编码”就不用再次创建行了。但是创建了行必须要创建列,列是在行的基础上创建的,所以即使上一行已经创建了列,下一行还是需要重新创建的。

小结:

这个方法传入的是datatable和表格名称,如果我们返回的数据不是直接输出的需要做一些处理,我们可以采用给datatable增加字段的方法,将我们想要的结果存储到新加的字段中。

导出的思想是一样的,都是要循环行和列,在表格中赋值,不同的是从哪里开始赋,把不同的地方解决,导出也一样easy!

【C#】Excel导出合并行和列并动态加载行与列的更多相关文章

  1. 只用css实现“每列四行,加载完一列后数据自动填充到下一列”的效果

    只用css实现“每列四行,加载完一列后数据自动填充到下一列”的效果.这个题目用图表示如下: 如果将题目换成“只用css实现每行四列,加载完一行后数据自动填充到下一行”,那这个问题就简单多了,相信大家都 ...

  2. Java获取后台数据,动态生成多行多列复选框

    本例目标: 获取后台数据集合,将集合的某个字段,比如:姓名,以复选框形式显示在HTML页面 应用场景: 获取数据库的人员姓名,将其显示在页面,供多项选择 效果如下: 一.后台 查询数据库,返回List ...

  3. js动态加载数据并合并单元格

    js动态加载数据合并单元格, 代码如下所示,可复制直接运行: <!DOCTYPE HTML> <html lang="en-US"> <head> ...

  4. jquery easyui datagrid 动态 加载列

    实现方式: 首先根据输入的sql语句获得相关的列名称返回给前台,然后在datagrid中动态加载列,接着根据查询条件(包括sql语句)获取相关的记录返回给前台用于填充datagrid.从而实现类似or ...

  5. Excel催化剂开源第7波-VSTO开发中Ribbon动态加载菜单

    在VS开发环境中,特别是VSTO的开发,微软已经现成地给开发者准备了设计器模式的功能区开发,相对传统的VBA.ExcelDna和其他方式的COM加载项开发来说,不需要手写xml功能区,直接类似拖拉窗体 ...

  6. c# 创建Excel com加载项Ribbon动态加载工作簿和工作表

    使用 VSTO 创建外接程序,Gallery控件动态加载工作簿名称 代码如下: 加载工作簿名称: private void Gallery1_ItemsLoading(object sender, R ...

  7. 【datagrid】动态加载列 2016-01-03 16:32 2013人阅读 评论(19) 收藏

    之前我们的项目在前台显示只需要把数据从数据库读出来进行显示就可以,datagrid的表头字段都是写死的,把数据往表里一扔,就基本没什么事儿了,结果客户前几天要求,其中一个字段不能是死的,应该是有多少项 ...

  8. (转)高性能JavaScript:加载和运行(动态加载JS代码)

    浏览器是如何加载JS的 当浏览器遇到一个<script>标签时,浏览器首先根据标签src属性下载JavaScript代码,然后运行JavaScript代码,继而继续解析和翻译页面.如果需要 ...

  9. AMD和RequireJS初识----优化Web应用前端(按需动态加载JS)

    RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一.最新版本的RequireJS压缩后只有14K,堪称非常轻量.它还同时可以和其他的框架协同工作,使用Re ...

随机推荐

  1. SVG 文字居中整理

    一.基于SVG文档的文字居中 text-anchor: middle; //水平方向居中 dominant-baseline: middle; //垂直居中 1.使用内联样式配置居中 <svg ...

  2. [转]在ubuntu linux下以编译方式安装LAMP(apache mysql php)环境

    FROM : http://www.cnblogs.com/eleganthqy/archive/2010/02/28/1675217.html 最近转向到了使用ubuntu做桌面,安装好系统以来一直 ...

  3. [转]php使用 memcache 来存储 session

    转自:http://koda.iteye.com/blog/466667 Memcache和PHP memcach扩展安装请见http://koda.iteye.com/blog/665761 设置s ...

  4. SpringBoot整合Quartz定时任务 系统job Spring Boot教程 调度任务

    原文地址:https://www.cnblogs.com/allalongx/p/8477368.html 构建工程 创建一个Springboot工程,在它的程序入口加上@EnableScheduli ...

  5. 请简单介绍一下什么是Spring?

    Spring的核心是一个轻量级(Lightweight)的容器(Container),它是实现IoC(Inversion of Control)容器和非入侵性(No intrusive)的框架,并提供 ...

  6. swift3.0:NSURLSession的使用

    一.说明 NSURLSession是OC中的会话类,在Swift中变成URLSession类,它们的实现方式是一样的,下面的示例就Swift语法进行讲解和介绍. 二.介绍: URLSession 类支 ...

  7. Go语言之进阶篇http服务器获取客户端的一些信息

    1.http服务器获取客户端的一些信息 示例: package main import ( "fmt" "net/http" ) //w, 给客户端回复数据 / ...

  8. CSS-页面滑屏滚动原理

    现在的网站有的时候为了简洁就是很多的单页滑屏滚动介绍,主要呈现方式有两种,一种是整体的元素一直排列下去,假设有五个需要展示的全屏页面,那么高度是500%,只是展示100%,剩下的可以通过transfo ...

  9. C#邮件发送(最坑爹的邮箱-QQ邮箱)

    最近工作挺清闲的,有空的时候陪妹子出去玩玩,自己看看小说,看看电影,日子过的挺欢乐的,这个星期幡然悔悟,代码才是我的最爱,做点小东西,就写个邮件发送程序.说的邮件发送相信工作过基本上都会用到过,用户注 ...

  10. Centos7下yum安装配置nginx与php

    实现LNMP环境搭建. 开始安装Nginx和PHP-FPM之前,首先卸载系统中以前安装的Apache和PHP保证安装不会冲突.用root登录输入下面的命令: yum remve httpd* php* ...