NPOI导出Excel并下载到客户端

报表数据导出Excel,很常见的需求,然而每次都能忘了,今天再次遇到了,总结一下。


一般来说都需要有个标题

//需要输出的字段
string[] fieldArr = { "Title", "Sequence", "WorkSheetDescription", "Position", "StartTime", "EndTime", "Transactor", "Status", "WorkClass", "Result", "StartDoTime", "EndDoTime" };

//对应的中文描述            System.Collections.Generic.Dictionary<string, string> fieldDic = new System.Collections.Generic.Dictionary<string, string> { { "Title", "工单编号" }, { "Sequence", "顺序" }, { "WorkSheetDescription", "工单描述" }, { "Position", "位置" }, { "StartTime", "计划开始时间" }, { "EndTime", "计划结束时间" }, { "Transactor", "处理人" }, { "Status", "工单状态" }, { "WorkClass", "班次" }, { "Result", "执行结果" }, { "StartDoTime", "实际开始时间" }, { "EndDoTime", "实际结束时间" } };

设置表单表格样式

ICellStyle titleStyle= wb.CreateCellStyle();
            IFont font1 = wb.CreateFont();//字体
            font1.FontName = "楷体";
            font1.Color = HSSFColor.White.Index;//字体颜色
            font1.Boldweight = (short)FontBoldWeight.Normal;//字体加粗
            titleStyle.SetFont(font1);//字体设置具体的字体
            //背景色
            titleStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Blue.Index;
            titleStyle.FillPattern = FillPattern.SolidForeground;
            titleStyle.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Blue.Index;
            titleStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;//文字水平对齐方式
            titleStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//文字垂直对齐方式

设置列宽

int[] columnWidth = { 10, 10, 25, 10, 15, 15, 20, 10, 20, 20, 15, 15 };
            for (int i = 0; i < columnWidth.Length; i++)
            {
                //设置列宽度,256*字符数,因为单位是1/256个字符
                sheet.SetColumnWidth(i, 256 * columnWidth[i]);
            }

把生成的Excel发送到客户端

MemoryStream ms = new MemoryStream();
            wb.Write(ms);
            Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", HttpUtility.UrlEncode("WS" + "_" + DateTime.Now.ToString("yyyy-MM-dd"), System.Text.Encoding.UTF8)));
            Response.BinaryWrite(ms.ToArray());
            Response.Flush();

            Response.End();
            wb = null;
            ms.Close();
            ms.Dispose();

因为我的项目是SharePoint的,所以数据源是SPListItemCollection传入,其他的DataTable或者其他的相应改动一下就行。

代码如下

public void NPOIExcel(SPListItemCollection items)
        {
            HSSFWorkbook wb = new HSSFWorkbook();

            //标题样式样式
            ICellStyle titleStyle= wb.CreateCellStyle();
            IFont font1 = wb.CreateFont();//字体
            font1.FontName = "楷体";
            font1.Color = HSSFColor.White.Index;//字体颜色
            font1.Boldweight = (short)FontBoldWeight.Normal;//字体加粗
            titleStyle.SetFont(font1);//设置字体
            //设置背景色
            titleStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Blue.Index;
            titleStyle.FillPattern = FillPattern.SolidForeground;
            titleStyle.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Blue.Index;
            titleStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;//文字水平对齐方式
            titleStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//文字垂直对齐方式

            //创建一个表单
            ISheet sheet = wb.CreateSheet("Sheet0");
            //设置列宽
            int[] columnWidth = { 10, 10, 25, 10, 15, 15, 20, 10, 20, 20, 15, 15 };
            for (int i = 0; i < columnWidth.Length; i++)
            {
                //设置列宽度,256*字符数,因为单位是1/256个字符
                sheet.SetColumnWidth(i, 256 * columnWidth[i]);
            }

            IRow row;
            ICell cell;

            string[] fieldArr = { "Title", "Sequence", "WorkSheetDescription", "Position", "StartTime", "EndTime", "Transactor", "Status", "WorkClass", "Result", "StartDoTime", "EndDoTime" };
            System.Collections.Generic.Dictionary<string, string> fieldDic = new System.Collections.Generic.Dictionary<string, string> { { "Title", "工单编号" }, { "Sequence", "顺序" }, { "WorkSheetDescription", "工单描述" }, { "Position", "位置" }, { "StartTime", "计划开始时间" }, { "EndTime", "计划结束时间" }, { "Transactor", "处理人" }, { "Status", "工单状态" }, { "WorkClass", "班次" }, { "Result", "执行结果" }, { "StartDoTime", "实际开始时间" }, { "EndDoTime", "实际结束时间" } };

            //写入标题行
            row = sheet.CreateRow(0);
            for (int i = 0; i < fieldArr.Length; i++)
            {
                cell = row.CreateCell(i);//创建第j列
                cell.CellStyle = titleStyle;
                SetCellValue(cell, fieldDic[fieldArr[i]]);
            }

            //写入数据,从第2行开始
            for (int i = 1; i <= items.Count; i++)
            {
                row = sheet.CreateRow(i);//创建第i行
                for (int j = 0; j < fieldArr.Length; j++)
                {
                    cell = row.CreateCell(j);

                    //根据数据类型设置不同类型的cell
                    var field = fieldArr[j];
                    object obj = null;
                    //如果报错,跳过该字段
                    try
                    {
                        obj = items[i - 1][field];
                    }
                    catch
                    {
                        continue;
                    }
                    if (obj != null)
                    {
                        SetCellValue(cell, obj);
                    }
                }
            }

            //发送到客户端
            MemoryStream ms = new MemoryStream();
            wb.Write(ms);
            Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", HttpUtility.UrlEncode("WS" + "_" + DateTime.Now.ToString("yyyy-MM-dd"), System.Text.Encoding.UTF8)));
            Response.BinaryWrite(ms.ToArray());
            Response.Flush();

            Response.End();
            wb = null;
            ms.Close();
            ms.Dispose();
        }

        /// 
        /// 根据数据类型设置不同类型的cell
        /// 
        /// 
        /// 
        public static void SetCellValue(ICell cell, object obj)
        {
            try
            {
                if (obj.GetType() == typeof(int))
                {
                    cell.SetCellValue((int)obj);
                }
                else if (obj.GetType() == typeof(double))
                {
                    cell.SetCellValue((double)obj);
                }
                else if (obj.GetType() == typeof(IRichTextString))
                {
                    cell.SetCellValue((IRichTextString)obj);
                }
                else if (obj.GetType() == typeof(string))
                {
                    cell.SetCellValue(obj.ToString());
                }
                else if (obj.GetType() == typeof(DateTime))
                {
                    cell.SetCellValue(Convert.ToDateTime(obj).ToString("yyyy/MM/dd"));
                }
                else if (obj.GetType() == typeof(bool))
                {
                    cell.SetCellValue((bool)obj);
                }
                else
                {
                    cell.SetCellValue(obj.ToString());
                }
            }
            catch (Exception ex)
            {
            }
        }

需要注意的是,如果在页面直接用按钮事件导出Excel的话,只能导出一次,然后因为页面被End了,导致页面没有刷新,如果需要多次导出的话,可以把下载的操作放到一个页面去执行,然后前端js创建iframe的方式去做。

好记忆不如烂笔头,记录一下,免得以后又要到处找。

你可能感兴趣的:(.net)