您的位置:首页 > 编程语言 > C#

C#以OleDb的方式操作Excel文件(三)

2014-09-03 11:59 711 查看

二、写Excel文件

前面讲了读Excel文件,后面就该写了。

其实写的基本过程也是类似的,设置连接字符串->打开文件->写文件->关闭文件。

打开可写文件的连接字符串:

string strConn;

strConn = @"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source="
+ fileName
+ @";Extended Properties='Excel 8.0;IMEX=0'";


和之前贴出来的读文件的连接字符串比较一下:

strConn = @"Provider=Microsoft.ACE.OLEDB.12.0;

                      Data Source="

                      + fileName

                      + @";Extended Properties=‘Excel 12.0; HDR=YES; IMEX=1;’";

差别我用红笔标注出来。为什么会有这样的差异?

如果查找一些资料的话,会找到这样的说法:

(Copy from http://blog.csdn.net/testcs_dn/article/details/25496155)
参数Excel 8.0 对于Excel
97以上到2003版本都用Excel 8.0,2007或2010的都用Extended Properties=Excel 12.0

IMEX ( IMport EXport mode )设置
  IMEX 有三种模式:
  0 is Export mode
  1 is Import mode
  2 is Linked mode (full update capabilities)
  我这里特别要说明的就是 IMEX 参数了,因为不同的模式代表著不同的读写行为:
  当 IMEX=0 时为“汇出模式”,这个模式开启的 Excel 档案只能用来做“写入”用途。
  当 IMEX=1 时为“汇入模式”,这个模式开启的 Excel 档案只能用来做“读取”用途。
  当 IMEX=2 时为“连結模式”,这个模式开启的 Excel 档案可同时支援“读取”与“写入”用途。
意义如下:
0 ---输出模式;
1---输入模式;
2----链接模式(完全更新能力)

经过我的实际测试,得到的结果是这样的:
Provider=Microsoft.Jet.OLEDB.4.0; 配上IMEX=2是可读写,但是已打开的文件不能修改。就是说,如果这个我要写入的文件已经被Excel程序打开,则我的程序就不能对这个文件进行写操作了;
Provider=Microsoft.ACE.OLEDB.12.0;配上IMEX=0可以写,而且已打开的文件可以修改。我曾经一边用Excel打开我要写入的文件,一边执行写入的程序,可以看到Excel中显示的文件变化(比如我先把工作表删除了,再写入数据,那么就可以看到Excel中先清空后写入数据的变化)。
还有一个我在实际使用中发现的问题就是,读Excel文件时,Extended Properties='Excel 12.0;'没有发现什么异常;但是写Excel文件时,如果设置Extended Properties='Excel 12.0;',那么这个文件在用Excel打开时,会提示:



选择“是”的话还是可以打开文件,并且看到文件内容。
而如果写文件连接字符串中,设置Extended Properties='Excel 8.0;‘,写入后的文件用Excel打开就不会提示这个了。
在网上想找到这个问题的原因,似乎是因为格式与扩展名不符,但我也试过扩展名写成xlsx,并没有解决这个问题。所以我现在写文件就使用8.0了。
这些设置到底该如何设,它们互相之间有什么关系,在MSDN中估计是有详细说明的,有兴趣的人可以查查,教教我,非常感谢!
比较完整的写Excel文件的代码如下:

using System;
using System.IO;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Windows.Forms;

namespace TestXL
{
public class Class1
{
public Class1()
{
}

/// <summary>
/// 测试连接的excel文件中,某个表(sheet)是否存在
/// </summary>
/// <param name="conn">已打开的excel连接</param>
/// <param name="sheetName">要求查找的sheet名称</param>
/// <returns>
/// 返回bool
/// true —— 该表已存在;false —— 该表不存在
/// </returns>
private bool IfSheetExist(OleDbConnection conn, string sheetName)
{
// 获得excel文件的各个表单(sheet)的名字
DataTable xlsTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,
new object[] { null, null, null, "TABLE" });

bool sheetExist = false;
foreach (DataRow sheetRow in xlsTable.Rows)
{
if (sheetRow["TABLE_NAME"].ToString() == sheetName)
{
sheetExist = true;
break;
}
}

return sheetExist;
}

/// <summary>
/// 保存未匹配的数据到EXCEL文件,用OLEDB的方式
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
private bool SaveToExcel(string fileName)
{
OleDbConnection conn = new OleDbConnection();
try
{

string strConn;

// 注意连接串的写法
strConn = @"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source="
+ fileName
+ @";Extended Properties='Excel 8.0;IMEX=0'";

conn = new OleDbConnection(strConn);

conn.Open();
}
catch (Exception ex)
{
MessageBox.Show("无法打开写入文件,错误:" + ex.Message);
}

try
{
OleDbCommand cmd = new OleDbCommand();
string sheetName = "人员";
if (IfSheetExist(conn, sheetName))
{
// 该工作表已存在,则删除之
string sqlDelete = @"DROP TABLE " + sheetName + ";";
cmd = new OleDbCommand(sqlDelete, conn);
// 删除已存在的工作表
cmd.ExecuteNonQuery();
}

// 创建工作表
string sqlCreate = @"CREATE TABLE "
+ sheetName
+ @" ([员工姓名] VarChar, [员工编号] VarChar)";
cmd = new OleDbCommand(sqlCreate, conn);

// 创建工作表
cmd.ExecuteNonQuery();

// 添加数据
// addPersonList是要写到Excel中的人员数据列表
foreach (PersonData person in addPersonList)
{
if (!person.matched)
{
// 一条一条地加,不知道是否有快的办法?
cmd.CommandText = @"INSERT INTO "
+ sheetName
+ " VALUES ('"
+ person.name
+ "', '"
+ person.sn
+ "');";
cmd.ExecuteNonQuery();
}
}

// 关闭数据库
conn.Close();

string displayInfo = "导出人员到\n“" + fileName + "”\n完成!";
MessageBox.Show(displayInfo, "提示信息",
MessageBoxButtons.OK, MessageBoxIcon.Information);

}
catch (Exception ex)
{
MessageBox.Show("写入文件错误:" + ex.Message);
conn.Close();
return false;
}

return true;
}
}
}


 

好,到此为止,这些天我了解的东西就这样了:)

 

在学习期间,我找到的一些比较好的介绍文章包括:

1、C#操作Excel(创建、打开、读写、保存)几种方法的总结

http://www.cnblogs.com/SunYu/archive/2010/04/27/1722471.html

这里面有作者自己的理解,有搜集到的网络资源

2、HOW TO:使用 GetOleDbSchemaTable 和 Visual C# .NET 检索架构信息

http://support.microsoft.com/kb/309681/zh-cn

3、如何使用 Visual C# 2005 或 Visual C# .NET 向 Excel 工作簿传输数据

http://support.microsoft.com/kb/306023/zh-cn
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: