net 导出excel的方式
推荐三种导出excel的方式,都比较的简单。坚决不推荐使用微软的com做导出!
1、 最简答的方式
凭借一个网页上常用的html table,相信最b/s开发的每天都在和table标签打交道,不多说了,看后台的代码,给一个方法,直接调用
public void ExportToExcel(string FileType, string FileName, string ExcelContent) { System.Web.HttpContext.Current.Response.ContentType = FileType; System.Web.HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8; System.Web.HttpContext.Current.Response.Charset = "utf-8"; System.Web.HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(FileName, System.Text.Encoding.UTF8).ToString()); System.IO.StringWriter tw = new System.IO.StringWriter(); //System.Web.HttpContext.Current.Response.Output.Write(ExcelContent.ToString()); //如果采用以上代码导出时出现内容乱码,可将以下所注释的代码覆盖掉上面【System.Web.HttpContext.Current.Response.Output.Write(ExcelContent.ToString());】即可实现。 System.Web.HttpContext.Current.Response.Write("<meta http-equiv=\"content-type\" content=\"application/ms-excel; charset=utf-8\"/>" + ExcelContent.ToString()); System.Web.HttpContext.Current.Response.Flush(); System.Web.HttpContext.Current.Response.End(); }
调用方式:ExportToExcel("application/ms-excel", "会员登录日志.xls", sHtml.ToString());
优点:太简单了,没有用到任何的第三方的类库
缺点:只能在b/s模式下使用
2、使用org.in2bits.Myxls
老外的插件,还不错,速度比较的快,api比较的简单,也不多,想相信学习的可以去查看相应的文档。给个小例子吧,其实网上有很多的例子:
public ActionResult ExportExcel()
{
XlsDocument xls = new XlsDocument();
Worksheet sheet = xls.Workbook.Worksheets.Add("Sheet1");
//特别注意,开始的行和列的索引都是1
//简单写了
Enumerable.Range(1, 10).ToList().ForEach(row =>
{
//添加行
//每行添加5个单元格
Enumerable.Range(1, 5).ToList().ForEach(col =>
{
sheet.Cells.Add(row, col, string.Format("({0},{1})", row, col));
});
});
xls.Send();//发送到前台,非常简答的写法
return null;
}
mvc里写的,直接写到action里了,实际项目肯定不会这么做的。前台直接写一个连接 location.href = '@Url.Action("exportExcel")'; 就可以了,如果再加上iframe,就很容易的实现了类似于ajax效果,加个滚动条,效果就比较的炫了!
优点:还是简单,速度快;
缺点:只能用与b/s模式的项目,只能导出xls格式的excel
3、npoi
一般来说,前边带着n的基本都是从java的jar包翻译过来的,有些可能水土不服,有些的用法比较的奇葩,现在2.0以上的版本效率还是比较高的。
上代码:
public void Export(string fileName, IList<Tuple<App.Entity.t_b_testing_item, App.Entity.t_o_testing_order, App.Entity.t_b_patient, App.Entity.t_b_doctor, App.Entity.t_b_doctor_hospital>> listAll)
{
var Response = HttpContext.Current.Response;
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", fileName + DateTime.Now + ".xlsx"));
XSSFWorkbook workbook = new XSSFWorkbook();
var sheetCount = listAll.Count % excelRowLimit == 0 ? listAll.Count / excelRowLimit : listAll.Count / excelRowLimit + 1;
for (int sheetIndex = 0; sheetIndex < sheetCount; sheetIndex++)
{
var list = listAll.Skip(sheetIndex * excelRowLimit - 2).Take(excelRowLimit - 2).ToList();
var sheetName = fileName;
if (sheetCount > 1)
{
sheetName = sheetName + "_" + sheetIndex;
}
ISheet sheet1 = workbook.CreateSheet(sheetName);
//创建样式
var style = workbook.CreateCellStyle();
style.BorderBottom = style.BorderLeft = style.BorderTop = style.BorderRight = BorderStyle.Thin;
style.Alignment = HorizontalAlignment.Center;
style.VerticalAlignment = VerticalAlignment.Center;
var font = workbook.CreateFont();
font.Boldweight = (short)FontBoldWeight.Bold;
style.SetFont(font);
var rowIndex = 0;
NPOI.SS.UserModel.IRow row1 = sheet1.CreateRow(rowIndex);
CreateCell(row1, 0, style, fileName);
//给sheet1添加第一行的头部标题
row1 = sheet1.CreateRow(++rowIndex);
var titles = new string[] { "订单日期", "检测项目", "检测项目简称", "检测人信息", "医生信息", "订单状态" };
for (int i = 0; i < titles.Length; i++)
{
CreateCell(row1, i, style, titles[i]);
}
sheet1.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, titles.Length - 1));
list = list.OrderBy(o => o.Item2.Id).ThenByDescending(o => o.Item2.Order_date).ToList();
var rowStyle = workbook.CreateCellStyle();
rowStyle.BorderBottom = rowStyle.BorderLeft = rowStyle.BorderTop = rowStyle.BorderRight = BorderStyle.Thin;
rowStyle.Alignment = HorizontalAlignment.Center;
rowStyle.VerticalAlignment = VerticalAlignment.Center;
var orderIds = new List<string>();
list.ToList().ForEach(o =>
{
row1 = sheet1.CreateRow(++rowIndex);
var colIndex = 0;
CreateCell(row1, colIndex++, rowStyle, o.Item2.Order_date.ToString("yyyy-MM-dd"));
CreateCell(row1, colIndex++, rowStyle, o.Item1.Testing_item_name);
CreateCell(row1, colIndex++, rowStyle, o.Item1.Testing_item_re);
var patientInfoStr = string.Format("{0}/{1}/{2}", o.Item2.Patient_name, o.Item2.Patient_sex, DateAgeHelper.AgeStr(o.Item3.Birthdate));
CreateCell(row1, colIndex++, rowStyle, patientInfoStr);
var doctorInfoStr = string.Format("{0}/{1}/{2}", o.Item4.Doctor_name, o.Item5.Section_name_ext, o.Item5.Hospital_name_ext);
CreateCell(row1, colIndex++, rowStyle, doctorInfoStr);
CreateCell(row1, colIndex++, rowStyle, CodeDictionaryCache.FindCodeDictionaryCodeName(3, o.Item2.Order_status.ToString()));
orderIds.Add(o.Item2.Id);
});
orderIds.Select(o => new
{
IndexOf = orderIds.IndexOf(o),
LastIndexOf = orderIds.LastIndexOf(o)
}).Distinct().ToList().ForEach(o =>
{
sheet1.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(o.IndexOf + 2, o.LastIndexOf + 2, 0, 0));
sheet1.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(o.IndexOf + 2, o.LastIndexOf + 2, 3, 3));
sheet1.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(o.IndexOf + 2, o.LastIndexOf + 2, 4, 4));
sheet1.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(o.IndexOf + 2, o.LastIndexOf + 2, 5, 5));
});
}
System.IO.MemoryStream ms = new System.IO.MemoryStream();
workbook.Write(ms);
Response.BinaryWrite(ms.ToArray());
Response.Flush();
Response.End();
}
void CreateCell(NPOI.SS.UserModel.IRow row, int colIndex, ICellStyle style, object val)
{
var cell = row.CreateCell(colIndex, CellType.String);
cell.CellStyle = style;
cell.SetCellValue(val.ToString());
}
相对于前边两种导出方式,npoi的导出代码还是比较的啰嗦,也比较的奇葩,java用这种插件做导出也真是受累了。npoi 设置样式的
CellStyle 等实例是全局的,如果向在一个sheet中使用不同的样式,那就重新声明一个来调用,不要尝试去修改原先定义的,因为它的定义是基于全局的,牵一发而动全身。代码的风格基本上不是c#的风格,写起来比较累人。有点:效率比较高,可以到xlsx格式的excel,b/s,c/s模式下都可以调用缺点:写法奇葩,很容掉坑里。
致力于写简答的代码,提高开发的效率!

浙公网安备 33010602011771号