生成导出EXCEL太慢了,一万条数据要10分钟左右

时间:2021-05-08 23:20:15
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ICSharpCode;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System.Data;
using System.Reflection;
using System.Text.RegularExpressions;

    public class WordHelp
    {

        #region Excel列类型获取列的值
        /// <summary>
        /// 根据Excel列类型获取列的值
        /// </summary>
        /// <param name="cell">Excel列</param>
        /// <returns></returns>
        private static string GetCellValue(ICell cell)
        {
            if (cell == null)
                return string.Empty;
            switch (cell.CellType)
            {
                case CellType.Blank:
                    return string.Empty;
                case CellType.Boolean:
                    return cell.BooleanCellValue.ToString();
                case CellType.Error:
                    return cell.ErrorCellValue.ToString();
                case CellType.Numeric:
                case CellType.Unknown:
                default:
                    return cell.ToString();//This is a trick to get the correct value of the cell. NumericCellValue will return a numeric value no matter the cell value is a date or a number
                case CellType.String:
                    return cell.StringCellValue;
                case CellType.Formula:
                    try
                    {
                        XSSFFormulaEvaluator e = new XSSFFormulaEvaluator(cell.Sheet.Workbook);
                        e.EvaluateInCell(cell);
                        return cell.ToString();
                    }
                    catch
                    {
                        return cell.NumericCellValue.ToString();
                    }
            }
        }
        #endregion

        //数据量过大会造成响应时间过长
        /// <summary>
        /// 自动设置Excel列宽
        /// </summary>
        /// <param name="sheet">Excel表</param>
        //private static void AutoSizeColumns(ISheet sheet)
        //{
        //    if (sheet.PhysicalNumberOfRows > 0)
        //    {
        //        IRow headerRow = sheet.GetRow(0);

        //        for (int i = 0, l = headerRow.LastCellNum; i < l; i++)
        //        { 
        //            sheet.AutoSizeColumn(i);
        //        }
        //    }
        //}

        /// <summary>
        /// 保存Excel文档流到文件
        /// </summary>
        /// <param name="ms">Excel文档流</param>
        /// <param name="fileName">文件名</param>
        private static void SaveToFile(MemoryStream ms, string fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
            {
                byte[] data = ms.ToArray();

                fs.Write(data, 0, data.Length);
                fs.Flush();

                data = null;
            }
        }

        ///// <summary>
        ///// 输出文件到浏览器
        ///// </summary>
        ///// <param name="ms">Excel文档流</param>
        ///// <param name="context">HTTP上下文</param>
        ///// <param name="fileName">文件名</param>
        //private static void RenderToBrowser(MemoryStream ms, HttpContext context, string fileName)
        //{
        //    if (context.Request.Browser.Browser == "IE")
        //        fileName = HttpUtility.UrlEncode(fileName);
        //    context.Response.AddHeader("Content-Disposition", "attachment;fileName=" + fileName);
        //    context.Response.BinaryWrite(ms.ToArray());
        //}

        /// <summary>
        /// DataReader转换成Excel文档流
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public static MemoryStream RenderToExcel(IDataReader reader)
        {
            MemoryStream ms = new MemoryStream();

            using (reader)
            {
                IWorkbook workbook = new XSSFWorkbook();

                ISheet sheet = workbook.CreateSheet();

                IRow headerRow = sheet.CreateRow(0);
                int cellCount = reader.FieldCount;

                // handling header.
                for (int i = 0; i < cellCount; i++)
                {
                    headerRow.CreateCell(i).SetCellValue(reader.GetName(i));
                }

                // handling value.
                int rowIndex = 1;
                while (reader.Read())
                {
                    IRow dataRow = sheet.CreateRow(rowIndex);

                    for (int i = 0; i < cellCount; i++)
                    {
                        dataRow.CreateCell(i).SetCellValue(reader[i].ToString());
                    }

                    rowIndex++;
                }

                //AutoSizeColumns(sheet);

                workbook.Write(ms);
                ms.Flush();
                ms.Position = 0;
            }

            return ms;
        }

        /// <summary>
        /// DataReader转换成Excel文档流,并保存到文件
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="fileName">保存的路径</param>
        public static void RenderToExcel(IDataReader reader, string fileName)
        {
            using (MemoryStream ms = RenderToExcel(reader))
            {
                SaveToFile(ms, fileName);
            }
        }

        ///// <summary>
        ///// DataReader转换成Excel文档流,并输出到客户端
        ///// </summary>
        ///// <param name="reader"></param>
        ///// <param name="context">HTTP上下文</param>
        ///// <param name="fileName">输出的文件名</param>
        //public static void RenderToExcel(IDataReader reader, HttpContext context, string fileName)
        //{
        //    using (MemoryStream ms = RenderToExcel(reader))
        //    {
        //        RenderToBrowser(ms, context, fileName);
        //    }
        //}

        /// <summary>
        /// DataTable转换成Excel文档流
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public static MemoryStream RenderToExcel(DataTable table)
        {
            MemoryStream ms = new MemoryStream();

            using (table)
            {
                IWorkbook workbook = new XSSFWorkbook();

                ISheet sheet = workbook.CreateSheet();

                IRow headerRow = sheet.CreateRow(0);

                // handling header.
                foreach (DataColumn column in table.Columns)
                    headerRow.CreateCell(column.Ordinal).SetCellValue(column.Caption);//If Caption not set, returns the ColumnName value
                // handling value.
                int rowIndex = 1;

                foreach (DataRow row in table.Rows)
                {
                    IRow dataRow = sheet.CreateRow(rowIndex);

                    foreach (DataColumn column in table.Columns)
                    {
                        dataRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());
                    }

                    rowIndex++;
                }
                //AutoSizeColumns(sheet);

                workbook.Write(ms);
                ms.Flush();
                //ms.Position = 0;
            }

            return ms;
        }

        /// <summary>
        /// DatasSet转换成Excel文档流
        /// </summary>
        /// <param name="sourceDs">DataSet</param>
        /// <param name="sheetName">工作表命,按逗号分隔</param>
        /// <returns></returns>
        private static MemoryStream RenderToExcel(DataSet sourceDs, string sheetName)
        {
            IWorkbook workbook = new XSSFWorkbook();
            MemoryStream ms = new MemoryStream();
            string[] sheetNames = sheetName.Split(',');
            for (int i = 0; i < sheetNames.Length; i++)
            {
                ISheet sheet = workbook.CreateSheet(sheetNames[i]);
                IRow headerRow = sheet.CreateRow(0);
                // handling header. 
                foreach (DataColumn column in sourceDs.Tables[i].Columns)
                    headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
                // handling value. 
                int rowIndex = 1;
                foreach (DataRow row in sourceDs.Tables[i].Rows)
                {
                    IRow dataRow = sheet.CreateRow(rowIndex);

                    foreach (DataColumn column in sourceDs.Tables[i].Columns)
                    {
                        dataRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());
                    }
                    rowIndex++;
                }
            }
            workbook.Write(ms);
            ms.Flush();
            //ms.Position = 0;
            //workbook = null;
            return ms;
        }

        /// <summary>
        /// DataTable转换成Excel文档流,并保存到文件
        /// </summary>
        /// <param name="table"></param>
        /// <param name="fileName">保存的路径</param>
        public static void RenderToExcel(DataTable table, string fileName)
        {
            using (MemoryStream ms = RenderToExcel(table))
            {
                SaveToFile(ms, fileName);
            }
        }

        ///// <summary>
        ///// DataTable转换成Excel文档流,并输出到客户端
        ///// </summary>
        ///// <param name="table"></param>
        ///// <param name="response"></param>
        ///// <param name="fileName">输出的文件名</param>
        //public static void RenderToExcel(DataTable table, HttpContext context, string fileName)
        //{
        //    using (MemoryStream ms = RenderToExcel(table))
        //    {
        //        RenderToBrowser(ms, context, fileName);
        //    }
        //}

        #region Excel验证是否有数据
        /// <summary>
        /// Excel文档流是否有数据
        /// </summary>
        /// <param name="excelFileStream">Excel文档流</param>
        /// <returns></returns>
        public static bool HasData(Stream excelFileStream)
        {
            return HasData(excelFileStream, 0);
        }

        /// <summary>
        /// Excel文档流是否有数据
        /// </summary>
        /// <param name="

