NPOI - 从模板创建新 Excel 时条件格式不起作用

作者:编程家 分类: excel 时间:2025-08-27

NPOI是一个强大的.NET开源库,用于处理Microsoft Office格式的文件。其中,NPOI可以用于创建和修改Excel文件。然而,最近在使用NPOI的过程中,我遇到了一个问题:在使用模板创建新Excel文件时,条件格式似乎不起作用。本文将详细介绍这个问题,并提供一个案例代码来解决它。

首先,让我们来看一下使用NPOI创建新Excel文件的一般流程。我们通常会先创建一个模板文件,其中包含了一些预定义的格式和样式,然后使用NPOI加载这个模板文件,并根据需要修改其中的内容。但是,在某些情况下,当我们使用模板创建新文件时,条件格式并不会正确地应用。

为了更好地说明这个问题,让我们来看一个具体的例子。假设我们有一个模板文件,其中包含一个日期列。我们希望在新创建的文件中,当日期大于当前日期时,该单元格的背景色变为红色。为了实现这个效果,我们可以使用条件格式。

下面是一个使用NPOI创建新Excel文件的示例代码:

csharp

using NPOI.HSSF.UserModel;

using NPOI.SS.UserModel;

using NPOI.SS.Util;

using System;

using System.IO;

public class ExcelCreator

{

public void CreateNewFileFromTemplate(string templatePath, string outputPath)

{

using (FileStream fs = new FileStream(templatePath, FileMode.Open, FileAccess.Read))

{

IWorkbook workbook = new HSSFWorkbook(fs);

ISheet sheet = workbook.GetSheetAt(0);

IConditionalFormattingHelper helper = sheet.SheetConditionalFormatting;

ISheetConditionalFormatting formatting = helper.CreateConditionalFormatting();

IConditionalFormattingRule rule = helper.CreateConditionalFormattingRule(ComparisonOperator.GreaterThan, "TODAY()");

IPatternFormatting patternFormatting = rule.CreatePatternFormatting();

patternFormatting.FillBackgroundColor = IndexedColors.Red.Index;

formatting.AddConditionalFormatting(CellRangeAddress.ValueOf("A2:A100"), rule);

sheet.SheetConditionalFormatting.AddConditionalFormatting(formatting);

using (FileStream outputFile = new FileStream(outputPath, FileMode.Create, FileAccess.Write))

{

workbook.Write(outputFile);

}

}

}

}

在上述代码中,我们首先使用`FileStream`加载模板文件,然后创建一个`IWorkbook`对象来表示工作簿。接下来,我们获取第一个工作表,并创建一个`IConditionalFormattingHelper`对象来辅助我们创建条件格式。然后,我们创建一个`IConditionalFormattingRule`对象,指定了条件格式的条件(日期大于当前日期)和样式(背景色为红色)。最后,我们将这个规则应用到指定的单元格范围,并将文件保存到输出路径。

然而,尽管我们在代码中正确地创建并应用了条件格式,但在使用模板创建新Excel文件时,这些条件格式并没有起作用。这是因为NPOI在处理模板文件时,似乎没有正确地解析和应用其中的条件格式。

为了解决这个问题,我们需要手动复制模板文件中的条件格式,并将其应用到新创建的文件中。以下是修改后的代码:

csharp

using NPOI.HSSF.UserModel;

using NPOI.SS.UserModel;

using NPOI.SS.Util;

using System;

using System.IO;

public class ExcelCreator

{

public void CreateNewFileFromTemplate(string templatePath, string outputPath)

{

using (FileStream fs = new FileStream(templatePath, FileMode.Open, FileAccess.Read))

{

IWorkbook templateWorkbook = new HSSFWorkbook(fs);

IWorkbook newWorkbook = new HSSFWorkbook();

ISheet newSheet = newWorkbook.CreateSheet("Sheet1");

CopyConditionalFormatting(templateWorkbook, newWorkbook, newSheet);

using (FileStream outputFile = new FileStream(outputPath, FileMode.Create, FileAccess.Write))

{

newWorkbook.Write(outputFile);

}

}

}

private void CopyConditionalFormatting(IWorkbook templateWorkbook, IWorkbook newWorkbook, ISheet newSheet)

{

for (int i = 0; i < templateWorkbook.NumSheets; i++)

{

ISheet templateSheet = templateWorkbook.GetSheetAt(i);

ISheet newSheet = newWorkbook.GetSheetAt(i);

for (int j = 0; j < templateSheet.NumConditionalFormattings; j++)

{

IConditionalFormatting templateFormatting = templateSheet.GetConditionalFormattingAt(j);

IConditionalFormatting newFormatting = newSheet.SheetConditionalFormatting.CreateConditionalFormatting();

for (int k = 0; k < templateFormatting.NumberOfRules; k++)

{

IConditionalFormattingRule templateRule = templateFormatting.GetRule(k);

IConditionalFormattingRule newRule = newFormatting.CreateConditionalFormattingRule(templateRule);

newFormatting.AddConditionalFormatting(templateFormatting.GetFormattingRanges(k), newRule);

}

newSheet.SheetConditionalFormatting.AddConditionalFormatting(newFormatting);

}

}

}

}

在上述修改后的代码中,我们首先创建了一个新的`IWorkbook`对象和一个新的`ISheet`对象,然后调用`CopyConditionalFormatting`方法来复制模板文件中的条件格式。在`CopyConditionalFormatting`方法中,我们遍历模板文件中的每个工作表和条件格式,并将其复制到新的文件中。最后,我们将新文件保存到输出路径。

通过这种方式,我们可以确保在使用模板创建新Excel文件时,条件格式能够正确地应用。这个问题的解决方法可能会在将来的NPOI版本中得到修复,但目前使用手动复制的方法是一个有效的解决方案。

在本文中,我们介绍了使用NPOI创建新Excel文件时条件格式不起作用的问题,并提供了一个案例代码来解决它。我们发现,通过手动复制模板文件中的条件格式,并将其应用到新创建的文件中,可以解决这个问题。希望这篇文章对正在使用NPOI处理Excel文件的开发者们有所帮助。