架构师_程序员

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7353|回复: 65

[WebAPI] webapi将list数据导出成Excel表格文件

  [复制链接]
跳转到指定楼层
楼主
发表于 2018-7-16 22:26:35
zu
使用c#导出excel表格,需要用到npoi,介绍如下:

NPOI是指构建在POI 3.x版本之上的一个程序,NPOI可以在没有安装Office的情况下对Word或Excel文档进行读写操作。
NPOI是一个开源的C#读写Excel、WORD等微软OLE2组件文档的项目。

网上很多的代码,都需要把数据存到服务器,搞成物理文件,再导出(或者给一个下载链接),本帖子代码,不需要存物理文件,直接可以把list数据导出下载

先看效果图:


我们用浏览器,访问:http://localhost:63096/api/download/test 接口地址,即可下载excel文件。

下载完成后,我们打开test.xls,可以正常打开和读取!如下图:



准备list数据,代码:

  1. public class UserInfo
  2.     {
  3.         public static List<UserInfo> GetList()
  4.         {
  5.             List<UserInfo> list = new List<UserInfo>();
  6.             list.Add(new UserInfo("张山", "男", 18, "羽毛球"));
  7.             list.Add(new UserInfo("李四", "男", 23, "篮球"));
  8.             list.Add(new UserInfo("小渣渣", "男", 23, "编程"));
  9.             list.Add(new UserInfo("小芳", "女", 25, "足球"));
  10.             list.Add(new UserInfo("小花", "女", 11, "可乐"));
  11.             list.Add(new UserInfo("架构师", "男", 4, "http://www.itsvse.com"));
  12.             return list;
  13.         }

  14.         public UserInfo(string n,string s,int a,string  l)
  15.         {
  16.             this.Name = n;
  17.             this.Sex = s;
  18.             this.Age = a;
  19.             this.Like = l;
  20.         }
  21.         public string Name { get; set; }

  22.         public string Sex { get; set; }


  23.         public int Age { get; set; }

  24.         public string Like { get; set; }
  25.     }
复制代码


webapi代码如下:

  1. [HttpGet]
  2.         public IHttpActionResult Test()
  3.         {

  4.             var browser = String.Empty;
  5.             if (HttpContext.Current.Request.UserAgent != null)
  6.             {
  7.                 browser = HttpContext.Current.Request.UserAgent.ToUpper();
  8.             }
  9.             HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK);
  10.             #region 内容
  11.             // Excel列的名称
  12.             Dictionary<string, string> cellheader = new Dictionary<string, string> {
  13.                 { "Name", "姓名" },
  14.                 { "Sex", "性别" },
  15.                 { "Age", "年龄" },
  16.                 { "Like", "爱好" },
  17.             };
  18.             var info = EntityListToExcel2003(cellheader, UserInfo.GetList(), "用户信息");
  19.             #endregion
  20.             Stream stream = new MemoryStream(info);
  21.             httpResponseMessage.Content = new StreamContent(stream);
  22.             httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
  23.             httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
  24.             {
  25.                 FileName =
  26.                     browser.Contains("FIREFOX")
  27.                         ? Path.GetFileName("test.xlsx")
  28.                         : HttpUtility.UrlEncode(Path.GetFileName("test.xls"))
  29.             };
  30.             return ResponseMessage(httpResponseMessage);
  31.         }
复制代码


EntityListToExcel2003方法如下:

  1. /// <summary>
  2.         /// 实体类集合导出到Excle2003
  3.         /// </summary>
  4.         /// <param name="cellHeard">单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };</param>
  5.         /// <param name="enList">数据源</param>
  6.         /// <param name="sheetName">工作表名称</param>
  7.         /// <returns>byte[]</returns>
  8.         public static byte[] EntityListToExcel2003(Dictionary<string, string> cellHeard, IList enList, string sheetName)
  9.         {
  10.             try
  11.             {
  12.                 // 2.解析单元格头部,设置单元头的中文名称
  13.                 HSSFWorkbook workbook = new HSSFWorkbook(); // 工作簿
  14.                 ISheet sheet = workbook.CreateSheet(sheetName); // 工作表
  15.                 IRow row = sheet.CreateRow(0);
  16.                 List<string> keys = cellHeard.Keys.ToList();
  17.                 for (int i = 0; i < keys.Count; i++)
  18.                 {
  19.                     row.CreateCell(i).SetCellValue(cellHeard[keys[i]]); // 列名为Key的值
  20.                 }
  21.                 // 3.List对象的值赋值到Excel的单元格里
  22.                 int rowIndex = 1; // 从第二行开始赋值(第一行已设置为单元头)
  23.                 foreach (var en in enList)
  24.                 {
  25.                     IRow rowTmp = sheet.CreateRow(rowIndex);
  26.                     for (int i = 0; i < keys.Count; i++) // 根据指定的属性名称,获取对象指定属性的值
  27.                     {
  28.                         string cellValue = ""; // 单元格的值
  29.                         object properotyValue = null; // 属性的值
  30.                         System.Reflection.PropertyInfo properotyInfo = null; // 属性的信息

  31.                         // 3.1 若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:UserEn.UserName
  32.                         if (keys[i].IndexOf(".") >= 0)
  33.                         {
  34.                             // 3.1.1 解析子类属性(这里只解析1层子类,多层子类未处理)
  35.                             string[] properotyArray = keys[i].Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
  36.                             string subClassName = properotyArray[0]; // '.'前面的为子类的名称
  37.                             string subClassProperotyName = properotyArray[1]; // '.'后面的为子类的属性名称
  38.                             System.Reflection.PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 获取子类的类型
  39.                             if (subClassInfo != null)
  40.                             {
  41.                                 // 3.1.2 获取子类的实例
  42.                                 var subClassEn = en.GetType().GetProperty(subClassName).GetValue(en, null);
  43.                                 // 3.1.3 根据属性名称获取子类里的属性类型
  44.                                 properotyInfo = subClassInfo.PropertyType.GetProperty(subClassProperotyName);
  45.                                 if (properotyInfo != null)
  46.                                 {
  47.                                     properotyValue = properotyInfo.GetValue(subClassEn, null); // 获取子类属性的值
  48.                                 }
  49.                             }
  50.                         }
  51.                         else
  52.                         {
  53.                             // 3.2 若不是子类的属性,直接根据属性名称获取对象对应的属性
  54.                             properotyInfo = en.GetType().GetProperty(keys[i]);
  55.                             if (properotyInfo != null)
  56.                             {
  57.                                 properotyValue = properotyInfo.GetValue(en, null);
  58.                             }
  59.                         }
  60.                         // 3.3 属性值经过转换赋值给单元格值
  61.                         if (properotyValue != null)
  62.                         {
  63.                             cellValue = properotyValue.ToString();
  64.                             // 3.3.1 对时间初始值赋值为空
  65.                             if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")
  66.                             {
  67.                                 cellValue = string.Empty;
  68.                             }
  69.                         }

  70.                         // 3.4 填充到Excel的单元格里
  71.                         rowTmp.CreateCell(i).SetCellValue(cellValue);
  72.                     }
  73.                     rowIndex++;
  74.                 }
  75.                 MemoryStream ms = new MemoryStream();
  76.                 workbook.Write(ms);
  77.                 byte[] data = ms.ToArray();
  78.                 return data;
  79.             }
  80.             catch (Exception ex)
  81.             {
  82.                 throw ex;
  83.             }
  84.         }
