1. 程式人生 > >C#專案自定義彙總匯出Excel功能

C#專案自定義彙總匯出Excel功能

專案中經常需要匯出excel,有時還有彙總需求。但匯出方式都一樣,而彙總方式不同。可以參考以下方式,使用標準的匯出方式,和自定義的彙總方式。

1.首先NuGet引用NPOI version 2.3.0

2.匯出表格原始碼

/// <summary>
        /// 【彙總的外接方法】func第一個引數是上次的行資料,第二個引數是當前行資料,第三個引數是Sheet中的當前行,第四個引數是否是最後一行資料,如果增加了新行,則必須返回true
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public void ExportDataToExcel(DataTable dt,  string FileName, Func<DataRow, DataRow, IRow,Boolean, Boolean> func)
        {
            HSSFWorkbook hssfworkbook = new HSSFWorkbook();
            ICellStyle cellstyle = hssfworkbook.CreateCellStyle();//設定垂直居中格式
            cellstyle.VerticalAlignment = VerticalAlignment.Top;    //垂直居中
            cellstyle.Alignment = HorizontalAlignment.Center;       //居中

            #region 初始化Sheets
            List<ISheet> Sheets = new List<ISheet>();//Sheets集合
            Action addSheet=()=>{
                ISheet sheet = hssfworkbook.CreateSheet();
                IRow row = sheet.CreateRow(0);
                //表頭
                for (int hi = 0; hi < dt.Columns.Count; hi++)
                {
                    ICell cell = row.CreateCell(hi);
                    cell.SetCellValue(dt.Columns[hi].ColumnName);
                    cell.CellStyle = cellstyle;
                }
                Sheets.Add(sheet);
            };
            
            #endregion
            int sheetIndex = 0;
            int rowcount = -1;
            DataRow lastIRow = null;
            try
            {
                addSheet();
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    rowcount++;
                    if (rowcount > 65535 * (sheetIndex+1))
                    {
                        addSheet();
                        ++sheetIndex;
                    }
                    int currentI = rowcount - (sheetIndex * 65535);
                    IRow row1 = Sheets.ToArray()[sheetIndex].CreateRow(currentI + 1);
                    if (lastIRow==null)
                    {
                        lastIRow = dt.Rows[i];
                    }
                    DataRow currentDataRow = dt.Rows[i];
                    Boolean isend =(i==dt.Rows.Count-1);
                    if (!isend)
                    {
                        var isaddCount = func(lastIRow, currentDataRow, row1, isend);
                        if (isaddCount)
                        {
                            rowcount++;
                            currentI = rowcount - (sheetIndex * 65535);
                            row1 = Sheets.ToArray()[sheetIndex].CreateRow(currentI + 1);
                        }
                    }
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        ICell cell = row1.CreateCell(j);
                       
                        string colName = dt.Columns[j].ColumnName;
                        if (colName.IndexOf("監管碼") > 0 || colName.IndexOf("產品碼") > 0 || colName.IndexOf("中獎使用者") > 0)
                        {

                            cell.SetCellValue("'" + dt.Rows[i][j].ToString());
                            cell.CellStyle = cellstyle;
                        }
                        else
                        {
                            cell.SetCellValue(dt.Rows[i][j].ToString());
                            cell.CellStyle = cellstyle;
                        }

                    }
                    if (isend)
                    {
                       func(lastIRow, currentDataRow, row1, isend);                        
                    }
                    
                    lastIRow = currentDataRow;
                }
                //轉為位元組陣列
                MemoryStream stream = new MemoryStream();
                hssfworkbook.Write(stream);

                stream.Position = 0;
                StreamReader rd = new StreamReader(stream, System.Text.Encoding.BigEndianUnicode);
                StringBuilder sb = new StringBuilder();
                sb.Append(rd.ReadToEnd());
                stream.Close();
                hssfworkbook.Close();

                StringWriter sw = new StringWriter();
                sw.Write(sb.ToString());
                HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(FileName + ".xls", System.Text.Encoding.UTF8));
                HttpContext.Current.Response.ContentType = "application/ms-excel";
                System.Web.HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.BigEndianUnicode;
                System.Web.HttpContext.Current.Response.Write(sw);
                sw.Close();
                System.Web.HttpContext.Current.Response.End();
               

            }
            catch (Exception ex)
            {
                hssfworkbook.Close();
                Acexe.Common.Utils.Log("error", String.Format("ExportDataToExcel {0}{1}{2}", ex.Message, System.Environment.NewLine, ex.StackTrace));
            }
        }

3.自定義參考原始碼

Func<DataRow, DataRow, IRow,Boolean, Boolean> func = (a, b, c,d) =>
            {
                ICellStyle cellstyle = c.Sheet.Workbook.CreateCellStyle();//設定垂直居中格式
                cellstyle.VerticalAlignment = VerticalAlignment.Top;    //垂直居中
                cellstyle.Alignment = HorizontalAlignment.Right;       //居中
               
                if(d)
                {
                    if (Decimal.TryParse(b["紅包金額"].ToString(), out recordMoney))
                    {
                        moneyCount += recordMoney;
                    }
                    ICell cell = c.Sheet.CreateRow(c.RowNum+1).CreateCell(0);
                    cell.SetCellValue("UserId:" + a["UserId"].ToString() + " 彙總: " + moneyCount.ToString("0.00"));
                    cell.CellStyle = cellstyle;
                    c.Sheet.AddMergedRegion(new CellRangeAddress(c.RowNum+1, c.RowNum+1, 0, a.Table.Columns.Count - 1));
                    return true;
                }
                else
                {
                    if (!(a["UserId"].ToString().Equals(b["UserId"].ToString())))
                    {
                        ICell cell = c.CreateCell(0);
                        cell.SetCellValue("UserId:" + a["UserId"].ToString() + " 彙總: " + moneyCount.ToString("0.00"));
                        cell.CellStyle = cellstyle;
                        c.Sheet.AddMergedRegion(new CellRangeAddress(c.RowNum, c.RowNum, 0, a.Table.Columns.Count - 1));
                        if (Decimal.TryParse(b["紅包金額"].ToString(), out recordMoney))
                        {
                            moneyCount = recordMoney;
                        }
                        return true;
                    }
                    else
                    {
                        if (Decimal.TryParse(b["紅包金額"].ToString(), out recordMoney))
                        {
                            moneyCount += recordMoney;
                        }
                        return false;
                    }
                }
            };