第09章-Excel高级功能-合并单元格与冻结窗格
第九章:Excel高级功能-合并单元格与冻结窗格
9.1 合并单元格
9.1.1 合并单元格基础
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("合并示例");
// 合并单元格:A1:D1
// 参数:起始行, 结束行, 起始列, 结束列
CellRangeAddress mergedRegion = new CellRangeAddress(0, 0, 0, 3);
sheet.AddMergedRegion(mergedRegion);
// 设置合并单元格的值(只需设置左上角单元格)
IRow row = sheet.CreateRow(0);
ICell cell = row.CreateCell(0);
cell.SetCellValue("这是合并后的标题");
9.1.2 合并单元格样式
// 合并单元格后,样式需要应用到左上角单元格
ICellStyle mergedStyle = workbook.CreateCellStyle();
mergedStyle.Alignment = HorizontalAlignment.Center;
mergedStyle.VerticalAlignment = VerticalAlignment.Center;
IFont font = workbook.CreateFont();
font.IsBold = true;
font.FontHeightInPoints = 16;
mergedStyle.SetFont(font);
// 设置边框(合并区域的边框需要特殊处理)
mergedStyle.BorderTop = BorderStyle.Thin;
mergedStyle.BorderBottom = BorderStyle.Thin;
mergedStyle.BorderLeft = BorderStyle.Thin;
mergedStyle.BorderRight = BorderStyle.Thin;
cell.CellStyle = mergedStyle;
9.1.3 合并区域边框处理
/// <summary>
/// 为合并区域设置边框
/// </summary>
public static void SetMergedRegionBorder(ISheet sheet, CellRangeAddress region,
BorderStyle borderStyle, short borderColor, IWorkbook workbook)
{
ICellStyle borderStyle_ = workbook.CreateCellStyle();
borderStyle_.BorderTop = borderStyle;
borderStyle_.BorderBottom = borderStyle;
borderStyle_.BorderLeft = borderStyle;
borderStyle_.BorderRight = borderStyle;
borderStyle_.TopBorderColor = borderColor;
borderStyle_.BottomBorderColor = borderColor;
borderStyle_.LeftBorderColor = borderColor;
borderStyle_.RightBorderColor = borderColor;
for (int rowIdx = region.FirstRow; rowIdx <= region.LastRow; rowIdx++)
{
IRow row = sheet.GetRow(rowIdx) ?? sheet.CreateRow(rowIdx);
for (int colIdx = region.FirstColumn; colIdx <= region.LastColumn; colIdx++)
{
ICell cell = row.GetCell(colIdx) ?? row.CreateCell(colIdx);
ICellStyle cellStyle = workbook.CreateCellStyle();
if (cell.CellStyle != null)
{
cellStyle.CloneStyleFrom(cell.CellStyle);
}
// 设置边框
if (rowIdx == region.FirstRow)
cellStyle.BorderTop = borderStyle;
if (rowIdx == region.LastRow)
cellStyle.BorderBottom = borderStyle;
if (colIdx == region.FirstColumn)
cellStyle.BorderLeft = borderStyle;
if (colIdx == region.LastColumn)
cellStyle.BorderRight = borderStyle;
cellStyle.TopBorderColor = borderColor;
cellStyle.BottomBorderColor = borderColor;
cellStyle.LeftBorderColor = borderColor;
cellStyle.RightBorderColor = borderColor;
cell.CellStyle = cellStyle;
}
}
}
9.1.4 取消合并
// 获取所有合并区域
int mergedRegionCount = sheet.NumMergedRegions;
// 遍历合并区域
for (int i = 0; i < mergedRegionCount; i++)
{
CellRangeAddress region = sheet.GetMergedRegion(i);
Console.WriteLine($"合并区域 {i}: {region.FormatAsString()}");
}
// 取消特定的合并区域(通过索引)
sheet.RemoveMergedRegion(0);
// 取消所有合并
while (sheet.NumMergedRegions > 0)
{
sheet.RemoveMergedRegion(0);
}
9.1.5 合并单元格辅助类
/// <summary>
/// 合并单元格辅助类
/// </summary>
public static class MergeCellHelper
{
/// <summary>
/// 合并单元格并设置值和样式
/// </summary>
public static void MergeAndSetValue(ISheet sheet, int firstRow, int lastRow,
int firstCol, int lastCol, object value, ICellStyle style = null)
{
// 创建合并区域
CellRangeAddress region = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
sheet.AddMergedRegion(region);
// 获取或创建左上角单元格
IRow row = sheet.GetRow(firstRow) ?? sheet.CreateRow(firstRow);
ICell cell = row.GetCell(firstCol) ?? row.CreateCell(firstCol);
// 设置值
if (value != null)
{
switch (value)
{
case string s:
cell.SetCellValue(s);
break;
case double d:
cell.SetCellValue(d);
break;
case DateTime dt:
cell.SetCellValue(dt);
break;
case bool b:
cell.SetCellValue(b);
break;
default:
cell.SetCellValue(value.ToString());
break;
}
}
// 设置样式
if (style != null)
{
cell.CellStyle = style;
}
}
/// <summary>
/// 创建带样式的合并标题
/// </summary>
public static void CreateMergedTitle(ISheet sheet, int row, int firstCol, int lastCol,
string title, IWorkbook workbook)
{
ICellStyle titleStyle = workbook.CreateCellStyle();
titleStyle.Alignment = HorizontalAlignment.Center;
titleStyle.VerticalAlignment = VerticalAlignment.Center;
IFont font = workbook.CreateFont();
font.IsBold = true;
font.FontHeightInPoints = 14;
titleStyle.SetFont(font);
titleStyle.FillForegroundColor = IndexedColors.LightBlue.Index;
titleStyle.FillPattern = FillPattern.SolidForeground;
MergeAndSetValue(sheet, row, row, firstCol, lastCol, title, titleStyle);
}
/// <summary>
/// 检查单元格是否在合并区域内
/// </summary>
public static bool IsCellInMergedRegion(ISheet sheet, int row, int col)
{
for (int i = 0; i < sheet.NumMergedRegions; i++)
{
CellRangeAddress region = sheet.GetMergedRegion(i);
if (region.IsInRange(row, col))
{
return true;
}
}
return false;
}
/// <summary>
/// 获取单元格所在的合并区域
/// </summary>
public static CellRangeAddress GetMergedRegion(ISheet sheet, int row, int col)
{
for (int i = 0; i < sheet.NumMergedRegions; i++)
{
CellRangeAddress region = sheet.GetMergedRegion(i);
if (region.IsInRange(row, col))
{
return region;
}
}
return null;
}
}
9.2 冻结窗格
9.2.1 冻结行
// 冻结首行
sheet.CreateFreezePane(0, 1); // 冻结0列,1行
// 冻结前3行
sheet.CreateFreezePane(0, 3);
9.2.2 冻结列
// 冻结首列
sheet.CreateFreezePane(1, 0); // 冻结1列,0行
// 冻结前2列
sheet.CreateFreezePane(2, 0);
9.2.3 同时冻结行和列
// 冻结首行和首列
sheet.CreateFreezePane(1, 1);
// 冻结前2列和前3行
sheet.CreateFreezePane(2, 3);
// 带滚动位置的冻结
// CreateFreezePane(冻结列数, 冻结行数, 右侧首列, 下方首行)
sheet.CreateFreezePane(2, 3, 2, 3);
9.2.4 拆分窗格
// 水平拆分
// CreateSplitPane(x位置, y位置, 左列, 上行, 激活区域)
sheet.CreateSplitPane(0, 2000, 0, 10, PanePosition.LowerLeft);
// 垂直拆分
sheet.CreateSplitPane(2000, 0, 5, 0, PanePosition.UpperRight);
// 同时水平和垂直拆分
sheet.CreateSplitPane(2000, 2000, 5, 10, PanePosition.LowerRight);
// 拆分位置说明:x和y使用twip单位(1点 = 20 twip)
9.3 自动筛选
9.3.1 设置自动筛选区域
// 设置自动筛选区域
CellRangeAddress filterRange = new CellRangeAddress(0, 100, 0, 5);
sheet.SetAutoFilter(filterRange);
// 也可以使用字符串格式
// sheet.SetAutoFilter(CellRangeAddress.ValueOf("A1:F101"));
9.3.2 筛选示例
public static void CreateFilterExample()
{
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("筛选示例");
// 创建表头
IRow header = sheet.CreateRow(0);
header.CreateCell(0).SetCellValue("姓名");
header.CreateCell(1).SetCellValue("部门");
header.CreateCell(2).SetCellValue("职位");
header.CreateCell(3).SetCellValue("薪资");
// 创建数据
var data = new[]
{
("张三", "技术部", "工程师", 15000),
("李四", "技术部", "高级工程师", 25000),
("王五", "市场部", "经理", 20000),
("赵六", "人事部", "主管", 18000),
("钱七", "技术部", "工程师", 16000)
};
for (int i = 0; i < data.Length; i++)
{
IRow row = sheet.CreateRow(i + 1);
row.CreateCell(0).SetCellValue(data[i].Item1);
row.CreateCell(1).SetCellValue(data[i].Item2);
row.CreateCell(2).SetCellValue(data[i].Item3);
row.CreateCell(3).SetCellValue(data[i].Item4);
}
// 设置自动筛选
sheet.SetAutoFilter(new CellRangeAddress(0, data.Length, 0, 3));
// 保存
using (FileStream fs = new FileStream("筛选示例.xlsx", FileMode.Create))
{
workbook.Write(fs);
}
}
9.4 分组与大纲
9.4.1 行分组
// 行分组(将第3-5行分为一组)
sheet.GroupRow(2, 4); // 索引从0开始
// 设置分组层级
sheet.GroupRow(2, 4);
sheet.GroupRow(5, 7);
sheet.GroupRow(2, 7); // 嵌套分组
// 折叠分组
sheet.SetRowGroupCollapsed(2, true);
// 展开分组
sheet.SetRowGroupCollapsed(2, false);
9.4.2 列分组
// 列分组(将B-D列分为一组)
sheet.GroupColumn(1, 3);
// 折叠列分组
sheet.SetColumnGroupCollapsed(1, true);
// 展开列分组
sheet.SetColumnGroupCollapsed(1, false);
9.4.3 大纲设置
// 设置大纲级别的摘要行位置
// true: 摘要行在下方;false: 摘要行在上方
sheet.RowSumsBelow = true;
// 设置大纲级别的摘要列位置
// true: 摘要列在右侧;false: 摘要列在左侧
sheet.RowSumsRight = true;
9.4.4 分组示例
public static void CreateGroupingExample()
{
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("分组示例");
// 创建季度销售报表数据
string[] rows = {
"Q1", " 一月", " 二月", " 三月",
"Q2", " 四月", " 五月", " 六月",
"Q3", " 七月", " 八月", " 九月",
"Q4", " 十月", " 十一月", " 十二月",
"年度合计"
};
Random rand = new Random();
for (int i = 0; i < rows.Length; i++)
{
IRow row = sheet.CreateRow(i);
row.CreateCell(0).SetCellValue(rows[i]);
row.CreateCell(1).SetCellValue(rand.Next(10000, 50000));
}
// 设置分组
// Q1详细数据
sheet.GroupRow(1, 3);
// Q2详细数据
sheet.GroupRow(5, 7);
// Q3详细数据
sheet.GroupRow(9, 11);
// Q4详细数据
sheet.GroupRow(13, 15);
// 默认折叠
sheet.SetRowGroupCollapsed(1, true);
sheet.SetRowGroupCollapsed(5, true);
sheet.SetRowGroupCollapsed(9, true);
sheet.SetRowGroupCollapsed(13, true);
// 保存
using (FileStream fs = new FileStream("分组示例.xlsx", FileMode.Create))
{
workbook.Write(fs);
}
}
9.5 打印设置
9.5.1 基本打印设置
// 获取打印设置对象
IPrintSetup printSetup = sheet.PrintSetup;
// 纸张大小
printSetup.PaperSize = (short)PaperSize.A4;
// 打印方向
printSetup.Landscape = true; // 横向
printSetup.Landscape = false; // 纵向
// 缩放比例
printSetup.Scale = 80; // 80%
// 适合页面
printSetup.FitWidth = 1; // 适合1页宽
printSetup.FitHeight = 0; // 高度不限
// 首页页码
printSetup.PageStart = 1;
printSetup.UsePage = true;
// 打印质量(DPI)
printSetup.HResolution = 300;
printSetup.VResolution = 300;
// 页边距(单位:英寸)
sheet.SetMargin(MarginType.TopMargin, 1.0);
sheet.SetMargin(MarginType.BottomMargin, 1.0);
sheet.SetMargin(MarginType.LeftMargin, 0.75);
sheet.SetMargin(MarginType.RightMargin, 0.75);
sheet.SetMargin(MarginType.HeaderMargin, 0.5);
sheet.SetMargin(MarginType.FooterMargin, 0.5);
9.5.2 打印区域
// 设置打印区域
workbook.SetPrintArea(0, 0, 10, 0, 100); // sheetIndex, 起始列, 结束列, 起始行, 结束行
// 或使用字符串格式
workbook.SetPrintArea(0, "$A$1:$K$101");
// 获取打印区域
string printArea = workbook.GetPrintArea(0);
9.5.3 重复打印行(标题行)
// 设置重复打印的行(每页都打印的标题行)
sheet.RepeatingRows = new CellRangeAddress(0, 0, 0, 10); // 第1行
// 设置重复打印的列
sheet.RepeatingColumns = new CellRangeAddress(0, 100, 0, 0); // 第A列
9.5.4 页眉页脚
// 获取页眉页脚对象
IHeader header = sheet.Header;
IFooter footer = sheet.Footer;
// 设置页眉
header.Left = "公司名称";
header.Center = "报表标题";
header.Right = "&D"; // 日期
// 设置页脚
footer.Left = "机密文件";
footer.Center = "第 &P 页,共 &N 页";
footer.Right = "&T"; // 时间
// 特殊代码
// &P - 页码
// &N - 总页数
// &D - 日期
// &T - 时间
// &F - 文件名
// &A - 工作表名
// &B - 粗体开关
// &I - 斜体开关
// &U - 下划线开关
// &"字体名" - 字体
// &数字 - 字号
9.5.5 打印设置示例
public static void SetupPrinting(IWorkbook workbook, ISheet sheet)
{
// 打印设置
IPrintSetup printSetup = sheet.PrintSetup;
printSetup.PaperSize = (short)PaperSize.A4;
printSetup.Landscape = false;
printSetup.FitWidth = 1;
printSetup.FitHeight = 0;
// 页边距
sheet.SetMargin(MarginType.TopMargin, 1.0);
sheet.SetMargin(MarginType.BottomMargin, 1.0);
sheet.SetMargin(MarginType.LeftMargin, 0.75);
sheet.SetMargin(MarginType.RightMargin, 0.75);
// 重复标题行
sheet.RepeatingRows = new CellRangeAddress(0, 0, 0, 0);
// 打印区域
int lastRow = sheet.LastRowNum;
int lastCol = sheet.GetRow(0)?.LastCellNum ?? 0;
workbook.SetPrintArea(workbook.GetSheetIndex(sheet), 0, lastCol - 1, 0, lastRow);
// 页眉页脚
IHeader header = sheet.Header;
header.Center = "月度销售报表";
header.Right = "&D";
IFooter footer = sheet.Footer;
footer.Center = "第 &P 页,共 &N 页";
footer.Right = "机密";
// 打印网格线
sheet.IsPrintGridlines = true;
// 打印行列标题
sheet.IsPrintRowAndColumnHeadings = false;
// 居中打印
sheet.HorizontallyCenter = true;
sheet.VerticallyCenter = false;
}
9.6 显示设置
9.6.1 网格线和标题
// 显示/隐藏网格线
sheet.DisplayGridlines = false;
// 显示/隐藏行列标题
sheet.DisplayRowColHeadings = false;
// 显示/隐藏零值
sheet.DisplayZeros = false;
// 显示公式而不是结果
sheet.DisplayFormulas = true;
9.6.2 缩放设置
// 设置缩放比例(10-400%)
sheet.SetZoom(150); // 150%
// 设置缩放为适合选定区域
// 这需要通过打印设置实现
9.6.3 选择设置
// 设置活动单元格
// 通过创建选择区域实现
if (sheet is XSSFSheet xssfSheet)
{
// XSSF特有功能
xssfSheet.SetActiveCell(new CellAddress("A1"));
}
9.7 名称管理器
9.7.1 创建命名范围
// 创建工作簿级别的命名范围
IName globalName = workbook.CreateName();
globalName.NameName = "SalesData";
globalName.RefersToFormula = "Sheet1!$A$1:$D$100";
// 创建工作表级别的命名范围
IName localName = workbook.CreateName();
localName.NameName = "LocalRange";
localName.RefersToFormula = "Sheet1!$B$2:$B$50";
localName.SheetIndex = 0; // 关联到第一个工作表
9.7.2 使用命名范围
// 获取命名范围
IName existingName = workbook.GetName("SalesData");
if (existingName != null)
{
string formula = existingName.RefersToFormula;
Console.WriteLine($"范围: {formula}");
}
// 获取所有命名范围
var allNames = workbook.GetAllNames();
foreach (IName name in allNames)
{
Console.WriteLine($"{name.NameName}: {name.RefersToFormula}");
}
// 删除命名范围
workbook.RemoveName("SalesData");
9.7.3 命名范围在公式中的使用
// 使用命名范围的公式
cell.SetCellFormula("SUM(SalesData)");
cell.SetCellFormula("AVERAGE(SalesData)");
cell.SetCellFormula("VLOOKUP(A1, SalesData, 2, FALSE)");
9.8 条件格式
9.8.1 基于值的条件格式
ISheetConditionalFormatting cf = sheet.SheetConditionalFormatting;
// 定义应用范围
CellRangeAddress[] ranges = { CellRangeAddress.ValueOf("B2:B100") };
// 大于80显示绿色背景
IConditionalFormattingRule rule1 = cf.CreateConditionalFormattingRule(
ComparisonOperator.GreaterThan, "80", null);
IPatternFormatting pf1 = rule1.CreatePatternFormatting();
pf1.FillBackgroundColor = IndexedColors.LightGreen.Index;
pf1.FillPattern = FillPattern.SolidForeground;
// 小于60显示红色背景
IConditionalFormattingRule rule2 = cf.CreateConditionalFormattingRule(
ComparisonOperator.LessThan, "60", null);
IPatternFormatting pf2 = rule2.CreatePatternFormatting();
pf2.FillBackgroundColor = IndexedColors.Rose.Index;
pf2.FillPattern = FillPattern.SolidForeground;
// 应用规则
cf.AddConditionalFormatting(ranges, new[] { rule1, rule2 });
9.8.2 基于公式的条件格式
// 基于公式的条件格式
IConditionalFormattingRule formulaRule = cf.CreateConditionalFormattingRule(
"AND($A2>0,$B2>100)");
IPatternFormatting pfFormula = formulaRule.CreatePatternFormatting();
pfFormula.FillBackgroundColor = IndexedColors.LightYellow.Index;
pfFormula.FillPattern = FillPattern.SolidForeground;
// 设置字体
IFontFormatting ff = formulaRule.CreateFontFormatting();
ff.SetFontStyle(true, false); // 粗体,非斜体
ff.FontColorIndex = IndexedColors.DarkRed.Index;
cf.AddConditionalFormatting(ranges, formulaRule);
9.9 综合示例
9.9.1 创建专业报表模板
public class ProfessionalReportExample
{
public static void CreateReport()
{
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("销售报表");
// 创建样式
var styles = CreateStyles(workbook);
int rowIndex = 0;
// 1. 报表标题(合并单元格)
MergeCellHelper.CreateMergedTitle(sheet, rowIndex++, 0, 6,
"2024年度销售业绩报表", workbook);
// 空行
rowIndex++;
// 2. 创建表头
IRow headerRow = sheet.CreateRow(rowIndex++);
string[] headers = { "序号", "月份", "销售额", "成本", "利润", "增长率", "备注" };
for (int i = 0; i < headers.Length; i++)
{
ICell cell = headerRow.CreateCell(i);
cell.SetCellValue(headers[i]);
cell.CellStyle = styles["header"];
}
// 3. 填充数据
string[] months = { "1月", "2月", "3月", "4月", "5月", "6月",
"7月", "8月", "9月", "10月", "11月", "12月" };
Random rand = new Random(42);
int dataStartRow = rowIndex;
for (int i = 0; i < months.Length; i++)
{
IRow row = sheet.CreateRow(rowIndex++);
row.CreateCell(0).SetCellValue(i + 1);
row.CreateCell(1).SetCellValue(months[i]);
double sales = rand.Next(80000, 150000);
double cost = sales * 0.6;
row.CreateCell(2).SetCellValue(sales);
row.CreateCell(3).SetCellValue(cost);
row.CreateCell(4).SetCellFormula($"C{rowIndex}-D{rowIndex}");
if (i > 0)
{
row.CreateCell(5).SetCellFormula($"(C{rowIndex}-C{rowIndex - 1})/C{rowIndex - 1}");
}
else
{
row.CreateCell(5).SetCellValue(0);
}
row.CreateCell(6).SetCellValue("");
// 应用样式
for (int j = 0; j < 7; j++)
{
ICell cell = row.GetCell(j);
cell.CellStyle = j == 5 ? styles["percent"] :
j >= 2 && j <= 4 ? styles["currency"] : styles["body"];
}
}
// 4. 汇总行
IRow summaryRow = sheet.CreateRow(rowIndex++);
summaryRow.CreateCell(0).SetCellValue("");
summaryRow.CreateCell(1).SetCellValue("合计");
summaryRow.CreateCell(2).SetCellFormula($"SUM(C{dataStartRow + 1}:C{rowIndex - 1})");
summaryRow.CreateCell(3).SetCellFormula($"SUM(D{dataStartRow + 1}:D{rowIndex - 1})");
summaryRow.CreateCell(4).SetCellFormula($"SUM(E{dataStartRow + 1}:E{rowIndex - 1})");
summaryRow.CreateCell(5).SetCellFormula($"AVERAGE(F{dataStartRow + 2}:F{rowIndex - 1})");
summaryRow.CreateCell(6).SetCellValue("");
for (int i = 0; i < 7; i++)
{
summaryRow.GetCell(i).CellStyle = styles["summary"];
}
// 5. 设置列宽
sheet.SetColumnWidth(0, 8 * 256);
sheet.SetColumnWidth(1, 10 * 256);
for (int i = 2; i <= 5; i++)
{
sheet.SetColumnWidth(i, 15 * 256);
}
sheet.SetColumnWidth(6, 20 * 256);
// 6. 冻结窗格
sheet.CreateFreezePane(0, 3);
// 7. 设置自动筛选
sheet.SetAutoFilter(new CellRangeAddress(2, rowIndex - 1, 0, 6));
// 8. 添加条件格式
AddConditionalFormatting(sheet, dataStartRow, rowIndex - 2);
// 9. 设置打印
SetupPrintSettings(workbook, sheet);
// 10. 计算公式
IFormulaEvaluator evaluator = workbook.GetCreationHelper().CreateFormulaEvaluator();
evaluator.EvaluateAll();
// 保存
using (FileStream fs = new FileStream("专业报表.xlsx", FileMode.Create))
{
workbook.Write(fs);
}
Console.WriteLine("报表创建成功!");
}
private static Dictionary<string, ICellStyle> CreateStyles(IWorkbook workbook)
{
var styles = new Dictionary<string, ICellStyle>();
IDataFormat format = workbook.CreateDataFormat();
// 表头样式
ICellStyle headerStyle = workbook.CreateCellStyle();
IFont headerFont = workbook.CreateFont();
headerFont.IsBold = true;
headerFont.FontHeightInPoints = 11;
headerStyle.SetFont(headerFont);
headerStyle.Alignment = HorizontalAlignment.Center;
headerStyle.VerticalAlignment = VerticalAlignment.Center;
headerStyle.FillForegroundColor = IndexedColors.Grey25Percent.Index;
headerStyle.FillPattern = FillPattern.SolidForeground;
SetAllBorders(headerStyle, BorderStyle.Thin);
styles["header"] = headerStyle;
// 正文样式
ICellStyle bodyStyle = workbook.CreateCellStyle();
bodyStyle.VerticalAlignment = VerticalAlignment.Center;
SetAllBorders(bodyStyle, BorderStyle.Thin);
styles["body"] = bodyStyle;
// 货币样式
ICellStyle currencyStyle = workbook.CreateCellStyle();
currencyStyle.CloneStyleFrom(bodyStyle);
currencyStyle.Alignment = HorizontalAlignment.Right;
currencyStyle.DataFormat = format.GetFormat("¥#,##0.00");
styles["currency"] = currencyStyle;
// 百分比样式
ICellStyle percentStyle = workbook.CreateCellStyle();
percentStyle.CloneStyleFrom(bodyStyle);
percentStyle.Alignment = HorizontalAlignment.Right;
percentStyle.DataFormat = format.GetFormat("0.00%");
styles["percent"] = percentStyle;
// 汇总行样式
ICellStyle summaryStyle = workbook.CreateCellStyle();
IFont summaryFont = workbook.CreateFont();
summaryFont.IsBold = true;
summaryStyle.SetFont(summaryFont);
summaryStyle.FillForegroundColor = IndexedColors.LightYellow.Index;
summaryStyle.FillPattern = FillPattern.SolidForeground;
summaryStyle.Alignment = HorizontalAlignment.Right;
summaryStyle.DataFormat = format.GetFormat("¥#,##0.00");
SetAllBorders(summaryStyle, BorderStyle.Thin);
styles["summary"] = summaryStyle;
return styles;
}
private static void SetAllBorders(ICellStyle style, BorderStyle borderStyle)
{
style.BorderTop = borderStyle;
style.BorderBottom = borderStyle;
style.BorderLeft = borderStyle;
style.BorderRight = borderStyle;
}
private static void AddConditionalFormatting(ISheet sheet, int startRow, int endRow)
{
ISheetConditionalFormatting cf = sheet.SheetConditionalFormatting;
// 增长率条件格式
CellRangeAddress[] ranges = { new CellRangeAddress(startRow, endRow, 5, 5) };
// 正增长显示绿色
IConditionalFormattingRule rule1 = cf.CreateConditionalFormattingRule(
ComparisonOperator.GreaterThan, "0", null);
IFontFormatting ff1 = rule1.CreateFontFormatting();
ff1.FontColorIndex = IndexedColors.Green.Index;
// 负增长显示红色
IConditionalFormattingRule rule2 = cf.CreateConditionalFormattingRule(
ComparisonOperator.LessThan, "0", null);
IFontFormatting ff2 = rule2.CreateFontFormatting();
ff2.FontColorIndex = IndexedColors.Red.Index;
cf.AddConditionalFormatting(ranges, new[] { rule1, rule2 });
}
private static void SetupPrintSettings(IWorkbook workbook, ISheet sheet)
{
IPrintSetup printSetup = sheet.PrintSetup;
printSetup.PaperSize = (short)PaperSize.A4;
printSetup.Landscape = true;
printSetup.FitWidth = 1;
printSetup.FitHeight = 0;
sheet.SetMargin(MarginType.TopMargin, 0.75);
sheet.SetMargin(MarginType.BottomMargin, 0.75);
sheet.SetMargin(MarginType.LeftMargin, 0.5);
sheet.SetMargin(MarginType.RightMargin, 0.5);
sheet.RepeatingRows = new CellRangeAddress(2, 2, 0, 6);
IHeader header = sheet.Header;
header.Center = "销售业绩报表";
header.Right = "&D";
IFooter footer = sheet.Footer;
footer.Center = "第 &P 页,共 &N 页";
sheet.HorizontallyCenter = true;
}
}
9.10 本章小结
本章详细介绍了NPOI中的Excel高级功能。通过本章学习,你应该掌握:
- 合并单元格的创建、样式设置和取消
- 冻结窗格和拆分窗格的使用
- 自动筛选的设置
- 行列分组和大纲功能
- 打印设置(纸张、页边距、打印区域、页眉页脚)
- 显示设置(网格线、缩放等)
- 命名范围的创建和使用
- 条件格式的应用
这些高级功能可以让Excel文档更加专业和易用,是创建企业级报表的重要工具。
下一章预告:第十章将介绍Word文档基础操作,包括文档的创建、打开、保存以及基本结构操作。

浙公网安备 33010602011771号