zoukankan      html  css  js  c++  java
  • 通用化NPOI导出xls

    前言:在导出到xls时有一些通用的元素,比如标题,列标题,内容区域,求和行,但每个xls多少有点不同,为了处理这个问题,可以使用delegate实现,这样可以把差异部分单独处理。


    //为了处理计算和之类的补公式
    public delegate void WriteXlsEndDelegate(DataTable dataTable, HSSFSheet sheet);  //代理函数方式
    public WriteXlsEndDelegate writeXlsEndDelegate=null; 
    /*
     * 根据模板导出xls
     * 数据表,文件名,模板文件名,填充开始行,原始模板里的数据表行数(不包括表头、求和行,一般要留一条示例数据)
     */
    public void ExportXlsByTemplate(DataTable dataTable, string filename, string templatefile, int startDataRegionRow,int orgRowCount=1)
    {
        HttpContext context = HttpContext.Current;
        //Excel模板
        string templetFileName = context.Server.MapPath(templatefile);
        HSSFWorkbook wk = null;
        if (templetFileName != null)
        { using (FileStream fs = File.Open(templetFileName, FileMode.Open,
                FileAccess.Read, FileShare.ReadWrite))
            {
                //把xls文件读入workbook变量里,之后就可以关闭了
                wk = new HSSFWorkbook(fs);
                fs.Close();
            }
            
        }
        else
        {
            return;
        }
        if (dataTable.Rows.Count>1)
        {
            HSSFSheet sheet1 = (HSSFSheet)wk.GetSheetAt(0);
            var rowSource = sheet1.GetRow(startDataRegionRow); 
            var rowStyle = rowSource.RowStyle;//获取当前行样式
            sheet1.ShiftRows(startDataRegionRow + orgRowCount, startDataRegionRow + orgRowCount, dataTable.Rows.Count - orgRowCount, true, false);//从下一行开始移动
    
    
            for (int i = startDataRegionRow + orgRowCount; i < startDataRegionRow + orgRowCount + (dataTable.Rows.Count - orgRowCount); i++)
            {
                var rowInsert = sheet1.CreateRow(i);
                if (rowStyle != null)
                    rowInsert.RowStyle = rowStyle;
                rowInsert.Height = rowSource.Height;
    
                for (int col = 0; col < rowSource.LastCellNum; col++)
                {
                    var cellsource = rowSource.GetCell(col);
                    var cellInsert = rowInsert.CreateCell(col,cellsource.CellType);
                    var cellStyle = cellsource.CellStyle;
                    //设置单元格样式    
                    if (cellStyle != null)
                        cellInsert.CellStyle = cellsource.CellStyle;
                    cellInsert.SetCellValue("");
                }
    
            }
            string nextFirstTxt = string.Empty;
            for (int i = startDataRegionRow; i < startDataRegionRow + dataTable.Rows.Count; i++)
            {
                
                IRow row = sheet1.GetRow(i);
                for (int j = 0; j < dataTable.Columns.Count; j++)
                {
                    var drValue = dataTable.Rows[i - startDataRegionRow][j].ToString();
                        switch (dataTable.Columns[j].DataType.ToString())
                        {
                            case "System.String"://字符串类型
                                row.GetCell(j).SetCellValue(drValue);
                                break;
                            case "System.DateTime"://日期类型
                                DateTime dateV;
                                DateTime.TryParse(drValue, out dateV);
                                row.GetCell(j).SetCellValue(dateV);
                                break;
                            case "System.Boolean"://布尔型
                                bool boolV = false;
                                bool.TryParse(drValue, out boolV);
                                row.GetCell(j).SetCellValue(boolV);
                                break;
                            case "System.Int16"://整型
                            case "System.Int32"://整型
                            case "System.Int64"://整型
                            case "System.Int"://整型
                                int invV = 0;
                                int.TryParse(drValue, out invV);
                                row.GetCell(j).SetCellValue(invV);
                                break;
    
                            case "System.Byte":
                                int intV = 0;
                                int.TryParse(drValue, out intV);
                                row.GetCell(j).SetCellValue(intV);
                                break;
                            case "System.Decimal"://浮点型                           
                            case "System.Double":
                                double doubV = 0;
                                double.TryParse(drValue, out doubV);
                                row.GetCell(j).SetCellValue(doubV);
                                break;default:
                                row.GetCell(j).SetCellValue("");
                                break;
                        }
                    
                }
            }
            sheet1.ForceFormulaRecalculation = true; 
            if(writeXlsEndDelegate!=null)//结束时是否需要进行其它处理
                writeXlsEndDelegate(dataTable,sheet1);
        }
        
        context.Response.ContentType = "application/vnd.ms-excel";
        // 添加头信息,指定文件名格式   
        context.Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);
        context.Response.AddHeader("Content-Transfer-Encoding", "binary");
        context.Response.ContentType = "application/octet-stream";
        context.Response.ContentEncoding = System.Text.Encoding.UTF8;
        MemoryStream file = new MemoryStream();
        wk.Write(file);
        context.Response.BinaryWrite(file.GetBuffer());
    }

    通常导出xls后会进行一些后续操作,比如设置公式求和,下面例子是对第L到U列设置求和公式编写方法

    ClassTest npoi=new ClassTest();
    //
    设置公式 npoi.writeXlsEndDelegate = (dataTable1, sheet) => { int rowIndex = dataTable1.Rows.Count + 1; ///做后补操作 };
    npoi.ExportXlsByTemplate(dataTable, filename, @"/Template/xls/test.xls", 1);

     模板示例

  • 相关阅读:
    redis 安装,及基本命令
    Scrapy爬取大众养生网
    笔记——抓包工具抓取手机app内容
    爬取起点小说网(三)遇到的问题和代码解析
    爬取起点小说网(二)设计代码
    爬取起点小说网(一)设计思想
    python爬取豆瓣登陆验证码
    python爬去笔趣阁完整一本小说
    把爬取到的链接放到数据库
    python爬取网络图片
  • 原文地址:https://www.cnblogs.com/zhaogaojian/p/9873881.html
Copyright © 2011-2022 走看看