NPOI导出Excel(多表头,多工作薄)

当前版本实现主要功能:实现一维表头,二维表头导出功能,时间比较紧,版本比较粗糙,如果有改进的版本,希望能给我发份

public class NPOIHelper
    {
        #region 实例化
        /// <summary>
        /// 文件名称
        /// </summary>
        public string _fileName { get; private set; }
        /// <summary>
        /// 工作薄名称,多工作薄以";"隔开,例如:测试1;测试2;测试3
        /// </summary>
        public string _sheetName { get; private set; }
        /// <summary>
        /// 每个工作薄只能有一个标题,多工作薄时,标题以";"隔开
        /// </summary>
        public string _title { get; private set; }
        /// <summary>
        /// 表头格式
        /// 相邻父列头之间用'#'分隔,父列头与子列头用空格(' ')分隔,相邻子列头用逗号分隔(',')
        /// 两行:序号#分公司#组别#本日成功签约单数 预警,续约,流失,合计#累计成功签约单数 预警,续约,流失,合计#任务数#完成比例#排名 
        /// 三行:等级#级别#上期结存 件数,重量,比例#本期调入 收购调入 件数,重量,比例#本期发出 车间投料 件数,重量,比例#本期发出 产品外销百分比 件数,重量,比例#平均值 
        /// 三行时请注意:列头要重复  
        /// </summary>
        public string _header { get; private set; }
        /// <summary>
        /// 文件路径 如果WEB导出时,路径可为空;
        /// </summary>
        public string _filePath { get; private set; }
        /// <summary>
        /// 导出方式 1:WEB导出 2:路径导出
        /// </summary>
        public int _exportMode { get; private set; } 
        /// <summary>
        /// 数据源
        /// </summary>
        public DataSet _dsSource { get; private set; }
        /// <summary>
        /// 数据库采用字段
        /// </summary>
        public string _filed { get; private set; }
        /// <summary>
        /// HSSFWorkbook 对象
        /// </summary>
        private HSSFWorkbook _workbook;
        /// <summary>
        /// 实例化
        /// </summary>
        /// <param name="fileName">文件名称</param>
        /// <param name="sheetName">工作薄名称,多工作薄以";"隔开,例如:测试1;测试2;测试3</param>
        /// <param name="header">
        /// 相邻父列头之间用'#'分隔,父列头与子列头用空格(' ')分隔,相邻子列头用逗号分隔(',')
        /// 两行:序号#分公司#组别#本日成功签约单数 预警,续约,流失,合计#累计成功签约单数 预警,续约,流失,合计#任务数#完成比例#排名 
        /// 三行:等级#级别#上期结存 件数,重量,比例#本期调入 收购调入 件数,重量,比例#本期发出 车间投料 件数,重量,比例#本期发出 产品外销百分比 件数,重量,比例#平均值 
        /// 三行时请注意:列头要重复
        /// </param>
        /// <param name="ds">数据来源</param>
        /// <param name="filed">数据字段</param>
        public NPOIHelper(string fileName, string sheetName, string header,DataSet ds,string filed)
        {
            // 判断文件后缀名是否存在
            if (string.IsNullOrEmpty(fileName))
                fileName = "新建Excel.xls";
            else if (fileName.IndexOf(".xls") == -1 && fileName.IndexOf(".xlsx") == -1)
                fileName += ".xls";

            this._workbook = new HSSFWorkbook();
            this._fileName = fileName;
            this._header = header;
            if (string.IsNullOrEmpty(sheetName))
                throw new ArgumentNullException("sheetName", "工作薄名称不能为空");
            this._sheetName = sheetName;
            this._exportMode = 1;
            this._dsSource = ds;
            this._filed = filed;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName">文件名称</param>
        /// <param name="sheetName">工作薄名称,多工作薄以";"隔开,例如:测试1;测试2;测试3</param>
        /// <param name="header">
        /// 相邻父列头之间用'#'分隔,父列头与子列头用空格(' ')分隔,相邻子列头用逗号分隔(',')
        /// 两行:序号#分公司#组别#本日成功签约单数 预警,续约,流失,合计#累计成功签约单数 预警,续约,流失,合计#任务数#完成比例#排名 
        /// 三行:等级#级别#上期结存 件数,重量,比例#本期调入 收购调入 件数,重量,比例#本期发出 车间投料 件数,重量,比例#本期发出 产品外销百分比 件数,重量,比例#平均值 
        /// 三行时请注意:列头要重复
        /// </param>
        /// <param name="title">每个工作薄只能有一个标题,多工作薄时,标题以";"隔开</param>
        /// <param name="filePath">文件路径</param>
        /// <param name="exportMode">导出方式 1:WEB导出 2:路径导出</param>
        /// <param name="ds">数据来源</param>
        /// <param name="filed">数据字段</param>
        public NPOIHelper(string fileName, string sheetName, string header, string title, DataSet ds, string filed,string filePath = null, int exportMode = 1)
        {
            // 判断文件后缀名是否存在
            if (string.IsNullOrEmpty(fileName))
                fileName = "新建Excel.xls";
            else if (fileName.IndexOf(".xls") == -1 && fileName.IndexOf(".xlsx") == -1)
                fileName += ".xls";

            this._workbook = new HSSFWorkbook();
            this._fileName = fileName;

            if (string.IsNullOrEmpty(sheetName))
                throw new ArgumentNullException("sheetName", "工作薄名称不能为空");
            this._sheetName = sheetName;
            this._header = header;
            this._title = title;

            if (2 == exportMode && string.IsNullOrEmpty(filePath))
                filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

            this._filePath = filePath;
            this._exportMode = exportMode;
            this._dsSource = ds;
            this._filed = filed;
        }
        #endregion

        #region 功能实现
        /// <summary>
        /// 实现导出功能
        /// </summary>
        public void Export()
        {
            #region 变量声明
            string[] tableTitle = this._header.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            // 表头数组
            string[] newHeaders = null;
            // 数据字段
            string[] files = this._filed.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            // 数据字段
            string[] file = null;
            // 临时数组
            string[] temp = null;
            // 临时表头
            string tempHeader = string.Empty;
            // 工作薄名称
            string[] sheetNames = this._sheetName.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
            // 表头名称
            string[] titles = this._title == null ? null : this._title.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
            // 获取行数
            int rows = GetRowCount(this._header);
            // 列数计数器
            int cols = 0;
            // 列头跨行数
            int rowSpans = 0;
            // 列头跨列数
            int colSpans = GetColCount(this._header);
            // HSSFSheet 对象
            HSSFSheet sheet = null;
            // IRow 对象
            IRow row = null;
            // 表头行添加
            int trow = (string.IsNullOrEmpty(this._title) ? 0 : 1);
            DataTable dt;
            #endregion

            #region 单元格样式
            ICellStyle style = _workbook.CreateCellStyle();
            style.Alignment = HorizontalAlignment.CENTER; //居中
            style.VerticalAlignment = VerticalAlignment.CENTER;//垂直居中 
            style.WrapText = true;//自动换行
            // 边框
            style.BorderBottom = BorderStyle.THIN;
            style.BorderLeft = BorderStyle.THIN;
            style.BorderRight = BorderStyle.THIN;
            style.BorderTop = BorderStyle.THIN;
            // 字体
            IFont font = _workbook.CreateFont();
            font.FontHeightInPoints = 10;
            font.FontName = "宋体";
            style.SetFont(font);

            ICellStyle titleType = _workbook.CreateCellStyle();
            titleType.Alignment = HorizontalAlignment.CENTER; //居中
            titleType.VerticalAlignment = VerticalAlignment.CENTER;//垂直居中 
            titleType.WrapText = true;//自动换行
            // 边框
            titleType.BorderBottom = BorderStyle.THIN;
            titleType.BorderLeft = BorderStyle.THIN;
            titleType.BorderRight = BorderStyle.THIN;
            titleType.BorderTop = BorderStyle.THIN;

            IFont font2 = _workbook.CreateFont();
            font2.FontHeightInPoints = 14;
            font2.FontName = "宋体";
            font2.Boldweight = (short)FontBoldWeight.BOLD;
            titleType.SetFont(font2);
            #endregion

            // 表格绘制
            for (int k = 0; k < sheetNames.Length; k++)
            {
                #region 表头绘制
                newHeaders = tableTitle[k].Split(new char[] { '#' }, StringSplitOptions.RemoveEmptyEntries);
                sheet = (HSSFSheet)_workbook.CreateSheet(sheetNames[k]);
                for (int m = 0; m < rows + trow; m++) // 创建行
                {
                    if (m == 0 && trow > 0)
                    {
                        row = sheet.CreateRow(0);
                        CellRangeAddress region = new CellRangeAddress(0, 0, 0, colSpans - 1);
                        sheet.AddMergedRegion(region);
                        row.CreateCell(0).SetCellValue(titles[k]);
                        row.GetCell(0).CellStyle = titleType;
                        row.Height = 20 * 20;
                        continue;
                    }
                    cols = 0;
                    for (int i = 0; i < newHeaders.Length; i++) // 创建列
                    {

                        tempHeader = newHeaders[i];
                        // 获取列头跨行数
                        rowSpans = GetRowSpan(tempHeader, rows);
                        // 获取列头跨列数
                        colSpans = GetColSpan(tempHeader);

                        // 如果表头还可以划分
                        temp = tempHeader.Split(new char[] { ' ' });
                        if (temp.Length == rows)
                            tempHeader = temp[m - trow];
                        else
                            tempHeader = temp[0];



                        if (1 == rowSpans)
                        {
                            // 获取行
                            row = sheet.GetRow(m);
                            if (row == null)
                                row = sheet.CreateRow(m);

                            // 未跨列
                            if (1 == colSpans)
                            {
                                row.CreateCell(cols).SetCellValue(tempHeader);
                                row.GetCell(cols).CellStyle = style;
                            }
                            else // 跨列
                            {
                                temp = tempHeader.Split(new char[] { ',' });
                                if (temp.Length > 1)
                                {
                                    for (int j = 0; j < temp.Length; j++)
                                    {
                                        row.CreateCell(j + cols).SetCellValue(temp[j]);
                                        row.GetCell(j + cols).CellStyle = style;
                                    }
                                }
                                else
                                {
                                    // 创建范围
                                    //CellRangeAddress四个参数为:起始行,结束行,起始列,结束列
                                    CellRangeAddress region = new CellRangeAddress(m, m, cols, cols + colSpans - 1);
                                    sheet.AddMergedRegion(region);
                                    row.CreateCell(cols).SetCellValue(tempHeader);
                                    row.GetCell(cols).CellStyle = style;
                                }
                                cols += colSpans - 1;
                            }
                        }
                        else if (rowSpans > 1 && m < 2)
                        {
                            // 获取行
                            row = sheet.GetRow(m);
                            if (row == null)
                                row = sheet.CreateRow(m);

                            // 未跨列
                            if (1 == colSpans)
                            {
                                // 创建范围
                                //CellRangeAddress四个参数为:起始行,结束行,起始列,结束列
                                CellRangeAddress region = new CellRangeAddress(m, rowSpans - 1 + trow, cols, cols);
                                sheet.AddMergedRegion(region);
                                row.CreateCell(cols).SetCellValue(tempHeader);
                                row.GetCell(cols).CellStyle = style;
                            }
                            else
                            {
                                // 创建范围
                                //CellRangeAddress四个参数为:起始行,结束行,起始列,结束列
                                CellRangeAddress region = new CellRangeAddress(m, rowSpans - 1 + trow, cols, cols + colSpans - 1);
                                sheet.AddMergedRegion(region);
                                row.CreateCell(cols).SetCellValue(tempHeader);
                                row.GetCell(cols).CellStyle = style;
                                cols += colSpans - 1;
                            }
                        }
                        // 列计数器
                        cols += 1;
                    }
                }
                #endregion

                #region 数据源
                int rowIndex = rows + trow;
                foreach (DataRow dr in this._dsSource.Tables[k].Rows)
                {

                    var dataRow = sheet.CreateRow(rowIndex);
                    foreach (DataColumn column in this._dsSource.Tables[k].Columns)
                    {
                        var newCell = dataRow.CreateCell(column.Ordinal);

                        string drValue = dr[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;
                        }

                    }
                    rowIndex++;
                }
                #endregion
            }
             
            #region 数据导出
            // WEB导出
            if (1 == this._exportMode)
            {
                System.Web.HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
                //设置下载的Excel文件名
                System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", this._fileName));

                using (MemoryStream ms = new MemoryStream())
                {
                    //将工作簿的内容放到内存流中
                    _workbook.Write(ms);
                    //将内存流转换成字节数组发送到客户端
                    System.Web.HttpContext.Current.Response.BinaryWrite(ms.GetBuffer());
                    System.Web.HttpContext.Current.Response.End();
                    _workbook = null;
                }
            }
            else if (2 == this._exportMode)
            {
                using (FileStream fs = File.Open(this._filePath, FileMode.Append))
                {
                    _workbook.Write(fs);
                    _workbook = null;
                }
            }
            #endregion
        }
        #endregion

        #region 辅助方法
        /// <summary>
        /// 获取表头行数
        /// </summary>
        /// <param name="newHeaders">表头文字</param>
        /// <returns></returns>
        private int GetRowCount(string newHeaders)
        {
            // 用@分割
            string[] ColumnNames = newHeaders.Split(new char[] { '@' });
            int Count = 0;
            if (ColumnNames.Length <= 1)
                ColumnNames = newHeaders.Split(new char[] { '#' });
            foreach (string name in ColumnNames)
            {
                int TempCount = name.Split(new char[] { ' ' }).Length;
                if (TempCount > Count)
                    Count = TempCount;
            }
            return Count;
        }

        /// <summary>
        /// 获取表头列数
        /// </summary>
        /// <param name="newHeaders">表头文字</param>
        /// <returns></returns>
        private int GetColCount(string newHeaders)
        {
            // 用@分割
            string[] ColumnNames = newHeaders.Split(new char[] { '@' });
            int Count = 0;
            if (ColumnNames.Length <= 1)
                ColumnNames = newHeaders.Split(new char[] { '#' });
            Count = ColumnNames.Length;
            foreach (string name in ColumnNames)
            {
                int TempCount = name.Split(new char[] { ',' }).Length;
                if (TempCount > 1)
                    Count += TempCount - 1;
            }
            return Count;
        }

        /// <summary>
        /// 列头跨列数
        /// </summary>
        /// <remarks>
        /// author:zhujt
        /// create date:2015-9-9 09:17:34
        /// </remarks>
        /// <param name="newHeaders">表头文字</param>
        /// <returns></returns>
        private int GetColSpan(string newHeaders)
        {
            return newHeaders.Split(',').Count();
        }

        /// <summary>
        /// 列头跨行数
        /// </summary> 
        /// <remarks>
        /// author:zhujt
        /// create date:2015-9-9 09:17:14
        /// </remarks>
        /// <param name="newHeaders">列头文本</param>
        /// <param name="rows">表头总行数</param>
        /// <returns></returns>
        private int GetRowSpan(string newHeaders, int rows)
        {
            int Count = newHeaders.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).Length;
            // 如果总行数与当前表头所拥有行数相等
            if (rows == Count)
                Count = 1;
            else if (Count < rows)
                Count = 1 + (rows - Count);
            else
                throw new Exception("表头格式不正确!");
            return Count;
        }
        #endregion
    }

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值