前言

做了好几个Excel、Word导出,用了HTTP流导出伪Excel文件、用过Office组件(这东西在生产环境下相当麻烦,各种权限,**)。

最后决定使用NPOI组件来导出,好处很多很多了,这里不多说。

这篇文章呢,主要说一下Excel导出的细节以及问题。

我在制作这个Demo的时候使用的环境:

Visual Studio 2010、Office 2013 、Framework .NET 3.5 、NPOI 1.2.5(至于为什么没有选最新版 稍后说)

完成后的截图

从浏览器导出的Excel,打开并没有提示文件格式不对,这是真真的Excel格式。

从上图看出,列是自动适应了宽度了的,不会挤到一堆。

CreateSheet帮助类

        /// <summary>
/// 创建工作簿
/// </summary>
/// <param name="fileName">下载文件名</param>
/// <param name="dt">数据源</param>
public static void CreateSheet(string fileName, DataTable dt)
{
HSSFWorkbook workbook = new HSSFWorkbook();
MemoryStream ms = new MemoryStream(); //创建一个名称为Payment的工作表
ISheet paymentSheet = workbook.CreateSheet("Payment"); //数据源
DataTable tbPayment = dt; //头部标题
IRow paymentHeaderRow = paymentSheet.CreateRow(); //循环添加标题
foreach (DataColumn column in tbPayment.Columns)
paymentHeaderRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName); // 内容
int paymentRowIndex = ; foreach (DataRow row in tbPayment.Rows)
{
IRow newRow = paymentSheet.CreateRow(paymentRowIndex); //循环添加列的对应内容
foreach (DataColumn column in tbPayment.Columns)
{
newRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());
} paymentRowIndex++;
} //列宽自适应,只对英文和数字有效
for (int i = ; i <= dt.Rows.Count; i++)
{
paymentSheet.AutoSizeColumn(i);
}
//获取当前列的宽度,然后对比本列的长度,取最大值
for (int columnNum = ; columnNum <= dt.Columns.Count; columnNum++)
{
int columnWidth = paymentSheet.GetColumnWidth(columnNum) / ;
for (int rowNum = ; rowNum <= paymentSheet.LastRowNum; rowNum++)
{
IRow currentRow;
//当前行未被使用过
if (paymentSheet.GetRow(rowNum) == null)
{
currentRow = paymentSheet.CreateRow(rowNum);
}
else
{
currentRow = paymentSheet.GetRow(rowNum);
} if (currentRow.GetCell(columnNum) != null)
{
ICell currentCell = currentRow.GetCell(columnNum);
int length = Encoding.Default.GetBytes(currentCell.ToString()).Length;
if (columnWidth < length)
{
columnWidth = length;
}
}
}
paymentSheet.SetColumnWidth(columnNum, columnWidth * );
} //将表内容写入流 通知浏览器下载
workbook.Write(ms);
System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", fileName));
System.Web.HttpContext.Current.Response.BinaryWrite(ms.ToArray()); //进行二进制流下在 workbook = null;
ms.Close();
ms.Dispose();
} /// <summary>
/// 虚拟 DataTable内容
/// </summary>
/// <returns></returns>
public static DataTable CreatTable()
{
//创建DataTable 将数据库中没有的数据放到这个DT中
DataTable datatable = new DataTable();
datatable.Columns.Add("列1", typeof(string));
datatable.Columns.Add("列2", typeof(string));
datatable.Columns.Add("列3", typeof(string));
//创建DatatTable 结束--------------------------- //开始给临时datatable赋值
for (int i = ; i < ; i++)
{
DataRow row = datatable.NewRow();
row["列1"] = "列111111111111111111111111111111";
row["列2"] = "列222222222222222222222222222222222222222";
row["列3"] = "列3333333322222222222211111111111111111111111113";
datatable.Rows.Add(row);
}
return datatable;
}

代码中我加上了一个自己创建的DataTable作为数据源来进行导出,以免Demo用到数据库。

关于错误问题

当创建项目的版本高于NPOI基于的.net版本,会提示报错。

更换.net版本就行了。

另外官网提供的最新版是bate版本,我使用过程中会报错。还是选择2.0版本吧。

DEMO下载

360云盘 http://yunpan.cn/Qagu3ZYyYYqnW (提取码:0538)

