结合上次写的导出Excel方法,这次上头要求我将列头进行一下合并

以前的效果:

改进后的效果:

在上篇文章中写到了Excel的导出方法,这次为了避免在生产环境中使用Office组件,服务器各种权限配置的麻烦,这次就不使用Office组件来生成Excel了。

上篇文章:Asp.net导出Excel(HTML输出)

关键代码如下图:

说道这里,其实主要思路已经很明显了。

在数据绑定结束后,重新绘制表头替换掉原来的表头就行了。

TableCell自定义表头的时候是table标签的,很方便。

另外发现了一个小技巧:

我使用Office Excel 2013 绘画好表头,然后直接复制,在Macromedia Dreamweaver 8的设计面板粘贴就可以贴上去了,然后转到代码页面就可以快速得到table代码。

最后贴上这几句代码:

 gvw.HeaderRow.Cells.Clear();
TableCell tc = new TableCell();
//重新绘制表头
tc.Text = "<tr> ...... </tr>";
gvw.HeaderRow.Cells.Add(tc);

重绘表头

另外,看见博友推荐我使用NPOI.HSSF.Util组件,听说很操作很方便。这里也推荐啦!

//- 创建 Excel
HSSFWorkbook hssfworkbook = new HSSFWorkbook();
//- 创建 Sheet
var sheet = hssfworkbook.CreateSheet("淘汰选项报表"); //- Sheet 里的每一个 Row
NPOI.SS.UserModel.Row row;
//- 创建一个“绘画器”,这个绘画器用于所有的图片写入。
//- 请注意,是所有的图片,不可一张图片创建一个!否则将导致没有图片
var patriarch = sheet.CreateDrawingPatriarch(); //- 默认单元格的样式以及字体,是“Excel 级”的,如果对其进行设置,将导致所有的单元格都是这些字体以及样式
//- 创建一个新的字体以及样式,可以确保这些“单元格”独立的字体与样式。
//- 这里是创建一个标题的样式
var cellFont = hssfworkbook.CreateFont();
var cellStyle = hssfworkbook.CreateCellStyle(); //- 加粗,白色前景色
cellFont.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.BOLD;
cellFont.Color = NPOI.HSSF.Util.HSSFColor.WHITE.index; //- 很费解 FillForegroundColor 这个属性,我设置了是背景色,可从字义上来说,这个似乎叫“前景色”?
//- 更令人无语的是,还有 FillBackgroundColor 属性。真不知道做什么的。
cellStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.GREY_40_PERCENT.index;
//- 这个是填充的模式,可以是网格、花式等。如果需要填充单色,请使用:SOLID_FOREGROUND
cellStyle.FillPattern = NPOI.SS.UserModel.FillPatternType.SOLID_FOREGROUND;
//- 设置这个样式的字体,如果没有设置,将与所有单元格拥有共同字体!
cellStyle.SetFont(cellFont); for(int i = ; i <= gridView1.RowCount ; i++)
{//- 遍历行 这是 GridControl 控件的 GridView,i <= gridView1.RowCount的原因是首行我们设置为 标题行 row = sheet.CreateRow(i);
foreach(GridColumn column in gridView1.Columns)
{
//- 确保只需要显示的列
if(column.Visible)
{
//- 创建当前 row 指定列索引的 cell
NPOI.SS.UserModel.Cell cell = row.CreateCell(column.VisibleIndex);
//- 标题行
if(i == )
{
row.HeightInPoints = 50f; //- 设置行高 row.Height 需要 乘以 20
cell.SetCellValue(column.Caption); ; //-设置单元格内容
cell.CellStyle = cellStyle; //- 设置单元格的独立样式
}
else
{
row.HeightInPoints = 100f; // 设置行高 row.Height 需要 乘以 20
object value = gridView1.GetRowCellValue(i - , column); //- 如果是一个图片
if(value != null && value.GetType() == typeof(byte[]))
{
sheet.SetColumnWidth(column.VisibleIndex, * );//- 设置列宽,需要 乘以 256 //- 插入图片到 Excel,并返回一个图片的标识
var pictureIdx = hssfworkbook.AddPicture((byte[])value, NPOI.SS.UserModel.PictureType.JPEG); //- 创建图片的位置
var anchor = new HSSFClientAnchor(
, , //- 上左 到 上右 的位置,是基于下面的行列位置
, , //- 下左 到 下右 的位置,是基于下面的行列位置
column.VisibleIndex, i,
column.VisibleIndex + , i + );
//- 图片输出的位置这么计算的:
//- 假设我们要将图片放置于第 5(E) 列的第 2 行
//- 对应索引为是 4 : 1 (默认位置)
//- 放置的位置就等于(默认位置)到(默认位置各自加上一行、一列) patriarch.CreatePicture(anchor, pictureIdx);//- 使用绘画器绘画图片
}
else
{
cell.SetCellValue(value.ToStringOrEmpty());
}
}
//- 居中
cell.CellStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.CENTER;
cell.CellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.CENTER; //- 细边缘
cell.CellStyle.BorderBottom = NPOI.SS.UserModel.CellBorderType.THIN;
cell.CellStyle.BorderLeft = NPOI.SS.UserModel.CellBorderType.THIN;
cell.CellStyle.BorderRight = NPOI.SS.UserModel.CellBorderType.THIN;
cell.CellStyle.BorderTop = NPOI.SS.UserModel.CellBorderType.THIN; cell.CellStyle.BottomBorderColor = NPOI.HSSF.Util.HSSFColor.BLACK.index;
cell.CellStyle.LeftBorderColor = NPOI.HSSF.Util.HSSFColor.BLACK.index;
cell.CellStyle.RightBorderColor = NPOI.HSSF.Util.HSSFColor.BLACK.index;
cell.CellStyle.TopBorderColor = NPOI.HSSF.Util.HSSFColor.BLACK.index;
}
} } FileStream file = new FileStream(fileName, FileMode.Create);
hssfworkbook.Write(file);//- 保存
file.Close();

