C# excel 文件读写
环境配置及入门
在使用c#读写excel文件时踩了不少坑,首先使用的是Microsoft.Office.Interop.Excel;
vs中没有的话,可以直接在Nuget中安装,搜索Excel找到Interop安装下载量最高的就可以,在初次运行时,一直报
QueryInterface 因以下错误而失败: 库没有注册。 (异常来自 HRESULT:0x8002801D (TYPE_E_LIBNOTREGISTERED)
这样的错误,网路上有不少人说是安装了新版本再回退到旧版本office导致的,但我只装过一个office16,在对应的注册表修改项中也没有找到对应其他版本,只有一个1.9的,我删了也没有作用(删除前最好备份注册表,以便回滚), 试了一圈,最后发现是wps的问题,需要安装wps(你没听错,是wps),再运行vs 程序就不报错了,后面再把wps删了,最好用win自带的删除功能删除,之后就一直都可以了
在之后我把excel的功能封装起来,如下
public class Excel_Control
{
/// <summary>
/// 简单操作Excel文件
/// </summary>
/// <param name="excelPath">excel 文件路径</param>
/// <returns></returns>
public static List<List<string>> ExcelOp(string excelPath)
{
string ExcelFilePath = excelPath.Trim();
List<List<string>> excel_list = new List<List<string>>();
//set columns
Excel.Application excel = new Excel.Application();
Excel.Workbook wb = null;
excel.Visible = false;//设置调用引用的 Excel文件是否可见
excel.DisplayAlerts = false;
wb = excel.Workbooks.Open(ExcelFilePath);
Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets[1]; //索引从1开始 //(Excel.Worksheet)wb.Worksheets["SheetName"];
int rowCount = 0;//有效行,索引从1开始
try
{
rowCount = ws.UsedRange.Rows.Count;//赋值有效行
for (int i = 2; i <= rowCount; i++)//从第二行开始读取,需要的可以设为1
{
List<string> data = new List<string>();
if (ws.Rows[i] != null)
{
for (int j = 1; j <= ws.UsedRange.Columns.Count; j++)
{
data.Add(ws.Cells[i, j].Value2.ToString());//获取每一单元格的数据
}
}
excel_list.Add(data);
}
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
finally
{
ClosePro(excelPath, excel, wb);
}
return excel_list;//返回读取的数据
}
/// <summary>
/// 关闭Excel进程
/// </summary>
/// <param name="excelPath"></param>
/// <param name="excel"></param>
/// <param name="wb"></param>
public static void ClosePro(string excelPath, Excel.Application excel, Excel.Workbook wb)
{
Process[] localByNameApp = Process.GetProcessesByName(excelPath);//获取程序名的所有进程
if (localByNameApp.Length > 0)
{
foreach (var app in localByNameApp)
{
if (!app.HasExited)
{
#region
设置禁止弹出保存和覆盖的询问提示框
//excel.DisplayAlerts = false;
//excel.AlertBeforeOverwriting = false;
保存工作簿
//excel.Application.Workbooks.Add(true).Save();
保存excel文件
//excel.Save("D:" + "\\test.xls");
确保Excel进程关闭
//excel.Quit();
//excel = null;
#endregion
app.Kill();//关闭进程
}
}
}
if (wb != null)
wb.Close(true, Type.Missing, Type.Missing);
excel.Quit();
// 安全回收进程
System.GC.GetGeneration(excel);
}
}
参考
(已解决)Win10+Office2016报错:库没有注册,HRESULT:0x8002801D
C#读写Excel的几种方法
C# 使用自带Microsoft.Office.Interop.Excel简单操作Excel文件
遇到的其他问题
使用Interop.excel读写文件,在读取时间时遇到问题,表格时间数据在默认显示时是正常的,但如果切换成文本,则会变成一串整型数据,发现对于这类数据,要使用转换类进行转换,可以使用datatime.TryParse来直接转化,或者使用DateTime.FromOADate(ws.Cells[i, j].Value2)
,效果都是一样的。后者最好标记好要转化的数据在表格的位置,此外,在另存时要记得设置保存格式,特别是对应xls文件时,最后别忘了关闭打开的应用句柄
public class Excel_Control
{
private const int OLDOFFICEVESION = -4143;
private const int NEWOFFICEVESION = 56;
/// <summary>
/// 读取Excel文件
/// </summary>
/// <param name="excelPath">excel 文件路径</param>
/// <param name="datatime_indexs">时间格的位置</param>
/// <returns></returns>
public static List<List<string>> ExcelOp(string excelPath, List<int> datatime_indexs = null)
{
string ExcelFilePath = excelPath.Trim();
List<List<string>> excel_list = new List<List<string>>();
//set columns
Excel.Application excel = new Excel.Application();
Excel.Workbook wb = null;
excel.Visible = false;//设置调用引用的 Excel文件是否可见
excel.DisplayAlerts = false;
wb = excel.Workbooks.Open(ExcelFilePath);
Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets[1]; //索引从1开始 //(Excel.Worksheet)wb.Worksheets["SheetName"];
int rowCount = 0;//有效行,索引从1开始
try
{
rowCount = ws.UsedRange.Rows.Count;//赋值有效行
for (int i = 2; i <= rowCount; i++)//从第二行开始读取,需要的可以设为1
{
List<string> data = new List<string>();
if (ws.Rows[i] != null)
{
for (int j = 1; j <= ws.UsedRange.Columns.Count; j++)
{
if (datatime_indexs != null && datatime_indexs.Contains(j))
{
data.Add(DateTime.FromOADate(ws.Cells[i, j].Value2).ToString());//获取转换后的时间数据
}
else
data.Add(ws.Cells[i, j].Value2.ToString());//获取每一单元格的数据
}
}
excel_list.Add(data);
}
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
finally
{
ClosePro(excelPath, excel, wb);
}
return excel_list;//返回读取的数据
}
/// <summary>
/// 写入excel
/// </summary>
/// <param name="excelPath">excel保存文件路径,不用填写后缀</param>
/// <returns></returns>
public static void WriteExcel(string filePath, List<List<string>> datas)
{
//保存excel文件的格式
int FormatNum;
//excel版本号
string Version;
List<List<string>> excel_list = new List<List<string>>();
//set columns
Excel.Application excel = new Excel.Application();//启动应用
Excel.Workbooks workbooks = excel.Workbooks;//创建文件
Excel.Workbook workbook = workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);//添加表模板
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets[1];//添加表一
excel.Visible = false;//设置调用引用的 Excel文件是否可见
excel.DisplayAlerts = false;
//获取你使用的excel 的版本号
Version = excel.Version;
//使用Excel 97-2003
if (Convert.ToDouble(Version) < 12)
{
FormatNum = OLDOFFICEVESION;
}
//使用 excel 2007或更新
else
{
FormatNum = NEWOFFICEVESION;
}
int row = 1;
foreach (var data in datas)
{
int i = 1;
foreach (var d in data)
{
worksheet.Cells[row, i++] = d;
}
row++;
}
if (File.Exists(filePath))//删除已经存在的文件
{
try
{
File.Delete(filePath);
}
catch (IOException e)
{
Console.WriteLine(e.Message);
}
}
//保存,这里必须指定FormatNum文件的格式,否则无法打开创建的excel文件
workbook.SaveAs(filePath, FormatNum);
ClosePro(filePath, excel, workbook);
}
/// <summary>
/// 关闭Excel进程
/// </summary>
/// <param name="excelPath"></param>
/// <param name="excel"></param>
/// <param name="wb"></param>
public static void ClosePro(string excelPath, Excel.Application excel, Excel.Workbook wb)
{
Process[] localByNameApp = Process.GetProcessesByName(excelPath);//获取程序名的所有进程
if (localByNameApp.Length > 0)
{
foreach (var app in localByNameApp)
{
if (!app.HasExited)
{
#region
设置禁止弹出保存和覆盖的询问提示框
//excel.DisplayAlerts = false;
//excel.AlertBeforeOverwriting = false;
保存工作簿
//excel.Application.Workbooks.Add(true).Save();
保存excel文件
//excel.Save("D:" + "\\test.xls");
确保Excel进程关闭
//excel.Quit();
//excel = null;
#endregion
app.Kill();//关闭进程
}
}
}
if (wb != null)
wb.Close(true, Type.Missing, Type.Missing);
excel.Quit();
// 安全回收进程
System.GC.GetGeneration(excel);
}
}
参考
C# Microsoft.Office.Interop.Excel读取excel中的日期问题
C#利用Microsoft.Office.Interop.Excel导出excel文件
C# 打开和保存文件对话框