再次更新(2015年11月16日 )

这次直接来一个简单的扩展,包含了泛型导出和DataTable导出:

     /// <summary>
/// Export扩展 - DataTable、泛型导出Excel
/// </summary>
public static class ExportExcel
{
/// <summary>
/// 导出Excel(03-07) 泛型集合操作
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="lists">数据源</param>
/// <param name="fileName">下载文件名</param>
/// <returns></returns>
public static byte[] ListToExcel<T>(this IList<T> lists, string fileName)
{
using (MemoryStream ms = new MemoryStream())
{
HSSFWorkbook workbook = new HSSFWorkbook();
//创建一个名称为Payment的工作表
ISheet paymentSheet = workbook.CreateSheet("Payment");
//头部标题
IRow paymentHeaderRow = paymentSheet.CreateRow(); PropertyInfo[] propertys = lists[].GetType().GetProperties();
//循环添加标题
for (int i = ; i < propertys.Count(); i++)
paymentHeaderRow.CreateCell(i).SetCellValue(propertys[i].Name);
// 内容
int paymentRowIndex = ;
foreach (var each in lists)
{
IRow newRow = paymentSheet.CreateRow(paymentRowIndex);
//循环添加列的对应内容
for (int i = ; i < propertys.Count(); i++)
{
var obj = propertys[i].GetValue(each, null);
newRow.CreateCell(i).SetCellValue(obj.ToString());
}
paymentRowIndex++;
} //列宽自适应,只对英文和数字有效
for (int i = ; i <= lists.Count; i++)
paymentSheet.AutoSizeColumn(i);
//将表内容写入流 等待下一步操作
workbook.Write(ms);
return ms.ToArray();
}
} /// <summary>
/// 导出Excel(03-07) DataTable操作
/// </summary>
/// <param name="dt">数据源</param>
/// <param name="fileName">下载文件名</param>
/// <returns></returns>
public static byte[] ListToExcel(this DataTable dt, string fileName)
{
using (MemoryStream ms = new MemoryStream())
{
HSSFWorkbook workbook = new HSSFWorkbook();
//创建一个名称为Payment的工作表
ISheet paymentSheet = workbook.CreateSheet("Payment");
//数据源
DataTable tbPayment = dt;
//头部标题
IRow paymentHeaderRow = paymentSheet.CreateRow();
//循环添加标题
foreach (DataColumn column in tbPayment.Columns)
paymentHeaderRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
// 内容
int paymentRowIndex = ;
foreach (DataRow row in tbPayment.Rows)
{
IRow newRow = paymentSheet.CreateRow(paymentRowIndex);
//循环添加列的对应内容
foreach (DataColumn column in tbPayment.Columns)
newRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());
paymentRowIndex++;
} //列宽自适应,只对英文和数字有效
for (int i = ; i <= dt.Rows.Count; i++)
paymentSheet.AutoSizeColumn(i);
//获取当前列的宽度,然后对比本列的长度,取最大值
for (int columnNum = ; columnNum <= dt.Columns.Count; columnNum++)
{
int columnWidth = paymentSheet.GetColumnWidth(columnNum) / ;
for (int rowNum = ; rowNum <= paymentSheet.LastRowNum; rowNum++)
{
//当前行未被使用过
var currentRow = paymentSheet.GetRow(rowNum) ?? paymentSheet.CreateRow(rowNum);
if (currentRow.GetCell(columnNum) != null)
{
ICell currentCell = currentRow.GetCell(columnNum);
int length = Encoding.Default.GetBytes(currentCell.ToString()).Length;
if (columnWidth < length)
columnWidth = length;
}
}
paymentSheet.SetColumnWidth(columnNum, columnWidth * );
}
//将表内容写入流 等待其他操作
workbook.Write(ms);
return ms.ToArray();
}
}
}

相关资料

解决自适应宽不支持中文问题: http://blog.csdn.net/jerry_cool/article/details/7000085

NPOI官网:http://npoi.codeplex.com/

NPOI大全:http://www.cnblogs.com/atao/category/209358.html