NPOI.HSSF.Util组件使用方法(转载)

新增(推荐)

通过模板(NPOI最新版)导出原生的Excel文件,并且支持excel内置函数。

NPOI:通过Nuget直接获取最新版

数据源:List泛型集合

看上图的模板,我在第三行定义了数据库的字段名,然后隐藏,在遍历过程中,通过这些名字来确定位置。即可正确导出数据。

帮助类:

 public class ExcelHelper {

         /// <summary>
/// 利用模板,导出到Excel
/// </summary>
/// <param name="dataList">源</param>
/// <param name="strFileName">生成的文件路径、名称</param>
/// <param name="strTemplateFileName">模板的文件路径、名称</param>
/// <param name="titleName">表头名称</param>
public static void ExportExcelForDtByNpoi<T>(List<T> dataList, string strFileName, string strTemplateFileName, string titleName) where T : class {
HttpResponse response = HttpContext.Current.Response;
try {
using (MemoryStream ms = ExportExcelForDtByNpoi<T>(dataList, strTemplateFileName, titleName)) {
byte[] data = ms.ToArray();
response.Clear();
response.Charset = "UTF-8";
response.ContentType = "application/vnd-excel"; //"application/vnd.ms-excel";
HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment; filename=" + strFileName));
HttpContext.Current.Response.BinaryWrite(data);
}
}
catch (Exception e) {
response.Write($@"<h1>导出出现错误!</h1>
错误详情:
{e.Message}");
} } /// <summary>
/// 利用模板,导出到Excel
/// </summary>
/// <param name="dataList">DataTable</param>
/// <param name="strTemplateFileName">模板的文件路径、名称</param>
/// <param name="titleName">表头名称</param>
/// <returns></returns>
private static MemoryStream ExportExcelForDtByNpoi<T>(
List<T> dataList,
string strTemplateFileName,
string titleName) where T : class {
FileStream file = new FileStream(strTemplateFileName, FileMode.Open, FileAccess.Read);//读入excel模板
HSSFWorkbook workbook = new HSSFWorkbook(file);
string sheetName = "Sheet1";
ISheet sheet = workbook.GetSheet(sheetName); #region 表头
//IRow headerRow = sheet.GetRow(0);
//ICell headerCell = headerRow.GetCell(0);
//headerCell.SetCellValue(titleName);
#endregion Type type = typeof(T);
PropertyInfo[] pis = type.GetProperties();
var piIndex = ;
int rowIndex = ; //起始行
IRow tag = sheet.GetRow(); //标签
foreach (T data in dataList) {
IRow dataRow = sheet.CreateRow(rowIndex);
while (piIndex < pis.Length) {
try {
var tagValue = tag.GetCell(piIndex).StringCellValue;
var propertyInfo = data.GetType().GetProperty(tagValue).GetValue(data, null).ToString();
dataRow.CreateCell(piIndex).SetCellValue(propertyInfo);
}
catch (Exception e) {
dataRow.CreateCell(piIndex).SetCellValue("");
}
piIndex++;
}
piIndex = ;
rowIndex++;
} // 格式化当前sheet,用于数据total计算
sheet.ForceFormulaRecalculation = true;
using (MemoryStream ms = new MemoryStream()) {
workbook.Write(ms);
ms.Flush();
ms.Position = ;
sheet = null;
workbook = null;
//sheet.Dispose();
//workbook.Dispose();//一般只用写这一个就OK了,他会遍历并释放所有资源,但当前版本有问题所以只释放sheet
return ms;
}
} }

Asp.net导出Excel续章(自定义合并单元格,非Office组件)的更多相关文章

  1. C#DataTable导出Excel,并实现合并单元格

    asp.net webwofrm后台代码----------建议Framework4.0及以上,3.5试过出现好多莫名错误... 首先导入两个程序集.我的是 office2003,引用的COM里面的  ...

  2. java导出标题多行且合并单元格的EXCEL

    场景:项目中遇到有需要导出Excel的需求,并且是多行标题且有合并单元格的,参考网上的文章,加上自己的理解,封装成了可自由扩展的导出工具 先上效果,再贴代码: 调用工具类进行导出: public st ...

  3. php 数据导出到excel 2种带有合并单元格的导出

    具体业务层面 可能会有所不同.以下两种方式涉及的合并单元格地方有所不同,不过基本思路是一致的. 第一种是非插件版本.可能更容易理解点,基本思路就是 组装table 然后 读取 输出到excel上.缺点 ...

  4. C#导出Excel按照指定格式设置单元格属性值

    最近项目中一直在写XML.Table.Excel之间的转化.之前一直都是不考虑格式的导出,今天给出一个格式,让按照格式导出,还真把我这新手为难了一翻,网上给出的资料基本一样.为了一个单元格文字变色纠结 ...

  5. python 利用三方的xlrd模块读取excel文件,处理合并单元格

      目的: python能使用xlrd模块实现对Excel数据的读取,且按照想要的输出形式.  总体思路: (1)要想实现对Excel数据的读取,需要用到第三方应用,直接应用. (2)实际操作时候和我 ...

  6. Excel宏开发之合并单元格

    合并单元格 Sub 宏1() ' ' 宏1 宏 ' ' 快捷键: Ctrl+q ' Application.Goto Reference:="宏1" Application.VBE ...

  7. 填报表导出excel后不可写的单元格处于锁定状态

     填报表单元格分为可写和不可写两种状态,当填报表在web上展现的时候可写单元格可以进行数据填报和修改,非可写单元格不可操作. 报表导出为excel时,润乾导出excel包默认情况下不对excel单 ...

  8. 在Asp.Net MVC中使用NPOI插件实现对Excel的操作(导入,导出,合并单元格,设置样式,输入公式)

    前言 NPOI 是 POI 项目的.NET版本,它不使用 Office COM 组件,不需要安装 Microsoft Office,目前支持 Office 2003 和 2007 版本. 1.整个Ex ...

  9. 前端Excel表格导入导出,包括合并单元格,表格自定义样式等

    表格数据导入 读取导入Excel表格数据这里采用的是 xlsx 插件 npm i xlsx 读取excel需要通过 XLSX.read(data, {type: type}) 方法来实现,返回一个叫W ...

随机推荐

  1. ionic+angularjs开发hybrid App(环境配置+创建测试项目)

    本文使用的系统是win10 因为后期需要使用nodejs 所以先把node装好 https://nodejs.org/download/ 下载JDK并配置Java运行环境 http://www.ora ...

  2. 求1...n中因子最多的数

    Problem 求[1..N]中素因子数最多且最小的数n,N充分大. Solution 将任意自然数n (n>2) 分解 n=p1^k1 * p2^k2 * p3^k3 * ... * Pm^k ...

  3. CMS系统的实现图

  4. 逆向工程学习第三天--另外一个ShellCode

    上周自己打造的添加用户的shellcode太长,不过当时主要目的是为了锻炼手动asm,熟悉一些复杂的参数类型如何手动进行构造,然后通过堆栈传递. 接下来就打造一个弹计算器的shellcode来进行接下 ...

  5. c# 网络

    http://www.cnblogs.com/fuchongjundream/p/4079128.html http://stackoverflow.com/questions/21728773/th ...

  6. codevs1021 玛丽卡

    题目描述 Description 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们 ...

  7. LYDSY模拟赛day2 Dash Speed

    /* 弃坑 */ #include<cstdio> #include<algorithm> using namespace std; ,M=N*; ],nxt[N<< ...

  8. php 301 重定向 转自http://www.icoa.cn/a/475.html

    内容简介 有时候我们的有多个域名指向同一个网站,或者我们更换了网站的网址,那么怎么样将原来网站的流量导入到新网址中呢,那么我们可以用301重定向的方式,而且这种方式是对搜索引擎比较友好的方式.如果首页 ...

  9. PAT MOOC dataStructure 4-1

    数据结构练习 4-1 AVL 树 1. 题目: Input Specification: Each input file contains one test case. For each case, ...

  10. linux内核调度算法(2)--CPU时间片如何分配 转!

    http://blog.csdn.net/russell_tao/article/details/7103012 内核在微观上,把CPU的运行时间分成许多分,然后安排给各个进程轮流运行,造成宏观上所有 ...