惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
H
Help Net Security
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 司徒正美
量子位
N
Netflix TechBlog - Medium
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
Scott Helme
Scott Helme
The Last Watchdog
The Last Watchdog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
AI
AI
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
U
Unit 42
V2EX - 技术
V2EX - 技术
MongoDB | Blog
MongoDB | Blog
Schneier on Security
Schneier on Security
博客园 - Franky
H
Heimdal Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
W
WeLiveSecurity
P
Privacy & Cybersecurity Law Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
N
News | PayPal Newsroom
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园_首页
罗磊的独立博客
H
Hackread – Cybersecurity News, Data Breaches, AI and More
雷峰网
雷峰网

博客园 - baileyer

VisualSVN破解安装到VS2026 使用 SQL 中的递归查询(Recursive CTE)来实现1-50数字 git 忽略本地文件提交(VS) C# 自定义导出模板(NPOI) Abp vue项目找不到模块“./app.vue” MSSqlserver分割文件备份恢复 github的镜像下载加快clone下载速度 widows部署.NET Core 3.1项目到IIS问题 .net core/mvc获取特性 oracle instr 替代like查询 quartz3.0.7和topshelf4.2.1实现任务调度 VS2017同时生成.net core和.net framework两份代码 .net core Failed to load API definition 错误 vs 2017 调试中断问题 .net Core 2.2实现京东宙斯API采用OAuth授权方式调用 WinForm 校验只能输入数字英文字母退格键 C#通过反射获取相应的字段和值 activemq.bat 在window7 x64下启动(安装)报错解决方案 <asp:RadioButton> 选项判断
NPOI导出excel
baileyer · 2018-08-31 · via 博客园 - baileyer

  本人在项目中用到导出,以前几乎没做过导出导入这类的功能,最近自己独立开发了几个项目,都用到了导出,于是便来一篇文章,记录一下,方便以后查找,也方便各位新手!

例子比较简单,不喜勿喷,如果有其它补充,请留言!谢谢!以下导出采用的是导出DataTable,没有做过多复杂的!

