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模式下都可以调用缺点:写法奇葩,很容掉坑里。

 致力于写简答的代码,提高开发的效率!

 

posted @ 2015-12-08 19:26  左立军  阅读(312)  评论(0)    收藏  举报