复制代码




上一篇:Asp.net mvc bundle将所有css文件打包在一起
下一篇:vs2017 浏览器输入路径就终止调试
帖子永久地址: 

架构师_程序员 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与架构师_程序员享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和架构师_程序员的同意
4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、架构师_程序员管理员和版主有权不事先通知发贴者而删除本文

码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
推荐
发表于 2019-1-7 11:22:53
非常好,我用这个泛型的
/// <summary>
        /// 将一组对象导出成EXCEL
        /// </summary>
        /// <typeparam name="T">要导出对象的类型</typeparam>
        /// <param name="objList">一组对象</param>
        /// <param name="FileName">导出后的文件名</param>
        /// <param name="columnInfo">列名信息</param>
        public void ListToExcel<T>(List<T> objList, string FileName, Dictionary<string, string> columnInfo)
        {
            if (columnInfo.Count == 0) { return; }
            if (objList.Count == 0) { return; }
            //生成EXCEL的HTML
            string excelStr = "";
            Type myType = objList[0].GetType();
            //根据反射从传递进来的属性名信息得到要显示的属性
            List<System.Reflection.PropertyInfo> myPro = new List<System.Reflection.PropertyInfo>();
            foreach (string cName in columnInfo.Keys)
            {
                System.Reflection.PropertyInfo p = myType.GetProperty(cName);
                if (p != null)
                {
                    myPro.Add(p);
                    excelStr += columnInfo[cName] + "\t";
                }
            }
            //如果没有找到可用的属性则结束
            if (myPro.Count == 0) { return; }
            excelStr += "\n";
            foreach (T obj in objList)
            {
                foreach (System.Reflection.PropertyInfo p in myPro)
                {
                    excelStr += p.GetValue(obj, null) + "\t";
                }
                excelStr += "\n";
            }
            //输出EXCEL
            HttpResponse rs = System.Web.HttpContext.Current.Response;
            rs.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
            rs.AppendHeader("Content-Disposition", "attachment;filename=" + FileName);
            rs.ContentType = "application/ms-excel";
            rs.Write(excelStr);
            rs.End();
        }
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
推荐
 楼主| 发表于 2019-7-31 13:22:31

不客气
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
推荐
发表于 2019-6-18 14:39:34
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
沙发
发表于 2018-7-20 08:09:57
山山水水

评分

参与人数 1MB -1 贡献 -1 收起 理由
QWERTYU -1 -1 请勿灌水,提高回帖质量是每位会员应尽的义.

查看全部评分

码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
回复

使用道具 举报

板凳
发表于 2018-7-25 09:23:54
可以看看,比较好
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
地板
发表于 2018-7-25 09:27:42
挺不错的
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
回复

使用道具 举报

5#
发表于 2018-8-22 15:56:01
EntityListToExcel2003 方法内容呢
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
6#
发表于 2018-9-5 16:24:07
水水水水水水水水水水水

评分

参与人数 1MB -1 贡献 -1 收起 理由
QWERTYU -1 -1 请勿灌水,提高回帖质量是每位会员应尽的义.

查看全部评分

码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
7#
发表于 2018-9-6 09:30:18
赞一个·标记一下·以后用得着!
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
8#
发表于 2018-9-19 15:05:17
很有用,谢谢
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
9#
发表于 2018-9-27 08:56:58
支持楼主更新~
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
10#
发表于 2018-9-27 09:14:28
了解一下
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。

Mail To:help@itsvse.com

QQ|Archiver|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2019-8-20 02:16

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表