使用NPOI——C#和WEB API导出到Excel

目录

介绍

在我们开始旅程之前

背景

使用代码


介绍

本文将引导您完成通用导出到Excel功能,该功能经过试用和测试,在WEB API中使用C#并使用NPOI

本文特定于.NET Framework,而我在.NET Core中尝试过,它运行得非常好。

在我们开始旅程之前

本文的主要概念是通过导入npoi开发通用excel来导出功能,并添加下面解释的示例中包含的2cs文件,然后jet set go

背景

我们正在使用NPOI DLL进行此导出,可以免费使用,有关详细信息,请参阅NPOI NuGet

更常见的情况是,我们需要在我们的应用程序中开发导出到Excel功能,我们中的许多人通常创建无聊的string构建器,然后将其转换为Excel或使用InteropITextSharpNPOI或其他东西来实现相同的结果。

所有上面列出的方法在它们自己的上下文中都是绝对正确的,但是如果可以有一种方法导出到Excel就像传递一个对象并获得所需的输出一样简单,那么我们的生活会更容易,不是吗?

这就是我将在本文中解释的内容。

使用代码

首先,有一个实用程序函数Export(),它只是将您的CList对象转换为NPOI对象,然后最终提供给HttpResponseMessage类型,可以在您的WEB API Action中使用。

您需要2个文件才能实现它——请参阅本文中附带的解决方案以便更好地理解>>目录中的ExcelExport文件夹:

  1. AbstractDataExport.cs——包含公共代码
  2. AbstractDataExportBridge.cs——转换ListNPOI Excel对象

AbstractDataExport.cs做了什么?

参考Export(List exportData, string fileName, string sheetName = DefaultSheetName)

让我们从我们的第一个文件AbstractDataExport.cs开始

创建一个新的Excel对象——_workbook = new XSSFWorkbook();

  1. 创建新的Excel工作表对象——_sheet = _workbook.CreateSheet(_sheetName);
  2. 调用WriteData()——稍后解释
  3. 最后,创建并返回MemoryStream对象
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;

namespace GenericExcelExport.ExcelExport
{
    public interface IAbstractDataExport
    {
        HttpResponseMessage Export(List exportData, string fileName, string sheetName);
    }

    public abstract class AbstractDataExport : IAbstractDataExport
    {
        protected string _sheetName;
        protected string _fileName;
        protected List _headers;
        protected List _type;
        protected IWorkbook _workbook;
        protected ISheet _sheet;
        private const string DefaultSheetName = "Sheet1";

        public HttpResponseMessage Export
              (List exportData, string fileName, string sheetName = DefaultSheetName)
        {
            _fileName = fileName;
            _sheetName = sheetName;

            _workbook = new XSSFWorkbook(); //Creating New Excel object
            _sheet = _workbook.CreateSheet(_sheetName); //Creating New Excel Sheet object

            var headerStyle = _workbook.CreateCellStyle(); //Formatting
            var headerFont = _workbook.CreateFont();
            headerFont.IsBold = true;
            headerStyle.SetFont(headerFont);

            WriteData(exportData); //your list object to NPOI excel conversion happens here

            //Header
            var header = _sheet.CreateRow(0);
            for (var i = 0; i < _headers.Count; i++)
            {
                var cell = header.CreateCell(i);
                cell.SetCellValue(_headers[i]);
                cell.CellStyle = headerStyle;
                // It's heavy, it slows down your Excel if you have large data                
                //_sheet.AutoSizeColumn(i);
            }

            using (var memoryStream = new MemoryStream()) //creating memoryStream
            {
                _workbook.Write(memoryStream);
                var response = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new ByteArrayContent(memoryStream.ToArray())
                };

                response.Content.Headers.ContentType = new MediaTypeHeaderValue
                       ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                response.Content.Headers.ContentDisposition = 
                       new ContentDispositionHeaderValue("attachment")
                {
                    FileName = $"{_fileName}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
                };

                return response;
            }
        }

        //Generic Definition to handle all types of List
        public abstract void WriteData(List exportData);
    }
}

现在,让我们继续我们的第二个也是最后一个文件,即AbstractDataExportBridge.cs。以下是对WriteData(List exportData)的解释:

  1. 转换ListDataTable
  2. Reflection要读取属性名称,您的列标题将来自此处
  3. 循环DataTable创建excel

这里有一些改进的地方,您可以进行必要的更改,例如完全删除DataTable

using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text.RegularExpressions;

namespace GenericExcelExport.ExcelExport
{
    public class AbstractDataExportBridge : AbstractDataExport
    {
        public AbstractDataExportBridge()
        {
            _headers = new List<string>();
            _type = new List<string>();
        }

        public override void WriteData<T>(List<T> exportData)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));

            DataTable table = new DataTable();

            foreach (PropertyDescriptor prop in properties)
            {
                var type = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
                _type.Add(type.Name);
                table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? 
                                  prop.PropertyType);
                string name = Regex.Replace(prop.Name, "([A-Z])", " $1").Trim();
                //name by caps for header
                _headers.Add(name);
            }

            foreach (T item in exportData)
            {
                DataRow row = table.NewRow();
                foreach (PropertyDescriptor prop in properties)
                    row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                table.Rows.Add(row);
            }

            IRow sheetRow = null;

            for (int i = 0; i < table.Rows.Count; i++)
            {
                sheetRow = _sheet.CreateRow(i + 1);

                for (int j = 0; j < table.Columns.Count; j++)
                {
                    ICell Row1 = sheetRow.CreateCell(j);
                    string cellvalue = Convert.ToString(table.Rows[i][j]);
                    
                    // TODO: move it to switch case

                    if (string.IsNullOrWhiteSpace(cellvalue))
                    {
                        Row1.SetCellValue(string.Empty);
                    }
                    else if (_type[j].ToLower() == "string")
                    {
                        Row1.SetCellValue(cellvalue);
                    }
                    else if (_type[j].ToLower() == "int32")
                    {
                        Row1.SetCellValue(Convert.ToInt32(table.Rows[i][j]));
                    }
                    else if (_type[j].ToLower() == "double")
                    {
                        Row1.SetCellValue(Convert.ToDouble(table.Rows[i][j]));
                    }
                    else if (_type[j].ToLower() == "datetime")
                    {
                        Row1.SetCellValue(Convert.ToDateTime
                             (table.Rows[i][j]).ToString("dd/MM/yyyy hh:mm:ss"));
                    }
                    else
                    {
                        Row1.SetCellValue(string.Empty);
                    }
                }
            }
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值