1. NPOI 帮助类,我使用的是 V2.3.0,改造的代码:

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace bmy.Common
{
    public static class NPOIExcelHelper
    {
 /// <summary>
        ///  组装workbook.
        /// </summary>
        /// <param name="dictionary">列头</param>
        /// <param name="dt">dataTable数据</param>
        /// <param name="columnHeader">表头</param>
        /// <returns></returns>
        public static HSSFWorkbook BuildWorkbook1(Dictionary<string, string> dictionary, DataTable dt, string columnHeader = "")
        {
            var workbook = new HSSFWorkbook();
            ISheet sheet = workbook.CreateSheet(string.IsNullOrWhiteSpace(dt.TableName) ? "Sheet1" : dt.TableName);

            var dateStyle = workbook.CreateCellStyle();
            var format = workbook.CreateDataFormat();
            dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");

            //取得列宽
            // var arrColWidth = new int[dt.Columns.Count];
            var arrColWidth = new int[dictionary.Count + 1];
            int itemCoutn = 0;//需要导出的列的数量.
            foreach (DataColumn item in dt.Columns)
            {
                //判断需要导出的 “列”

                if (dictionary.ContainsKey(item.ColumnName))
                {
                    arrColWidth[itemCoutn] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;
                    itemCoutn++;
                }
            }
            itemCoutn = 0;
            for (var i = 0; i < dt.Rows.Count; i++)
            {
                for (var j = 0; j < dt.Columns.Count; j++)
                {
                    //判断需要导出的 “列”
                    if (dictionary.ContainsKey(dt.Rows[i][j].ToString()))
                    {
                        int intTemp = Encoding.GetEncoding(936).GetBytes(dt.Rows[i][j].ToString()).Length;
                        if (intTemp > arrColWidth[j])
                        {
                            arrColWidth[j] = intTemp;
                        }
                    }
                }
            }
            int rowIndex = 0;//行索引,第一行为:表头(列头)

            foreach (DataRow row in dt.Rows)
            {
                #region 表头 列头
                if (rowIndex == 65535 || rowIndex == 0)
                {
                    if (rowIndex != 0)
                    {
                        sheet = workbook.CreateSheet();
                    }

                    #region 表头及样式
                    {
                        IRow headerRow = sheet.CreateRow(0);
                        headerRow.HeightInPoints = 19.5F;
                        headerRow.Height = 40 * 20;
                        headerRow.CreateCell(0).SetCellValue(columnHeader);

                        //CellStyle
                        ICellStyle headStyle = workbook.CreateCellStyle();
                        headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中    
                        headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 
                        // 设置单元格的背景颜色(单元格的样式会覆盖列或行的样式)    
                        headStyle.FillForegroundColor = (short)11;
                        //定义font
                        IFont font = workbook.CreateFont();
                        font.FontHeightInPoints = 20;
                        font.Boldweight = 700;
                        headStyle.SetFont(font);
                        headerRow.GetCell(0).CellStyle = headStyle;
                        //根据表的列数计算
                        //sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, dt.Columns.Count - 1));
                        sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, dictionary.Count));
                    #endregion

                    }
                    {
                        #region 列头及样式

                        var headerRow = sheet.CreateRow(1);
                        //CellStyle
                        ICellStyle headStyle = workbook.CreateCellStyle();
                        headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中    
                        headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 
                        //定义font
                        IFont font = workbook.CreateFont();
                        font.FontHeightInPoints = 10;
                        font.Boldweight = 700;
                        headStyle.SetFont(font);

                        int columnCount = 0;
                        foreach (var dic in dictionary)
                        {
                            foreach (DataColumn column in dt.Columns)
                            {
                                //判断需要导出的 “列”
                                if (dic.Key.ToLower()==column.ColumnName.ToLower())
                                {
                                    //headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
                                    //headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
                                    //sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256);
                                    headerRow.CreateCell(columnCount).SetCellValue(dic.Value);//column.ColumnName
                                    headerRow.GetCell(columnCount).CellStyle = headStyle;
                                    sheet.SetColumnWidth(columnCount, (arrColWidth[columnCount]) * 256);
                                    columnCount++;
                                    continue;
                                }
                            }
                        }
                        #endregion
                    }

                    rowIndex = 2;
                }
                #endregion


                #region 内容
                var dataRow = sheet.CreateRow(rowIndex);

                int columnContentCount = 0; //column.Ordinal
                foreach (var dicKey in dictionary)
                {
                    foreach (DataColumn column in dt.Columns)
                    {
                        //判断需要导出的 “列”
                        if (dicKey.Key.ToLower()==column.ColumnName.ToLower())
                        {
                            var newCell = dataRow.CreateCell(columnContentCount);

                            string drValue = row[column].ToString();

                            switch (column.DataType.ToString())
                            {
                                case "System.String"://字符串类型
                                    newCell.SetCellValue(drValue);
                                    break;
                                case "System.DateTime"://日期类型
                                    DateTime dateV;
                                    DateTime.TryParse(drValue, out dateV);
                                    newCell.SetCellValue(dateV);

                                    newCell.CellStyle = dateStyle;//格式化显示
                                    break;
                                case "System.Boolean"://布尔型
                                    bool boolV = false;
                                    bool.TryParse(drValue, out boolV);
                                    newCell.SetCellValue(boolV);
                                    break;
                                case "System.Int16"://整型
                                case "System.Int32":
                                case "System.Int64":
                                case "System.Byte":
                                    int intV = 0;
                                    int.TryParse(drValue, out intV);
                                    newCell.SetCellValue(intV);
                                    break;
                                case "System.Decimal"://浮点型
                                case "System.Double":
                                    double doubV = 0;
                                    double.TryParse(drValue, out doubV);
                                    newCell.SetCellValue(doubV);
                                    break;
                                case "System.DBNull"://空值处理
                                    newCell.SetCellValue("");
                                    break;
                                default:
                                    newCell.SetCellValue("");
                                    break;
                            }
                            columnContentCount++;//列索引
                            continue;
                        }
                    }
                }

                #endregion

                rowIndex++;
            }
            //自动列宽
            for (int i = 0; i <= dictionary.Count; i++)
                sheet.AutoSizeColumn(i, true);


            return workbook;
        }
    
    }    

}

View Code

