【C#】Excel导出合并行和列并动态加载行与列

原文链接:http://blog.csdn.net/ww130929/article/details/51816751

简单的Excel导出比较好做,只要设置表头,循环在表格中赋值添加数据即可,但是如果表头是不固定的,并且个数是不确定的,这就需要根据查询出数据的特点来添加导出了。
这里写图片描述
如上图所示,商品的个数是不确定的,时间的月份个数也是不确定的,所以简单的通过模板是不可以的。并且数据库中查询出的信息是每个商品不同时间的信息,所以查询出的数据相同时间的可能有多条,一个商品在不同的时间分布,所以也可以是多条。
这里写图片描述

public int DataTableToExcelByMProduct(DataTable dt_model, string sheetName)  
{  
    workbook = new HSSFWorkbook();  
    ISheet sheet = workbook.CreateSheet(sheetName);  
    IRow row = null;  
    ICell cell = null;  
    //样式  
    ICellStyle style = workbook.CreateCellStyle();  
    style.Alignment = HorizontalAlignment.CENTER;//设置单元格的样式:水平对齐居中  
    style.VerticalAlignment = VerticalAlignment.CENTER;//设置单元格样式:垂直对齐居中  
    IFont font = workbook.CreateFont();//新建一个字体样式对象  
    font.Boldweight = short.MaxValue;  
    style.SetFont(font);  
    DateTime nowTime = DateTime.Now;  

    //商品编码数量  
    var dtgroup=(from p in dt_model.AsEnumerable()  
    group p by new {  
        RealName=p.Field<string>("RealName"),  
        Name=p.Field<string>("Name")                
    }into g  
    select new {  
        RealName=g.Key.RealName,  
        Name=g.Key.Name,  
        counts=g.Count()  
    }).ToList();  
    //数据表头,时间  

     row = sheet.CreateRow(0);  
    cell = row.CreateCell(0);  
    cell.SetCellValue("时间");  
    cell.CellStyle = style;  
    //CellRangeAddress四个参数:起始行、结束行、起始列、结束列  
    sheet.AddMergedRegion(new CellRangeAddress(0, 2, 0, 0));  

    //进出口岸  1,1,2,口岸数*2  
    cell = row.CreateCell(1);  
    cell.SetCellValue(“进出口商品编码”);  
    cell.CellStyle = style;  
    //CellRangeAddress四个参数:起始行、结束行、起始列、结束列  
    sheet.AddMergedRegion(new CellRangeAddress(0, 0, 1, 2*dtgroup.Count));  

    //商品拼接  
     row = sheet.CreateRow(1);  
    row = sheet.CreateRow(2);  
    for( int c=0;c<dtgroup.Count;c++)  
    {  
        //创建进出口岸单元格,开始  
         cell = row.CreateCell(2*c+1);  
         cell.SetCellValue(dtgroup[c].RealName);  
         cell.CellStyle = style;  
    //CellRangeAddress四个参数:起始行、结束行、起始列、结束列  
        sheet.AddMergedRegion(new CellRangeAddress(1, 1, 2*c+1, 2*c+2));  

        //创建进口单元格   
        //创建一列  
        cell=row.CreateCell(2*c+1);  
        cell.SetCellValue("进口");  
        cell=row.CreateCell(2*c+2);     
        cell.SetCellValue("出口");      
    }  

    var AllYearCount=(from p in dt_model.AsEnumerable()  
                      group p by new {Year_Month=p.Field<string>("Year_Month")} into m  
                      select new   
                      {  
                          YearMonth =m.Key.Year_Month,  
                          AllYearCount=m.Count()  
                      }).ToList();  
    //年份  
    for (int i=0;i < AllYearCount.Count;i++)  
    {  
        row=sheet.CreateRow(i+3);  
        cell=row.CreateCell(0);  
        string YearMonth=AllYearCount[i].YearMonth;  

        int month =SafeConvert.ToInt16(YearMonth.Substring(4,2));  
        cell.SetCellValue("1-"+month+"月");  


    //贸易额对碰情况  
        for (int j=0;j<dtgroup.Count;j++)  
        {  
            var items=dt_model.AsEnumerable().Where(a=>a.Field<string>("Year_Month")==AllYearCount[i].YearMonth && a.Field<string>("Name")==dtgroup[j].Name).ToList();  
            if(items.Count>0)  
            {  
                cell=row.CreateCell(2*j+1);  
                cell.SetCellValue(items[0].Field<string>("Export_Desn"));  
                cell=row.CreateCell(2*j+2);  
                cell.SetCellValue(items[0].Field<string>("Import_Desn"));  
            }  
            else  
            {  
                cell=row.CreateCell(2*j+1);  
                cell.SetCellValue("");  
                cell=row.CreateCell(2*j+2);  
                cell.SetCellValue("");  
            }  

        }  
    }  
    using(FileStream fsm=File.Open(fileName,FileMode.OpenOrCreate,FileAccess.ReadWrite))  
    {  
        workbook.Write(fsm);  
        fsm.Close();  
    }  
    return 1;  

}  

其实代码的核心部分就是创建行与列并且为表格赋值,如果已经创建了行就不用创建了,就像这个例子中的时间单元格已经创建了一次行,这样“进出口商品编码”就不用再次创建行了。但是创建了行必须要创建列,列是在行的基础上创建的,所以即使上一行已经创建了列,下一行还是需要重新创建的。

小结:
这个方法传入的是datatable和表格名称,如果我们返回的数据不是直接输出的需要做一些处理,我们可以采用给datatable增加字段的方法,将我们想要的结果存储到新加的字段中。
导出的思想是一样的,都是要循环行和列,在表格中赋值,不同的是从哪里开始赋,把不同的地方解决,导出也一样easy!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值