13 个解决方案

#1


生成导出EXCEL太慢了,一万条数据要10分钟左右

 
 这个很正常,微软提供的东西就是那么的慢。因为不开源,所以你还不能优化。

 如果你要快点,可以从COM+ 底层API入手,直接调用,或许能增加速率。不过COM+ 貌似已经淘汰许久。

#2


引用 1 楼 tangyanzhi1111 的回复:
生成导出EXCEL太慢了,一万条数据要10分钟左右

 
 这个很正常,微软提供的东西就是那么的慢。因为不开源,所以你还不能优化。

 如果你要快点,可以从COM+ 底层API入手,直接调用,或许能增加速率。不过COM+ 貌似已经淘汰许久。


生成导出EXCEL太慢了,一万条数据要10分钟左右生成导出EXCEL太慢了,一万条数据要10分钟左右生成导出EXCEL太慢了,一万条数据要10分钟左右

#3


引用 1 楼 tangyanzhi1111 的回复:
生成导出EXCEL太慢了,一万条数据要10分钟左右

 
 这个很正常,微软提供的东西就是那么的慢。因为不开源,所以你还不能优化。

 如果你要快点,可以从COM+ 底层API入手,直接调用,或许能增加速率。不过COM+ 貌似已经淘汰许久。


说你二笔不知道有没有人点赞

