C# 监听Excel表格更改
Original...About 1 min
C# 监听Excel表格更改
需求
监听Excel表格的变化,每当有变化就执行表格处理操作。
C# 标准库有提供 FileSystemWatcher
,直接实现我们想要的监听功能。官方文档给出了示例。
根据这里要监听的文件类型,修改如下参数:
watcher.Filter = "*.xlsx";
watcher.IncludeSubdirectories = false;
watcher.EnableRaisingEvents = true;
然后运行,修改表格内容,会发现如下输出信息(完整路径略去):
Renamed:
Old: Effect.xlsx
New: EE144302.tmp
Renamed:
Old: 1C910100
New: Effect.xlsx
Changed: Effect.xlsx
Changed: Effect.xlsx
注意到特别之处了吗?文件内容变化时,Excel 会先转为一个临时文件,然后用另一个临时文件替换了原来的文件。而 Changed
事件会触发两次!因此监听 Changed
是不太管用的。
而且,如果尝试调整 NotifyFilter
,会发现它其实是 NotifyFilters.Security
触发的,是文件或文件夹的安全设置更改,并不是我们想要的。其他写入、大小更改等是无法被监听到的!
而且考虑到两次 Changed
难以区分,这里只监听重命名事件 Renamed
。
在回调函数,可以加一个过滤器,确保这个文件是有效的 xlsx,不是临时文件。
if (e.Name.StartsWith("~") || !e.Name.EndsWith(".xlsx"))
{
return;
}
完整代码如下:
public static class ExcelWatcher
{
public static void Start()
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Watching changes in {Config.mExcelPath}");
Console.ResetColor();
using var watcher = new FileSystemWatcher(Config.mExcelPath);
// excel的更新是 rename 模式
watcher.Renamed += OnRenamed;
watcher.Filter = "*.xlsx";
watcher.IncludeSubdirectories = false;
watcher.EnableRaisingEvents = true;
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
}
private static void OnRenamed(object sender, RenamedEventArgs e)
{
// 过滤掉不是 excel 的文件
if (e.Name.StartsWith("~") || !e.Name.EndsWith(".xlsx"))
{
return;
}
Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.Write($"[{DateTime.Now}] ");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"Update: {e.Name}");
Console.ResetColor();
// do something ...
}
}