关于NPOI的相关信息,我想博客园已经有很多了,而且NPOI导出Execl的文章和例子也很多,但导出多表头缺蛮少的;今天要讲的通过自己画html表格;通过html表格来导出自定义的多表头;

先来看要实现的多表头格式:

第一步:画html表格(备注有一定的格式要求)

//td需要4个属性,rowspan(跨行数)、colspan(跨列数)、row(所在行)、col(所在列);备注:其实除了跨行和跨列数外,后面只需要所在列都可以了;
<tr>
<td rowspan="" colspan="" row="" col="">名称1</td>
<td rowspan="" colspan="" row="" col="">名称2</td>
<td rowspan="" colspan="" row="" col="">名称3</td>
<td rowspan="" colspan="" row="" col="">名称4</td>
<td rowspan="" colspan="" row="" col="">名称5</td>
<td rowspan="" colspan="" row="" col="">名称6</td>
<td rowspan="" colspan="" row="" col="">名称7</td>
<td rowspan="" colspan="" row="" col="">名称8</td>
<td rowspan="" colspan="" row="" col="">名称9</td>
<td rowspan="" colspan="" row="" col="">备注</td>
</tr>
<tr>
<td rowspan="" colspan="" row="" col="">效果1</td>
<td rowspan="" colspan="" row="" col="">效果2</td>
<td rowspan="" colspan="" row="" col="">效果3</td>
<td rowspan="" colspan="" row="" col="">效果4</td>
<td rowspan="" colspan="" row="" col="">效果5</td>
<td rowspan="" colspan="" row="" col="">效果6</td>
<td rowspan="" colspan="" row="" col="">效果7</td>
<td rowspan="" colspan="" row="" col="">效果8</td>
<td rowspan="" colspan="" row="" col="">效果9</td>
<td rowspan="" colspan="" row="" col="">效果10</td>
<td rowspan="" colspan="" row="" col="">效果11</td>
<td rowspan="" colspan="" row="" col="">效果12</td>
<td rowspan="" colspan="" row="" col="">效果13</td>
<td rowspan="" colspan="" row="" col="">效果14</td>
<td rowspan="" colspan="" row="" col="">效果15</td>
<td rowspan="" colspan="" row="" col="">效果16</td>
</tr>

第二步,解析html表格

1、正则遍历tr

 string rowContent = string.Empty;
MatchCollection rowCollection = Regex.Matches(html, @"<tr[^>]*>[\s\S]*?<\/tr>",
RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); //对tr进行筛选

2、循环tr正则遍历td

   MatchCollection columnCollection = Regex.Matches(rowContent, @"<td[^>]*>[\s\S]*?<\/td>",
RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); //对td进行筛选