#4


开一个线程,让他自己慢慢生成去。
生成完了,就通知一下就好了。

#5


引用 3 楼 diaodiaop 的回复:
Quote: 引用 1 楼 tangyanzhi1111 的回复:

生成导出EXCEL太慢了,一万条数据要10分钟左右

 
 这个很正常,微软提供的东西就是那么的慢。因为不开源,所以你还不能优化。

 如果你要快点,可以从COM+ 底层API入手,直接调用,或许能增加速率。不过COM+ 貌似已经淘汰许久。


说你二笔不知道有没有人点赞


--------------------------------

说我是你爹,肯定有人点赞....  你不信,叫声亲爹试试

#6


引用 4 楼 hanjun0612 的回复:
开一个线程,让他自己慢慢生成去。
生成完了,就通知一下就好了。

那效率也还是没有得到改善。。。。。。 生成导出EXCEL太慢了,一万条数据要10分钟左右

#7


引用 6 楼 qq_28419365 的回复:
Quote: 引用 4 楼 hanjun0612 的回复:

开一个线程,让他自己慢慢生成去。
生成完了,就通知一下就好了。

那效率也还是没有得到改善。。。。。。 生成导出EXCEL太慢了,一万条数据要10分钟左右

你1万条数据要放到excel啊。。。慢也是正常。
我不清楚能不能 使用 并行方式Parallel  能不能同时操作一个excel,把数据整进去。。。感觉不太行。 生成导出EXCEL太慢了,一万条数据要10分钟左右

#8


你试试看吧。我也不清楚 Parallel行不行。

#9


引用 5 楼 tangyanzhi1111 的回复:
Quote: 引用 3 楼 diaodiaop 的回复:

Quote: 引用 1 楼 tangyanzhi1111 的回复:

生成导出EXCEL太慢了,一万条数据要10分钟左右

 
 这个很正常,微软提供的东西就是那么的慢。因为不开源,所以你还不能优化。

 如果你要快点,可以从COM+ 底层API入手,直接调用,或许能增加速率。不过COM+ 貌似已经淘汰许久。


说你二笔不知道有没有人点赞




你这种人多厉害.. 代码都不看 就知道人家要问什么.. 还com+ 呵呵. 是不是觉得自己阅代码无数?

#10


https://bbs.csdn.net/topics/390830774

datareader 不知道.. datatable反正是很快的  看下帖子  看看哪里不同

#11


引用 10 楼 diaodiaop 的回复:
https://bbs.csdn.net/topics/390830774

datareader 不知道.. datatable反正是很快的  看下帖子  看看哪里不同



------------------

【datatable很快,npoi 封装】,这逼 这垃圾玩意还发链接,拿出来丢人?


看你这逼的发的资源别人第一条评论: 这种垃圾,还好意思13分...


回去种田吧,蠢逼,笑死你爹。

#12


如果是单纯的想快速导出,而且,数据中没有特殊符号(主要是TAB和回车),可以试试:用string字符串保存导出的内容,两个单元格之间用TAB分隔,两行之间用回车分隔,全部导出完成后,新建一个空EXCEL,再将结果粘贴进去。

#13


可以试试第三方插件NOPI 效率还可以

#1


