Loading

C#使用NPOI 读取并修改 Excel 模版(移动行,增加行)

准备一下:

templatePath 为模版路径,初始化 workbook
var workbook = new XSSFWorkbook(File.OpenRead(templatePath));
var sheet = workbook.GetSheetAt(0);

 

1、指定行、列单元格赋值

sheet.GetRow(1).GetCell(2).SetCellValue(companyInfo?.FFullName);

 

2、模版内现有行移动

(例如需要在中间行查询需要写入的数据行)
这里我们总共需要做三步,将源行移动至指定行、清除源行内容、清除源行单元格格式(如果想后续直接Copy写入数据行且存在合并单元格时,则必须清除,避免合并单元格在CopyRow时重复设置而CopyRow失败)

比如我们现在需要在从第五行(index=4)开始插入我们需要写的数据行:
var addRowCount = 5; // 导出数据行数
var initRowNum = 4; // 模版第4行起为 XX列表

var lastRowNum = sheet.LastRowNum; // 模板中最后的行数  

#region 根据导出数量向后移动至指定行
for (int j = lastRowNum; j >= initRowNum + 1; j--)
{
    // 1、将数据行从 j 行 Copy 到 j + addRowCount 行
    sheet.CopyRow(j, j + addRowCount);

    // 2、移除行(但不包括此行的合并单元格设置,因为合并单元格设置是存储在Sheet中的,而不是行上)
    sheet.RemoveRow(sheet.GetRow(j));

    // 3、移除源数据行的合并单元格设置(从sheet的合并单元格设置中找到当前行的合并单元格设置的 Index,然后干掉)
    var curRowMergedRegions = sheet.MergedRegions.FindAll(x => x.FirstRow == j);

    var curRowMergedRegionIndexs = curRowMergedRegions.Select(x =>
    {
        return sheet.MergedRegions.IndexOf(x);
    }).ToList();

    sheet.RemoveMergedRegions(curRowMergedRegionIndexs);
}
#endregion

 

3、向模版中间空行写入业务数据行

if (!dataList.IsNullOrEmpty()) // dataList 为业务需要写入数据行
{
    // 添加数据行
    for (var i = 0; i < dataList.Count; i++)
    {
        var assetAll = assetList[i];

        var row = sheet.GetRow(initRowNum); // 因为模版内已经存在一格空行,所以直接赋值,后续从此行进行 CopyRow 即可
        if (i == 0)
        {
            SetRowCellValue(i + 1, row, assetAll);
            continue;
        }

        var newRow = sheet.CopyRow(initAssetAllRowNum, initAssetAllRowNum + i);
        SetRowCellValue(i + 1, newRow, assetAll); // SetRowCellValue 一个自定义的往行中的单元格设置值的方法,大家可根据业务封装,赋值方式例如:newRow.GetCell(0).SetCellValue(serialNo);
    }
}

 

至此,已经Ok,后续保存 workbook 为excel文件即可。对于很多到处审批单或者复杂Excel的需求直接往模版内填值或者增行这样更加简单。

临时记录,主要逻辑和代码如上,仅供参考。

 

posted @ 2023-11-10 16:39  Pengxx  阅读(2173)  评论(0编辑  收藏  举报