C# net8生成excel,并设置列规则导出文件

安装 依赖库:NPOI

创建XSSFWorkbook和Sheet

设置表头行

添加数据验证:

身份证列用COUNTIF公式确保唯一

地址相关列锁定固定值

学段列设置三级下拉

固定值通过单元格赋值实现

输出

csharp 复制代码
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.SS.Util;
using System.IO;


/// <summary>
/// 下载模板
/// </summary>
/// <returns></returns>
public ActionResult DownloadTemplate(DownloadTemplateDto input) {
    if (input.total< 1) throw new UserFriendlyException("人数不能为0");
    var stream = GenerateExcel(input.total);
    var data= stream.ToArray();
    return new FileContentResult(data, "application/octet-stream");//application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
}

private MemoryStream GenerateExcel(int rowTotal)
{
    rowTotal = rowTotal + 10;//总行数
    // 1. 创建工作簿和工作表
    IWorkbook workbook = new XSSFWorkbook();
    ISheet sheet = workbook.CreateSheet("基础信息");

	// 创建文本格式样式(用于身份证号列)
	ICellStyle textStyle = workbook.CreateCellStyle();
	IDataFormat textFormat = workbook.CreateDataFormat();
	textStyle.DataFormat = textFormat.GetFormat("@"); // "@" 表示文本格式


    // 2. 创建列名行
    // 2. 设置列名(共12列)
    string[] headers = { "姓名", "身份证号", "现住省", "现住市", "现住区", "联系电话",
                  "详细地址", "学校名称", "学校编号", "学段", "年级", "班级" };
    IRow headerRow = sheet.CreateRow(0);
    for (int i = 0; i < headers.Length; i++)
    {
        headerRow.CreateCell(i).SetCellValue(headers[i]);
    }

    // 3. 设置数据验证规则
    IDataValidationHelper validationHelper = sheet.GetDataValidationHelper();

    // 规则1:身份证号列唯一性验证
    CellRangeAddressList idRange = new CellRangeAddressList(1, rowTotal, 1, 1); // B列
    IDataValidationConstraint idConstraint = validationHelper.CreateCustomConstraint("COUNTIF(B:B, B1)=1");
    IDataValidation idValidation = validationHelper.CreateValidation(idConstraint, idRange);
    idValidation.CreateErrorBox("重复错误", "身份证号必须唯一!");
    sheet.AddValidationData(idValidation);

    // 规则2:固定值验证(省、市、区、学校名称、学校编号)
    SetFixedValue(sheet, 2, "北京市", rowTotal); // C列:现住省
    SetFixedValue(sheet, 3, "昌平区", rowTotal); // D列:现住市
    SetFixedValue(sheet, 4, "A街道", rowTotal); // E列:街道
    SetFixedValue(sheet, 7, deptName, rowTotal); // H列:学校名称
    SetFixedValue(sheet, 8, deptId, rowTotal); // I列:学校编号

    // 规则3:学段下拉选择(小学/初中/高中)
    CellRangeAddressList stageRange = new CellRangeAddressList(1, rowTotal, 9, 9); // J列
    IDataValidationConstraint stageConstraint = validationHelper.CreateExplicitListConstraint(
        new string[] { "小学", "初中", "高中", "高三", "中专", "技校", "大学" });
    IDataValidation stageValidation = validationHelper.CreateValidation(stageConstraint, stageRange);
    stageValidation.CreateErrorBox("输入错误", "请选择下拉选中对应值!");
    sheet.AddValidationData(stageValidation);

    // 规则4:年级
    CellRangeAddressList grade = new CellRangeAddressList(1, rowTotal, 10, 10); // K列
    IDataValidationConstraint gradeConstraint = validationHelper.CreateExplicitListConstraint(
        new string[] { "一年级", "二年级", "三年级", "四年级", "五年级", "六年级",
            "初一", "初二", "初三", "高一", "高二", "高三", "大一", "大二", "大三", "大四" });
    IDataValidation gradeValidation = validationHelper.CreateValidation(gradeConstraint, grade);
    gradeValidation.CreateErrorBox("输入错误", "请选择下拉选中对应值!");
    sheet.AddValidationData(gradeValidation);

	for (int rowIndex = 1; rowIndex <= rowTotal; rowIndex++)
	{
    	IRow row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);
    	ICell idCell = row.GetCell(idCardColumnIndex) ?? row.CreateCell(idCardColumnIndex);

    	// 应用文本样式(即使单元格为空)
    	idCell.CellStyle = textStyle;

    	// 如果已有数据,确保以文本格式存储
    	if (idCell.StringCellValue != null)
    	{
        	idCell.SetCellValue(idCell.StringCellValue);
    	}
}

    // 5. 流式输出
    MemoryStream stream = new MemoryStream();
    workbook.Write(stream, true);
    stream.Position = 0; // 重置流位置 
    return stream;
}

// 辅助方法:为整列设置固定值 添加样式参数
private void SetFixedValue(ISheet sheet, int columnIndex, string value, int rowTotal, ICellStyle textStyle)
{
    for (int rowIndex = 1; rowIndex <= rowTotal; rowIndex++)
    {
        IRow row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);
        ICell cell = row.GetCell(columnIndex) ?? row.CreateCell(columnIndex);
        cell.SetCellValue(value);

        // 如果是身份证列(索引1),应用文本样式
        if (columnIndex == 1)
        {
            cell.CellStyle = textStyle;
        }
    }
}

测试

修改下载后的文件后缀为xlsx格式即可打开

相关推荐
加号35 分钟前
【C#】实现沃德普线光控制器通信控制(附完整源码)
开发语言·c#
lzhdim1 小时前
SharpCompress:跨平台的 C# 压缩与解压库
开发语言·c#
~plus~3 小时前
.NET 8 C# 委托与事件实战教程
网络·c#·.net·.net 8·委托与事件·c#进阶
城数派4 小时前
2000-2025年我国省市县三级逐8天日间地表温度数据(Shp/Excel格式)
数据库·arcgis·信息可视化·数据分析·excel
beyond谚语4 小时前
接口&抽象类
c#·接口隔离原则·抽象类
新手小新4 小时前
C#学习笔记1-在VS CODE部署C#开发环境
笔记·学习·c#
开开心心就好6 小时前
能把网页藏在Word里的实用摸鱼工具
linux·运维·服务器·windows·随机森林·逻辑回归·excel
锵锵锵锵~蒋7 小时前
AI全托管处理EXCEL(并接入AI平台)
人工智能·excel·mcp·ai全托管·ai提效’
rockey6277 小时前
AScript动态脚本多语言环境支持
sql·c#·.net·script·eval·function·动态脚本
ou.cs8 小时前
c# SemaphoreSlim保姆级教程
开发语言·网络·c#