生成导出EXCEL太慢了,一万条数据要10分钟左右

 
 这个很正常,微软提供的东西就是那么的慢。因为不开源,所以你还不能优化。

 如果你要快点,可以从COM+ 底层API入手,直接调用,或许能增加速率。不过COM+ 貌似已经淘汰许久。

#2


引用 1 楼 tangyanzhi1111 的回复:
生成导出EXCEL太慢了,一万条数据要10分钟左右

 
 这个很正常,微软提供的东西就是那么的慢。因为不开源,所以你还不能优化。

 如果你要快点,可以从COM+ 底层API入手,直接调用,或许能增加速率。不过COM+ 貌似已经淘汰许久。


生成导出EXCEL太慢了,一万条数据要10分钟左右生成导出EXCEL太慢了,一万条数据要10分钟左右生成导出EXCEL太慢了,一万条数据要10分钟左右

#3


引用 1 楼 tangyanzhi1111 的回复:
生成导出EXCEL太慢了,一万条数据要10分钟左右

 
 这个很正常,微软提供的东西就是那么的慢。因为不开源,所以你还不能优化。

 如果你要快点,可以从COM+ 底层API入手,直接调用,或许能增加速率。不过COM+ 貌似已经淘汰许久。


说你二笔不知道有没有人点赞

#4


开一个线程,让他自己慢慢生成去。
生成完了,就通知一下就好了。

#5


引用 3 楼 diaodiaop 的回复:
Quote: 引用 1 楼 tangyanzhi1111 的回复:

生成导出EXCEL太慢了,一万条数据要10分钟左右

 
 这个很正常,微软提供的东西就是那么的慢。因为不开源,所以你还不能优化。

 如果你要快点,可以从COM+ 底层API入手,直接调用,或许能增加速率。不过COM+ 貌似已经淘汰许久。


说你二笔不知道有没有人点赞


--------------------------------

说我是你爹,肯定有人点赞....  你不信,叫声亲爹试试

#6


引用 4 楼 hanjun0612 的回复:
开一个线程,让他自己慢慢生成去。
生成完了,就通知一下就好了。

那效率也还是没有得到改善。。。。。。 生成导出EXCEL太慢了,一万条数据要10分钟左右

#7


引用 6 楼 qq_28419365 的回复:
Quote: 引用 4 楼 hanjun0612 的回复:

开一个线程,让他自己慢慢生成去。
生成完了,就通知一下就好了。

那效率也还是没有得到改善。。。。。。 生成导出EXCEL太慢了,一万条数据要10分钟左右

你1万条数据要放到excel啊。。。慢也是正常。
我不清楚能不能 使用 并行方式Parallel  能不能同时操作一个excel,把数据整进去。。。感觉不太行。 生成导出EXCEL太慢了,一万条数据要10分钟左右

#8


你试试看吧。我也不清楚 Parallel行不行。

#9


引用 5 楼 tangyanzhi1111 的回复:
Quote: 引用 3 楼 diaodiaop 的回复:

Quote: 引用 1 楼 tangyanzhi1111 的回复:

生成导出EXCEL太慢了,一万条数据要10分钟左右

 
 这个很正常,微软提供的东西就是那么的慢。因为不开源,所以你还不能优化。

 如果你要快点,可以从COM+ 底层API入手,直接调用,或许能增加速率。不过COM+ 貌似已经淘汰许久。


说你二笔不知道有没有人点赞




你这种人多厉害.. 代码都不看 就知道人家要问什么.. 还com+ 呵呵. 是不是觉得自己阅代码无数?

#10


https://bbs.csdn.net/topics/390830774

datareader 不知道.. datatable反正是很快的  看下帖子  看看哪里不同

#11


引用 10 楼 diaodiaop 的回复:
https://bbs.csdn.net/topics/390830774

datareader 不知道.. datatable反正是很快的  看下帖子  看看哪里不同



------------------

【datatable很快,npoi 封装】,这逼 这垃圾玩意还发链接,拿出来丢人?


看你这逼的发的资源别人第一条评论: 这种垃圾,还好意思13分...


回去种田吧,蠢逼,笑死你爹。

#12


如果是单纯的想快速导出,而且,数据中没有特殊符号(主要是TAB和回车),可以试试:用string字符串保存导出的内容,两个单元格之间用TAB分隔,两行之间用回车分隔,全部导出完成后,新建一个空EXCEL,再将结果粘贴进去。

#13


可以试试第三方插件NOPI 效率还可以