NPOI导出Excel - 自动适应中文宽度(帮助类下载)的更多相关文章

  1. NPOI导出Excel自动计算公式问题

    以前用过sheet.ForceFormulaRecalculation = true;当时能够自动计算出来. 今天把模板改了一下(没动公式,但是模板是老板改的,我也不知道他操作了什么),结果就不能自动 ...

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

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

  3. .NET NPOI导出Excel详解

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

  4. NPOI导出Excel示例

    摘要:使用开源程序NPOI导出Excel示例.NPOI首页地址:http://npoi.codeplex.com/,NPOI示例博客:http://tonyqus.sinaapp.com/. 示例编写 ...

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

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

  6. NPOI导出excel(带图片)

    近期项目中用到Excel导出功能,之前都是用普通的office组件导出的方法,今天尝试用下NPOI,故作此文以备日后查阅. 1.NPOI官网http://npoi.codeplex.com/,下载最新 ...

  7. 使用NPOI导出Excel引发异常(IsReadOnly = “book.IsReadOnly”引发了类型“System.NotImplementedException”的异常)

    前言: 本人调式npoi导入.导出试用成功后,引入到项目中,导入完美运行,但是导出怎么样都看不到现在的页面,而且浏览器和后台都没有报任务错误,让人好事纳闷,后来去调式,发现在除了一个IsReadOnl ...

  8. NPOI导出EXCEL报_服务器无法在发送 HTTP 标头之后追加标头

    虽然发表了2篇关于NPOI导出EXCEL的文章,但是最近再次使用的时候,把以前的代码粘贴过来,居然报了一个错误: “服务器无法在发送 HTTP 标头之后追加标头” 后来也查询了很多其他同学的文章,都没 ...

  9. NPOI导出Excel及使用问题

    NPOI导出Excel及使用问题 因为最近公司质管部门提出了一个统计报表的需求:要求导出一个2016及2017年度深圳区域的所有供应商的费用成本计算--一个22列的Excel表,其中还包括多列的合并单 ...

随机推荐

  1. Angular指令渗透式理解

    通过一段时间对angular指令的使用,理解了angular指令的意义,下面逐一介绍一下. ng-app:定义一个angualr模块,表示angular作用的范围,如下代码: ng-app在html标 ...

  2. NGUI 滑动特效之中间放大滚动

    效果图如下: 其实很简单,在NGUI原有的滑动组件的基础上处理一下比例系数就好,每个块的位置是固定的,移动的是Panel. 所以呢用Panel的位置与块的位置做差在比几个块不就成了比例系数了么..自然 ...

  3. ionic browser+ios头部高度显示问题

    ionic项目在使用ionic build browser或者打包ios时如果设置头部高度 方法如下 .bar-header { padding:; height:; } .scroll-conten ...

  4. awk删除文件第一列

    awk删除文件第一列 1.采用awk awk '{$1="";print $0}' file 2.采用sed sed -e 's/[^]* //' file sort -R fil ...

  5. 探索 OpenStack 之(8):Neutron 深入探索之 OVS + GRE 之 完整网络流程 篇

    前两篇博文分别研究了Compute节点和Neutron节点内部的网络架构.本文通过一些典型流程案例来分析具体网络流程过程. 0. 环境 同 学习OpenStack之(7):Neutron 深入学习之 ...

  6. js只弹窗一次

    <script> var alertmessage="检测到您当前浏览器为IE8或以下版本,建议您使用IE9或以上版本,或者火狐.谷歌浏览器,才能体验到最佳效果" fu ...

  7. rsync快速删除海量文件

    rsync --delete-before -avH --progress --stats /tmp/empty/ /var/spool/postfix/maildrop/ 由于业务侧使用时,一些脚本 ...

  8. RESTEasy-Rest服务框架

    什么是 RESTEasy RESTEasy 是 JBoss 的一个开源项目,提供各种框架帮助你构建 RESTful Web Services 和 RESTful Java 应用程序.它是 JAX-RS ...

  9. vtkMapper

    本文只是整理了该网页的内容:http://www.cnblogs.com/lizhengjin/archive/2009/08/16/1547340.html vtkMapper是一个抽象类,指定了几 ...

  10. Windows平台下Qt中glut库的使用

    用Qt中的QGLWidget窗体类中是不包括glut工具库的,难怪在myGLWidget(在我的程序中是QGLWidget的派生类)中绘制实心球体是说“glutSolidSphere”: 找不到标识符 ...