NPOI导出EXCEL模板文件联动的效果
Posted zjy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NPOI导出EXCEL模板文件联动的效果相关的知识,希望对你有一定的参考价值。
第一步:先定义下拉的数据源,正常情况是在建立第二个sheet,第一个sheet作为主界面显示,而下拉数据源放在后面
定义数据源根据父子关系建立,如
此处cell的操作需要根据父子表的关系循环设置
DataTable dtF = ds.Tables[0]; //父 DataTable dtC = ds.Tables[1]; //子 ISheet sheetSource = hssfworkbook.CreateSheet("Dictionary"); int MaxRow = dtBusiness.Rows.Count;//默认最大行数 if (dtF != null && dtF.Rows.Count > 0) { for (int i = 0; i < dtF.Rows.Count; i++) { var row = sheet2.CreateRow(i);//添加行 row.CreateCell(0).SetCellValue(dtF.Rows[i]["Name"].ToString()); if (i == 0) { for (int j = 1; j <= dtF.Rows.Count; j++) { row.CreateCell(j).SetCellValue(dtF.Rows[j - 1]["Name"].ToString()); } } } for (int i = 1; i <= dtF.Rows.Count; i++) { DataRow[] dr = dtC.Select("PCode=‘" + dtF.Rows[i - 1]["Code"].ToString() + "‘"); if (dr.Length > 0) { if (dr.Length > MaxRow) { int needLen = dr.Length - MaxRow; } for (int j = 1; j <= dr.Length; j++) { if (j < MaxRow) { var r = sheetSource.GetRow(j);//针对已经存在行的情况下 r.CreateCell(i).SetCellValue(dr[j - 1]["Name"].ToString()); } else { var newRow = sheetSource.CreateRow(j);//添加行 newRow.CreateCell(i).SetCellValue(dr[j - 1]["Name"].ToString()); MaxRow++; } } } } }
数字转字母的方法,为了匹配出列名,其实不需要也可以,因为模板都是固定格式的,可以直接写入自己需要的列名,如A,B...
private string GetExcelColumnName(int columnNumber) { int dividend = columnNumber; string columnName = String.Empty; int modulo; while (dividend > 0) { modulo = (dividend - 1) % 26; columnName = Convert.ToChar(65 + modulo).ToString() + columnName; dividend = (int)((dividend - modulo) / 26); } return columnName; }
第二步:设置主菜单下拉选项
IName range = hssfworkbook.CreateName();
range.NameName = "MainRange";
var colName = GetExcelColumnName(1);//数字转成大写英文字母,就是列头
range.RefersToFormula = string.Format("{0}!${3}${2}:${3}${1}", "Dictionary", dtF.Rows.Count.ToString(), 1, colName);//动态设定范围
DVConstraint constraint = DVConstraint.CreateFormulaListConstraint("MainRange");
HSSFDataValidation dataValidate = new HSSFDataValidation(regions, constraint);
sheet.AddValidationData(dataValidate); //sheet 是已经新建好的第一个sheet
第三步: 定义公式名称(EXCEL里的定义名词)
for (int i = 1; i <= dtF.Rows.Count; i++) { IName rangeC = hssfworkbook.CreateName(); rangeC.NameName = dtF.Rows[i - 1]["Name"].ToString(); var colNameC = GetExcelColumnName(i+1); DataRow[] dr = dtC.Select("PCode=‘" + dtF.Rows[i - 1]["Code"].ToString() + "‘"); rangeC.RefersToFormula = string.Format("{0}!${3}$2:${3}${1}", "Dictionary", dr.Length+1, 2, colNameC);//动态设定范围 }
第二步与第三部关键点在于设置校验的范围
第四步:加入验证
for (int i = 1; i <= 2; i++) //2表示控制2列,其实可以根据这个思路随意扩展 { var smallColIndex = i - 1; colName = GetExcelColumnName(1); for (int j = 1; j <= 50; j++) //设置多少行应用这个验证 { CellRangeAddressList regions2 = new CellRangeAddressList(j, j, smallColIndex, smallColIndex); DVConstraint constraint2 = DVConstraint.CreateFormulaListConstraint(string.Format("INDIRECT(${0}${1})", colName, j + 1));//将父值关联起来 HSSFDataValidation dataValidate2 = new HSSFDataValidation(regions2, constraint2); sheet.AddValidationData(dataValidate2); } }
最终效果,选择一级,二级根据一级选项产生联动效果
其实实现这个效果还是先要会EXCEL里这样的操作,这样更容易理解EXCEL里公式
以上是关于NPOI导出EXCEL模板文件联动的效果的主要内容,如果未能解决你的问题,请参考以下文章
动态从数据库获取数据,省市县三级联动,有校验,导出Excel模板