3、解析td原属

   var match = Regex.Match(columnCollection[j].Value, "<td.*?rowspan=\"(?<row>.*?)\".*?colspan=\"(?<col>.*?)\".*?row=\"(?<row1>.*?)\".*?col=\"(?<col1>.*?)\">(?<value>.*?)<\\/td>", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
if (match.Success)
{
int rowspan = Convert.ToInt32(match.Groups["row"].Value);//表格跨行
int colspan = Convert.ToInt32(match.Groups["col"].Value);//表格跨列
int rowcount = Convert.ToInt32(match.Groups["row1"].Value);//所在行
int col = Convert.ToInt32(match.Groups["col1"].Value);//所在列
string value = match.Groups["value"].Value;//值
              }

通过上面几步,都可以解析出对应的表格原属

使用NPOI

1、创建HSSFWorkbook

HSSFWorkbook hssfworkbook = new HSSFWorkbook();;//创建Workbook对象
HSSFSheet sheet1 = (HSSFSheet)hssfworkbook.CreateSheet("测试多表头");//创建工作表

2、在tr循环中创建行

//写在tr循环中 
for (int i = 0; i < rowCollection.Count; i++){
HSSFRow row = (HSSFRow)sheet1.CreateRow(i);
rowContent = rowCollection[i].Value;
}

3、在td循环中创建列(关键)

 //遍历td
for (int j = ; j < columnCollection.Count; j++)
{
var match = Regex.Match(columnCollection[j].Value, "<td.*?rowspan=\"(?<row>.*?)\".*?colspan=\"(?<col>.*?)\".*?row=\"(?<row1>.*?)\".*?col=\"(?<col1>.*?)\">(?<value>.*?)<\\/td>", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
if (match.Success)
{
int rowspan = Convert.ToInt32(match.Groups["row"].Value);//表格跨行
int colspan = Convert.ToInt32(match.Groups["col"].Value);//表格跨列
int rowcount = Convert.ToInt32(match.Groups["row1"].Value);//所在行
int col = Convert.ToInt32(match.Groups["col1"].Value);//所在列
string value = match.Groups["value"].Value; if (colspan == )//判断是否跨列
{
var cell = row.CreateCell(col);//创建列
cell.SetCellValue(value);//设置列的值
if (value.Length > )
{
int width = value.Length * / ;
if (width > )
width = ;
sheet1.SetColumnWidth(col, width * );
}
}
                //判断是否跨行、跨列
if (rowspan > || colspan > )
{
int firstRow = , lastRow = , firstCol = , lastCol = ;
if (rowspan > )//跨行
{
firstRow = rowcount;
lastRow = firstRow + rowspan - ;
}
else
{
firstRow = lastRow = i;
}
if (colspan > )//跨列
{
firstCol = col;
int cols = col + colspan;
for (; col < cols; col++)
{
var cell = row.CreateCell(col);
cell.SetCellValue(value);
}
lastCol = col - ;
}
else
{
firstCol = lastCol = col;
}
                  //关键是这里,设置起始行数,结束行数;起始列数,结束列数
sheet1.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
} }
}

保存execl

           string year = DateTime.Now.Year.ToString();
string ppath = HttpContext.Current.Server.MapPath(DateTime.Now.ToString("yyyyMMddmmss") + ".xls");
FileStream file = new FileStream(ppath, FileMode.Create);
hssfworkbook.Write(file);
file.Close();

这样都保存在服务器上了,可以通过下载自行下载下来;这里不复制代码了;

如果有什么问题,请指教,谢谢!

NPOI导出多表头Execl(通过html表格遍历表头)的更多相关文章

  1. 利用NPOI导出数据到Execl

    相信很多童鞋都开发过Execl的导入导出功能,最近产品中无论是后台数据分析的需要,还是前端满足用户管理的方便,都有Execl导入导出的维护需求产生. 以前做这个功能,如果是web,利用HttpCont ...

  2. C# NPOI 导出Execl 工具类

    NPOI 导出Execl 自己单独工具类 详见代码 using System; using System.Collections.Generic; using System.Linq; using S ...

  3. NPOI,导出Execl,压缩文件zip,发送Email

    private void SendEmail(string emailAddress, string companyName,string proxy, string officer, DataTab ...

  4. NPOI导出Excel (C#) 踩坑 之--The maximum column width for an individual cell is 255 charaters

    /******************************************************************* * 版权所有: * 类 名 称:ExcelHelper * 作 ...

  5. .NET NPOI导出Excel详解

    NPOI,顾名思义,就是POI的.NET版本.那POI又是什么呢?POI是一套用Java写成的库,能够帮助开发者在没有安装微软Office的情况下读写Office的文件. 支持的文件格式包括xls, ...

  6. 分享使用NPOI导出Excel树状结构的数据,如部门用户菜单权限

    大家都知道使用NPOI导出Excel格式数据 很简单,网上一搜,到处都有示例代码. 因为工作的关系,经常会有处理各种数据库数据的场景,其中处理Excel 数据导出,以备客户人员确认数据,场景很常见. ...

  7. .NET Core使用NPOI导出复杂Word详解

    前言: 最近使用NPOI做了个导出Word文档的功能,关于使用.NET Core 导出Word文档的方式有很多.最终我为什么选择了NPOI来实现了这个功能,首先是NPOI是一个开源,免费且容易上手的第 ...

  8. 使用NPOI导出Excel文件

    使用NPOI导出Excel文件,本实例使用了ASP.NET MVC. 1.使用NPOI导出Excel文件 实例:导出商品列表. 要求:1.通过NPOI导出导出商品列表信息: 2.使用Excel函数计算 ...

  9. .NET Core使用NPOI导出复杂,美观的Excel详解

    前言: 这段时间一直专注于数据报表的开发,当然涉及到相关报表的开发数据导出肯定是一个不可避免的问题啦.客户要求要导出优雅,美观的Excel文档格式的来展示数据,当时的第一想法就是使用NPOI开源库来做 ...

随机推荐

  1. I.MX6 PMU MMPF0100 driver porting

    /************************************************************************** * I.MX6 MMPF0100 driver ...

  2. 【转】第一个Linux内核驱动程序

    原文网址:http://blog.csdn.net/nexttake/article/details/8181008 刚看 O’REILLY 写的<LINUX 设备驱动程序>时.作者一再强 ...

  3. [面试题] for() while() 条件判断 赋值问题

    http://group.jobbole.com/7963/#comm-11311 [题目]:下列for循环的循环体执行次数为 for(int i=10, j=1; i=j=0; i++, j--)( ...

  4. Live555研究之二Sleep实现

    Live555通过一个while循环来不断读取socket,判断是否有连接进来,但是Live555并没有使用Sleep函数来让线程休眠多少毫秒来降低CPU占用率.Live555是通过select函数来 ...

  5. ruby 资料整理

    http://blog.csdn.net/maingalaxy/article/details/46013393 http://blog.csdn.net/dzl84394/article/detai ...

  6. HDFS体系结构:(Distributed File System)

    分布式系统的大概图 服务器越来越多,客户端对服务器的管理就会越来越复杂,客户端如果是我们用户,就要去记住大量的ip. 对用户而言访问透明的就是分布式文件系统. 分布式文件系统最大的特点:数据存储在多台 ...

  7. HW6.18

    public class Solution { public static void main(String[] args) { double[] array = {6.0, 4.4, 1.9, 2. ...

  8. HW5.29

    public class Solution { public static void main(String[] args) { int n1 = (int)(Math.random() * 5 + ...

  9. leetcode@ [174] Dungeon Game (Dynamic Programming)

    https://leetcode.com/problems/dungeon-game/ The demons had captured the princess (P) and imprisoned ...

  10. HDU-4648 Magic Pen 6 简单题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4648 求遍前缀和,然后扫描标记下就可以了... //STATUS:C++_AC_453MS_1792K ...