110,545
社区成员
发帖
与我相关
我的任务
分享
using Excel = Microsoft.Office.Interop.Excel;
public Excel.Application StartExcel()
{
Excel.Application instance = null;
try
{
instance = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
}
catch (System.Runtime.InteropServices.COMException ex)
{
instance = new Excel.ApplicationClass();
}
return instance;
}
可以直接从系统中获取已存在的 excel 实例,应该可以解决文件被独占访问的问题。
第二步,判断文件是否已打开
var xls = StartExcel();
foreach (Excel.Workbook wb in xls.Workbooks)
{
if(wb.Path == path) // 文件是否打开判断
}
第三步,利用二维数组映射数据,快速读取
object[,] arr = (object[,])sh.UsedRange.Value;
测试:
文件包含一张表 7 个字段,2542 行数据
关闭状态用时 < 300 ms
打开状态用时 < 50 ms
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;
// 获取系统中已存在的 Excel Application 实例
public Excel.Application GetInstance()
{
Excel.Application instance = null;
try
{
instance = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
}
catch (System.Runtime.InteropServices.COMException ex)
{
Console.WriteLine(ex.Message);
instance = new Excel.Application();
}
return instance;
}
private void meOnClick(object sender, RoutedEventArgs e)
{
Stopwatch sw = new Stopwatch(); // 启动一个计时器
sw.Start();
Excel.Application xls = GetInstance(); // 获取 Excel 实例
Excel.Workbook wb = null;
Excel.Worksheet sh;
bool openByMe = false; // 用于标识是否是自己的程序打开的文件
// 程序目录中放了一个测试用的 xlsx
// 表中有 7 个字段 2542 行数据
string path = System.IO.Path.GetFullPath("test.xlsx");
foreach (Excel.Workbook item in xls.Workbooks)
{
// 通过路径判断文件是否已被打开
if (item.FullName == path)
{
wb = item;
break;
}
}
if (wb == null) // 判断文件是否已打开
{
try
{
wb = xls.Workbooks.Open(path, ReadOnly: true); // 已只读方式打开文件
openByMe = true; // 是自己的程序打开的
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
if (wb == null)
return;
sh = (Excel.Worksheet)wb.Sheets["systems"]; // 获取目标 Worksheet
object[,] arr = (object[,])sh.UsedRange.Value; // 以最快的方式获取数据
if (openByMe) // 判断标识
{
wb.Close(SaveChanges: false); // 关闭文件
xls.Quit(); // 退出 Excel
sh = null;
wb = null;
xls = null;
}
Console.WriteLine("{0}", sw.Elapsed.TotalMilliseconds);
if (arr == null) // 判断是否获取了数据
return;
var sb = new StringBuilder();
// 将数组数据植入 StringBuilder
for (int i = arr.GetLowerBound(0); i <= arr.GetUpperBound(0); i++)
{
for (int j = arr.GetLowerBound(1); j <= arr.GetUpperBound(1); j++)
{
if (j == arr.GetLowerBound(1))
{
sb.AppendFormat("{0}", arr[i, j]); // 首个字段直接写值
}
else
{
sb.AppendFormat("\t{0}", arr[i, j]); // 非首字段写\t+值
}
}
sb.AppendLine(); // 写入回车
}
// 获取一个 cache.csv 文件路径,该文件位于当前应用程序目录
string path = System.IO.Path.GetFullPath("cache.csv");
System.IO.File.WriteAllText(path, sb.ToString(), Encoding.Default); // 写入数据
sw.Stop();
Console.WriteLine("{0}", sw.Elapsed.TotalMilliseconds);
}