c# npoi分批往excel追加數據


直接貼代碼:

using DongYang.Core.Model.Domain;
using DongYang.Core.Utils;
using NLog;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Threading;

namespace DongYang.Core.Service
{
    public class DYTrackANODetail700013TodayNewService
    {
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();//日志組件

        /// <summary>
        /// 導出excel
        /// </summary>
        /// <param name="anomateexcels"></param>
        /// <param name="currentTime"></param>
        public void ExportToExcel(List<Anomateexcel> anomateexcels, DateTime currentTime)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();

            FileStream file = null;
            string strBeginTime = string.Empty;//查詢開始時間
            string strEndTime = string.Empty;//查詢結束時間

            try
            {
                //模板文件
                string templateFileName = AppDomain.CurrentDomain.BaseDirectory + "\\template.xlsx";
                //導出文件
                string reportFileName = FileHelper.GetExportFilePath(currentTime) + $"\\{currentTime.ToString("yyyyMMdd_HHmmss")}.xlsx";
                //獲取查詢日期
                this.GetTime(currentTime, out strBeginTime, out strEndTime);
                //查詢數據總數
                int count = this.GetDataTableCount(strBeginTime, strEndTime);
                if (count == 0) return;
                //先拷貝空文件
                File.Copy(templateFileName, reportFileName);
                //分頁查詢數據,在循環里面,打開拷貝的文件並追加數據,最后關閉文件句柄
                var pages = Math.Ceiling(Convert.ToDouble(count) / ConfigHelper.PageSize);
                for (int pageIndex = 1; pageIndex <= pages; pageIndex++)
                {
                    var startRow = (pageIndex - 1) * ConfigHelper.PageSize + 1;
                    var endRow = pageIndex * ConfigHelper.PageSize;
                    var dt = this.GetDataTable(strBeginTime, strEndTime, startRow, endRow);

                    file = new FileStream(reportFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    XSSFWorkbook xssfworkbook = new XSSFWorkbook(file);//將文件讀到內存,在內存中操作excel
                    file.Close();
                    XSSFSheet xssfsheet = xssfworkbook.GetSheet(ConfigHelper.WorkSheetName) as XSSFSheet;

                    var beginRow = 3 + startRow - 1;//這里的beginRow這么處理,是因為我的Excel標題是在第三行
                    for (var i = 0; i < dt.Rows.Count; i++)
                    {
                        var excelRow = xssfsheet.CreateRow(beginRow++);
                        foreach (var anomateexcel in anomateexcels)
                        {
                            var excelCell = excelRow.CreateCell(anomateexcel.Excellist.ToInt());
                            excelCell.SetCellType(NPOI.SS.UserModel.CellType.String);
                            var value = dt.Rows[i][anomateexcel.Anofield].ToString();
                            excelCell.SetCellValue(value);
                        }
                    }

                    xssfsheet.ForceFormulaRecalculation = true;
                    //將內存數據寫到文件
                    using (FileStream fs = File.OpenWrite(reportFileName))
                    {
                        xssfworkbook.Write(fs);
                        xssfworkbook.Close();
                    }

                    Thread.Sleep(100);
                }
            }
            catch (Exception ex)
            {
                _logger.Error($"導出數據出錯,message:{ex.Message},stackTrace:{ex.StackTrace}");
            }
            finally
            {
                if (file != null) file.Close();
            }

            sw.Stop();
            _logger.Info($"日期:{currentTime},耗時{sw.Elapsed.TotalSeconds}秒");
        }

        #region 獲取開始時間和結束時間

        /// <summary>
        /// 獲取開始時間和結束時間
        /// </summary>
        /// <param name="currentTime"></param>
        /// <param name="strBeginTime"></param>
        /// <param name="strEndTime"></param>
        private void GetTime(DateTime currentTime, out string strBeginTime, out string strEndTime)
        {
            DateTime beginTime;
            DateTime endTime;
            if (currentTime < currentTime.Date.AddHours(7.5))
            {
                beginTime = currentTime.Date.AddDays(-1).AddHours(7.5);//前天7:30
                endTime = currentTime.Date.AddHours(7.5);//當天的7:30
            }
            else
            {
                beginTime = currentTime.Date.AddHours(7.5);
                endTime = currentTime.Date.AddDays(1).AddHours(7.5);
            }

            strBeginTime = beginTime.ToString("yyyy-MM-dd HH:mm");
            strEndTime = endTime.ToString("yyyy-MM-dd HH:mm");
        }

        #endregion

        #region 查詢數據

        /// <summary>
        /// 查詢數據
        /// </summary>
        /// <param name="strBeginTime"></param>
        /// <param name="strEndTime"></param>
        /// <param name="startRow"></param>
        /// <param name="endRow"></param>
        /// <returns></returns>
        private DataTable GetDataTable(string strBeginTime, string strEndTime, int startRow, int endRow)
        {
            var sql = $@"
select * from 
(
    select row_number() over(order by A asc,AB asc,AC asc) as rownumber, * 
    from {ConfigHelper.ExcelExportTableName}
    where E between '{strBeginTime}' and '{strEndTime}'
) as t 
where rownumber between {startRow} and {endRow}
";
            DataTable dt = DapperSqlHelper.QueryDataTable(sql);
            return dt;
        }

        #endregion

        #region 查詢總數

        /// <summary>
        /// 查詢總數
        /// </summary>
        /// <param name="strBeginTime"></param>
        /// <param name="strEndTime"></param>
        /// <returns></returns>
        private int GetDataTableCount(string strBeginTime, string strEndTime)
        {
            var sql = $"select count(1) from {ConfigHelper.ExcelExportTableName} where E between '{strBeginTime}' and '{strEndTime}'";
            DataTable dt = DapperSqlHelper.QueryDataTable(sql);
            var count = Convert.ToInt32(dt.Rows[0][0]);
            return count;
        }

        #endregion
    }
}

一開始是一次性讀取符合條件的數據,因為數據量大,大概七八千條,而且每條記錄400個字段。所以后面優化成了分頁讀取,每次取100條數據,然后再往excel插入數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM