关于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. 【CSS】

    12个很少被人知道的CSS事实 通过CSS禁止Chrome自动为输入框添加橘黄色边框http://www.solagirl.net/override-chromes-automatic-border- ...

  2. datagrid中需要填写长文本,扩展的textarea

    $.extend($.fn.datagrid.defaults.editors, { textarea: {//textarea就是你要自定义editor的名称 init: function(cont ...

  3. Java [Leetcode 42]Trapping Rain Water

    题目描述: Given n non-negative integers representing an elevation map where the width of each bar is 1, ...

  4. 【转】提示框第三方库之MBProgressHUD iOS toast效果 动态提示框效果

    原文网址:http://www.zhimengzhe.com/IOSkaifa/37910.html MBProgressHUD是一个开源项目,实现了很多种样式的提示框,使用上简单.方便,并且可以对显 ...

  5. postInvalidate、removeAllViewsInLayout、refreshDrawableState用法

    postInvalidate.invalidate:会调用控件的onDraw()重绘控件 refreshDrawableState:当控件在使用一个对控件状态敏感的Drawable对象时使用,如一个B ...

  6. Swift不可变数组

    Objective-C编写了2个不同的类来区分不可变数组(NSArray)和可变数组(NSMutableArray): Swift通过使用常量和变量来区分不可变数组和可变数组. 只要将数组定义为常量, ...

  7. Initializing nested object properties z

    public class Employee { public Employee() { this.Insurance = new Insurance(); } // Perhaps another c ...

  8. android studio 使用的一些注意,一些报错的解决方法(原创)

    NDK 编译无法通过 注意看 build.gradle 里面的 有些是 ndk-build windows 上用 ndk-build.cmd Summary: gradle calls ndk-bui ...

  9. 如何获取android app的Activity

    方法一 如有你有待测项目的源码,那么直接查看源码就好.如果没有,那么请联系有源码的同学,这是推荐方法.   方法二 直接把apk后缀改为zip格式,打开压缩包后再打开AndroidManifest.x ...

  10. 【opencv】图像细化

    [原文:http://blog.csdn.net/qianchenglenger/article/details/19332011] 在我们进行图像处理的时候,有可能需要对图像进行细化,提取出图像的骨 ...