XLS 电子表格 C# 的查询字符串选择
Query string selections for XLS spreadsheet C#
我正在尝试获取 XLS 电子表格中的单元格,将它们分配给字符串数组,然后处理数据并导出到多个 CVS 文件。
问题是 XLS 电子表格包含不相关的信息,可用数据直到第 17 行才开始,列没有标题,只有默认的 Sheet1。
我查看了相关问题并尝试自己解决,但没有成功。以下读取 XLS 的代码有点管用,但使用起来很麻烦,因为行长度因一个 XLS 文件而异,并且它会自动拉空列和行。
代码
public static void xlsReader()
{
string fileName = string.Format("{0}\LoadsAvailable.xls", Directory.GetCurrentDirectory());
string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";" + @"Extended Properties='Excel 8.0;HDR=Yes;'";
string queryString = "SELECT * FROM [Sheet1$]";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbCommand command = new OleDbCommand(queryString, connection);
connection.Open();
OleDbDataReader reader = command.ExecuteReader();
int counter = 0;
while (reader.Read())
{
Console.WriteLine("Line " + counter + ":" + reader[28].ToString()); // Just for testing
counter++;
}
}
}
我可以用循环做一堆诡计来获取所需的数据,但必须有一个查询字符串才能从第 17 行获取只有 8 列的数据(而不是 26 列,其中 18 列为空)?
我已经尝试了很多查询字符串示例,但无法结合使用起始行索引或过滤掉空数据。
这是将 excel 文件转换为平面文件的简便方法。
您可能想要更改连接字符串属性以满足您的需要。我的情况需要 headers。
请注意,您需要在计算机上安装 Access 数据库引擎。我需要 32 位版本,因为我开发的应用程序是 32 位的。我打赌你也会需要它。
我参数化了平面文件的分隔符,因为在某些情况下我不需要逗号而是管道符号。
如何调用方法 ex: ConvertExcelToFlatFile(openFileName, savePath, '|'); // pipe delimited
// Converts Excel To Flat file
private void ConvertExcelToFlatFile(string excelFilePath, string csvOutputFile, char delimeter, int worksheetNumber = 1)
{
if (!File.Exists(excelFilePath)) throw new FileNotFoundException(excelFilePath);
if (File.Exists(csvOutputFile)) throw new ArgumentException("File exists: " + csvOutputFile);
// connection string
var cnnStr = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml; IMEX=1; HDR=NO\"", excelFilePath);
var cnn = new OleDbConnection(cnnStr);
// get schema, then data
var dt = new DataTable();
try
{
cnn.Open();
var schemaTable = cnn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (schemaTable.Rows.Count < worksheetNumber) throw new ArgumentException("The worksheet number provided cannot be found in the spreadsheet");
string worksheet = schemaTable.Rows[worksheetNumber - 1]["table_name"].ToString().Replace("'", "");
string sql = String.Format("select * from [{0}]", worksheet);
var da = new OleDbDataAdapter(sql, cnn);
da.Fill(dt);
}
catch (Exception e)
{
throw e;
}
finally
{
// free resources
cnn.Close();
}
// write out CSV data
using (var wtr = new StreamWriter(csvOutputFile)) // disposes file handle when done
{
foreach (DataRow row in dt.Rows)
{
//MessageBox.Show(row.ItemArray.ToString());
bool firstLine = true;
foreach (DataColumn col in dt.Columns)
{
// skip the first line the initial
if (!firstLine)
{
wtr.Write(delimeter);
}
else
{
firstLine = false;
}
var data = row[col.ColumnName].ToString();//.Replace("\"", "\"\""); // replace " with ""
wtr.Write(String.Format("{0}", data));
}
wtr.WriteLine();
}
}
}
我正在尝试获取 XLS 电子表格中的单元格,将它们分配给字符串数组,然后处理数据并导出到多个 CVS 文件。
问题是 XLS 电子表格包含不相关的信息,可用数据直到第 17 行才开始,列没有标题,只有默认的 Sheet1。
我查看了相关问题并尝试自己解决,但没有成功。以下读取 XLS 的代码有点管用,但使用起来很麻烦,因为行长度因一个 XLS 文件而异,并且它会自动拉空列和行。
代码
public static void xlsReader()
{
string fileName = string.Format("{0}\LoadsAvailable.xls", Directory.GetCurrentDirectory());
string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";" + @"Extended Properties='Excel 8.0;HDR=Yes;'";
string queryString = "SELECT * FROM [Sheet1$]";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbCommand command = new OleDbCommand(queryString, connection);
connection.Open();
OleDbDataReader reader = command.ExecuteReader();
int counter = 0;
while (reader.Read())
{
Console.WriteLine("Line " + counter + ":" + reader[28].ToString()); // Just for testing
counter++;
}
}
}
我可以用循环做一堆诡计来获取所需的数据,但必须有一个查询字符串才能从第 17 行获取只有 8 列的数据(而不是 26 列,其中 18 列为空)?
我已经尝试了很多查询字符串示例,但无法结合使用起始行索引或过滤掉空数据。
这是将 excel 文件转换为平面文件的简便方法。
您可能想要更改连接字符串属性以满足您的需要。我的情况需要 headers。
请注意,您需要在计算机上安装 Access 数据库引擎。我需要 32 位版本,因为我开发的应用程序是 32 位的。我打赌你也会需要它。
我参数化了平面文件的分隔符,因为在某些情况下我不需要逗号而是管道符号。
如何调用方法 ex: ConvertExcelToFlatFile(openFileName, savePath, '|'); // pipe delimited
// Converts Excel To Flat file
private void ConvertExcelToFlatFile(string excelFilePath, string csvOutputFile, char delimeter, int worksheetNumber = 1)
{
if (!File.Exists(excelFilePath)) throw new FileNotFoundException(excelFilePath);
if (File.Exists(csvOutputFile)) throw new ArgumentException("File exists: " + csvOutputFile);
// connection string
var cnnStr = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml; IMEX=1; HDR=NO\"", excelFilePath);
var cnn = new OleDbConnection(cnnStr);
// get schema, then data
var dt = new DataTable();
try
{
cnn.Open();
var schemaTable = cnn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (schemaTable.Rows.Count < worksheetNumber) throw new ArgumentException("The worksheet number provided cannot be found in the spreadsheet");
string worksheet = schemaTable.Rows[worksheetNumber - 1]["table_name"].ToString().Replace("'", "");
string sql = String.Format("select * from [{0}]", worksheet);
var da = new OleDbDataAdapter(sql, cnn);
da.Fill(dt);
}
catch (Exception e)
{
throw e;
}
finally
{
// free resources
cnn.Close();
}
// write out CSV data
using (var wtr = new StreamWriter(csvOutputFile)) // disposes file handle when done
{
foreach (DataRow row in dt.Rows)
{
//MessageBox.Show(row.ItemArray.ToString());
bool firstLine = true;
foreach (DataColumn col in dt.Columns)
{
// skip the first line the initial
if (!firstLine)
{
wtr.Write(delimeter);
}
else
{
firstLine = false;
}
var data = row[col.ColumnName].ToString();//.Replace("\"", "\"\""); // replace " with ""
wtr.Write(String.Format("{0}", data));
}
wtr.WriteLine();
}
}
}