【发布时间】:2014-09-19 17:04:19
【问题描述】:
我们有一个应用程序,它使用 Microsoft Access 数据库引擎从 Excel xlsx 文件中读取数据。 xlsx 文件由第三方软件生成。该应用程序多年来一直运行良好。
生成 xlsx 文件的公司修改了他们的软件,导致 xlsx 文件的格式发生了变化。我们的应用程序无法再读取这些文件。 但是,如果我使用 Excel 手动打开其中一个文件,然后立即单击“保存”,则新文件可以正常工作。
第三方的回复基本上是“既然你可以用Excel打开文件,那就说明它是一个有效的xlsx文件。问题一定出在你自己身上”。他们确实有道理。
我已在https://drive.google.com/file/d/0B6jNYMkptFteTmc4YU9BWU1PRUk/edit?usp=sharing 发布了其中一个 xlsx 文件的示例
这是一个重现问题的简单测试程序(VisualStudio.net 中的控制台应用程序)。
static void Main(string[] args)
{
String fileSpec = @"C:\Temp\TestData-Original.xlsx";
String connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileSpec + ";Extended Properties=\"Excel 12.0;HDR=No;IMEX=1\"";
DataTable dtExcelRecords = null;
OleDbConnection con = new OleDbConnection(connectionString);
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = con;
OleDbDataAdapter dAdapter = new OleDbDataAdapter(cmd);
try
{
con.Open(); // Throws exception here.
DataTable dtExcelSheetNames = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
String sheetName = (dtExcelSheetNames.Rows[0]["Table_Name"].ToString()).Replace("''", "'");
if (!(String.IsNullOrEmpty(sheetName)))
{
cmd.CommandText = "SELECT * FROM [" + sheetName + "]";
dtExcelRecords = new DataTable();
dAdapter.SelectCommand = cmd;
dAdapter.Fill(dtExcelRecords);
}
con.Close();
Console.WriteLine(String.Format("Found {0} records in file {1}", dtExcelRecords.Rows.Count, fileSpec));
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
finally
{
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
如果您使用示例 Excel 文件运行此程序,它将失败。 如果您在 Excel 中打开示例文件,然后单击“保存”,然后运行程序,它将成功读取文件。
测试程序做了 2 个假设:(1) xlsx 文件位于 C:\Temp\TestData-Original.xlsx 和 (2) Microsoft Access 数据库引擎已安装在您的计算机上。
我对此进行了研究,但没有运气。大多数讨论都围绕更改连接字符串以指定不同版本的 Excel 展开。到目前为止没有任何改变。
注意:我注意到当我使用 Excel 打开文件然后保存时,大小增加了大约 70%。
有什么想法吗?
【问题讨论】:
-
If you run this program with the sample Excel file, it will fail.怎么会失败?它有例外吗?如果是这样,它是什么?它说什么?如果您在调试器中单步执行代码会发生什么? -
第三方能否为您提供所使用的确切文件格式?可以想象,“Excel 文件”有点模糊。 Excel 可以打开纯文本文件,但这很难证明纯文本是有效的 xlsx 文件。如果您在纯文本编辑器中打开前后文件,它们是否有一些指定格式信息的内部 XML?
-
您是否对文件进行了前后比较?从理论上讲,如果您不在 excel 中执行任何操作并再次将其保存,则文件应该只有非常小的更改(例如更新总编辑时间、最后编辑时间等...计数器)。比较它们,看看发生了什么。
-
@MarcB:实际上,根据文件的生成方式,差异可能相当大。一个简单的示例是,您可以将字符串直接放入 XLSX 文件的单元格中,也可以使用字符串表。当您在 Excel 中打开文件并再次保存时,Excel 很可能会为您提取那些内联字符串并将它们放入字符串表中。
-
另外注意,
.xlsx文件只是.zip文件。您可以将扩展名更改为zip并解压缩它们。这样做并比较里面的各种(主要是xml)文件可能很有用。
标签: c# excel xls file-format