C#中如何在Excel打开编辑时读取XLSX文件?
解决C#读取被Excel占用文件的问题
可行方案
1. 用FileStream指定共享权限打开文件
Excel打开文件时并非完全独占,允许其他进程以共享模式访问。通过FileStream的FileShare.ReadWrite参数,可绕过占用限制直接读取文件。示例代码(以EPPlus库为例):
using (var stream = new FileStream("xxxx.xlsx", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (var excelPackage = new ExcelPackage(stream)) { var worksheet = excelPackage.Workbook.Worksheets.First(); // 执行数据读取逻辑,例如读取单元格值 string cellValue = worksheet.Cells[1, 1].Text; } }
注意:避免使用File.ReadAllBytes、File.ReadAllText这类默认独占访问的方法;如果仍使用OLEDB读取,可能不支持该共享模式,建议替换为EPPlus、NPOI等基于流的Excel处理库。
2. 读取Excel临时文件
Excel编辑文件时,会在同目录生成一个以~$开头的隐藏临时文件,该文件同步保存当前编辑内容。可直接读取此临时文件:
string originalPath = "xxxx.xlsx"; string tempFilePath = Path.Combine(Path.GetDirectoryName(originalPath), $"~${Path.GetFileName(originalPath)}"); if (File.Exists(tempFilePath)) { using (var stream = new FileStream(tempFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { // 用Excel处理库读取流内容 } }
局限性:临时文件为隐藏属性,需确保程序有读取权限;部分Excel版本或环境下可能不生成该临时文件,路径也可能存在差异。
3. 缓存数据+监控文件变化
若无需实时获取最新编辑内容,可首次读取后缓存数据,再通过FileSystemWatcher监控文件修改事件,仅当文件变化时重新读取更新缓存,避免频繁打开文件:
private static readonly object _cacheLock = new object(); private static DataTable _excelDataCache; public void SetupFileMonitor(string filePath) { var watcher = new FileSystemWatcher(Path.GetDirectoryName(filePath), Path.GetFileName(filePath)) { NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size, EnableRaisingEvents = true }; // 文件修改时更新缓存 watcher.Changed += (sender, e) => { lock (_cacheLock) { _excelDataCache = ReadExcelToDataTable(e.FullPath); } }; // 初始化缓存 _excelDataCache = ReadExcelToDataTable(filePath); } private DataTable ReadExcelToDataTable(string filePath) { var dt = new DataTable(); using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (var package = new ExcelPackage(stream)) { var worksheet = package.Workbook.Worksheets.First(); // 填充DataTable逻辑,此处省略具体实现 } } return dt; }
后续业务逻辑直接读取_excelDataCache即可,无需重复打开文件。
内容的提问来源于stack exchange,提问作者lyj
相关产品推荐
相关产品推荐