2.调用,先保存数据到文件夹,再将文件返回给调用页面提供下载,下载完成就删除文件,节省资源。

  public static string WriteSheet(Dictionary<string, string> dictionary, DataTable dt, string path, string sheetName)
        {
            HSSFWorkbook newBook = BuildWorkbook1(dictionary, dt, sheetName);
            string date = DateTime.Now.ToString("yyyyMMddHHmmss");
            string fileName = sheetName + "_" + date;

            #region 保存C:\ExcelList
            //string urlPath = "\\ExcelList\\" + fileName;
            //string filePath = urlPath;
            //string directoryName = Path.GetDirectoryName(urlPath);
            //if (!Directory.Exists(directoryName))
            //{
            //    Directory.CreateDirectory(directoryName);
            //}
            //using (var fs = File.OpenWrite(urlPath + ".xls"))
            //{
            //    newBook.Write(fs);
            //    Console.WriteLine("生成成功");
            //} 
            #endregion

           
            string urlPath2 = "/ExcelList/" + fileName;
            string directoryName2 = Path.GetDirectoryName(urlPath2);

            string newUrl = path + directoryName2;
            if (!Directory.Exists(newUrl))
            {
                Directory.CreateDirectory(newUrl);
            }
            using (var fs = File.OpenWrite(path + urlPath2 + ".xls"))
            {
                newBook.Write(fs);
                Console.WriteLine("生成成功");
            } 

            return fileName + ".xls";

        }

View Code

3.页面调用方法, Dictionary<string, string>的作用就是将要导出的DataTable数据的字段,换成中文名称,方便阅读。

 Dictionary<string, string> dictionary = new Dictionary<string, string>();

            DataTable dt = ExcelExport(1, 10000);
            if (dt.Rows.Count > 0)
            {
                sheetName = "待审核订单列表";
                dictionary.Add("OrderNo", "待审核订单号");
                dictionary.Add("Mobile", "手机号码");

                //返回路径下载
                string path = System.AppDomain.CurrentDomain.BaseDirectory;
                string fileName = MxWeiXinPF.Common.NPOIExcelHelper.WriteSheet(dictionary, dt, path, sheetName);
                //文件夹
                string folder = "/ExcelList/";
                //下载
                this.ResponDown(Response, path, folder, fileName);

View Code

4.下载方法

  /// <summary>
        /// 下载
        /// </summary>
        /// <param name="response">封装来自ASP.NET 的http相应消息</param>
        /// <param name="path">文件路径</param>
        /// <param name="folder">文件夹</param>
        /// <param name="fileName">文件名</param>
        public void ResponDown(HttpResponse response, string path, string folder, string fileName)
        {
            response.Clear();
            response.ClearHeaders();
            response.Buffer = false;
            response.ContentType = "application/ms-excel";
            response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
            //Response.Write(writer);
            FileStream file = new FileStream(path + folder + fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            BinaryReader br = new BinaryReader(file);
            response.AppendHeader("Content-Length", file.Length.ToString());
            // StringReader sr = new StringReader(writer.GetStringBuilder().ToString());
            long flen = file.Length;
            int size = 102400;//每100k同时下载数据
            byte[] readdata = new byte[size];//指定缓冲区的大小
            if (size > flen) size = Convert.ToInt32(flen);
            long fpos = 0;
            bool isend = false;
            while (!isend)
            {
                if (response.IsClientConnected)
                {
                    if ((fpos + size) > flen)
                    {
                        size = Convert.ToInt32(flen - fpos);
                        readdata = new byte[size];
                        isend = true;
                    }
                    if (size > 1)
                    {
                        br.Read(readdata, 0, size);//读入一个压缩块
                        // byte[] re = Encoding.UTF8.GetBytes(readdata, 0, readdata.Length);
                        response.BinaryWrite(readdata);
                        //Response.OutputStream.Write(re, 0, size);
                    }
                    fpos += size;
                }
                else
                {
                    response.End();
                }
            }
            file.Close();
            br.Close();
            response.Flush();
            Response.Close();

            File.Delete(path + folder + fileName);   //删除文件
            response.End();
        }

View Code

最后,完成!只是简单记录,对于代码没有更好的优化,尽量以后整理好点贡献给大家!