前段时间 用 C# 调用 OLEDB 导出 Excel 文件以后。
现在又有新的问题了。
客户要求一些特殊的效果。
要求某行里面,某列的数值大于另外一列的数据的时候,要求该行字体粗体,字色变红。
实现上面的功能,可以通过手动, 在 Excel 里面,通过 条件格式 的设定,来实现。
也就是像下图这样的处理。
问题就在于,这个操作, 客户是不做的,只能 C# 里面去做。
下面是 设定这个 条件格式的 C# 代码 (仅仅包含 条件格式 与 冻结窗口 的代码,其他的不额外粘贴了)
/// <summary>
/// 获取指定工作表的 已使用数据单元 最大 行列地址.
/// </summary>
/// <param name="mySheet"></param>
/// <returns></returns>
private string GetEndAddress(Excel.Worksheet mySheet)
{
// 取得数据的Sheet的行数与列数
int rowCount = mySheet.UsedRange.Rows.Count;
int colCount = mySheet.UsedRange.Columns.Count;
if (colCount <= 26)
{
// 列数小于等于 26。 字母是 A-Z
char topChar = (char)('A' + (colCount - 1));
return topChar.ToString() + rowCount;
}
else
{
// 大于 26, 意味着要有 AA-- ZZ了
char topChar = (char)('A' + (colCount / 26) - 1);
char secondChar = (char)('A' + (colCount % 26) - 1);
return topChar.ToString() + secondChar.ToString() + rowCount;
}
}
/// <summary>
/// 设置条件格式.
/// </summary>
/// <param name="fromSheetName"> 需要设置条件格式的 Sheet 名字.</param>
/// <param name="formula1"> 条件公式. </param>
/// <param name="bold"> 满足条件后的行 是否粗体. </param>
/// <param name="italic"> 满足条件后的行 是否斜体. </param>
/// <param name="color"> 满足条件后的行 字体的颜色. </param>
public void SetFormatConditions(
string fromSheetName,
string formula1,
bool bold,
bool italic,
int color)
{
// 选择源工作表.
Excel.Worksheet mySheet = (Excel.Worksheet)xlBook.Sheets.get_Item(fromSheetName);
// 选择
mySheet.Select();
// 范围选择.
Excel.Range myRange = mySheet.Range["A2", GetEndAddress(mySheet)];
// 设置条件公式.
Excel.FormatCondition myCond = myRange.FormatConditions.Add(
Excel.XlFormatConditionType.xlExpression,
Type.Missing,
formula1);
// 设置条件字体.
myCond.Font.Bold = bold;
myCond.Font.Italic = italic;
myCond.Font.Color = color;
}
/// <summary>
/// 设置 冻结窗口 (首行)
/// </summary>
/// <param name="fromSheetName"> 需要设置条件格式的 Sheet 名字. </param>
public void ActiveWindow(string fromSheetName)
{
// 选择源工作表.
Excel.Worksheet mySheet = (Excel.Worksheet)xlBook.Sheets.get_Item(fromSheetName);
mySheet.Select();
xlApp.ActiveWindow.SplitColumn = 0;
xlApp.ActiveWindow.SplitRow = 1;
xlApp.ActiveWindow.FreezePanes = true;
}
关于 那个 Excel 公式, 有点讲究, 因为不能用绝对地址, 只能用相对地址。
上图的公式为:
=INDIRECT(CONCATENATE("R",ROW(),"C2"),FALSE) < INDIRECT(CONCATENATE("R",ROW(),"C3"),FALSE)
其中 ROW() 是 获得 Excel 表格当前行号
CONCATENATE 是连接字符串
CONCATENATE("R",ROW(),"C2")
CONCATENATE("R",ROW(),"C3") 就是通过 行号,来计算一个 当前行的地址。
例如当前行是第3行
那么就返回 R3C2, 意思是 第3行第2列。
以及返回 R3C3, 意思是 第3行第3列。
INDIRECT 是通过 地址,获取指定地址的具体数据。
例如当前行是第3行。
最后相当于执行的是
=INDIRECT("R3C2"),FALSE) < INDIRECT("R3C3"),FALSE)
也就是判断,当前行的第3列的数据,是否大于当前行的第2列的数据。
如果条件满足了,那么就需要设定格式。