我想使用OLEDB更新Excel(xlsx)文件中的1个单元格。 我附上了我的代码。 第一次运行时,它会填充值,因为INSERT正在运行。 第二次运行时,它会附加值,因为UPDATE失败,我的Catch执行INSERT。我的目标是让UPDATE命令工作。执行UPDATE命令时,出现错误消息:
没有给出一个或多个必需参数的值。 在System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr) 在System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams,Object& executeResult) 在System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult) 在System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior,Object& executeResult) 在System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior,String method) 在System.Data.OleDb.OleDbCommand.ExecuteNonQuery() 在ConsoleApp3.Program.InsertCSVIntoSheet(String excelPath,String sheet,String csvPath)中的C:\ Users \ jbendler.atlab \ source \ repos \ ConsoleApp3 \ Program.cs:第175行
此代码来自演示控制台应用程序。这是program.cs文件。 代码的主要部分位于InsertCSVIntoSheet方法的底部。输出xlsx文件只是一个未编辑的新工作簿。输入文件只是一个文本文件,以.csv扩展名命名,包含以下由car-return / linefeed分隔的内容 - 因此文件有5行,每行一个字符:
感谢。
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
InsertCSVIntoSheet(@"c:\temp\book1.xlsx", "NewSheet", @"c:\temp\test.csv");
}
private static void InsertCSVIntoSheet(string excelPath, string sheet, string csvPath)
{
int column;
int row;
int pos;
bool done;
char readUntilChar;
string csvData;
string columnName;
string cell;
string excelSheetName;
List<Tuple<int, int, object>> values = new List<Tuple<int, int, object>>();
string connectionString = CreateOleDbConnectionStringForExcel(excelPath);
OleDbCommand oleDbCommand = new OleDbCommand();
decimal decimalTest;
DateTime dateTimeTest;
int status;
int numColumns;
// Put CSV in to row/column/value Tuples
using (StreamReader reader = new StreamReader(csvPath))
{
csvData = reader.ReadToEnd();
row = 1;
// Split the csv data by new line
foreach (string line in csvData.Split(new string[] { "\r\n" }, StringSplitOptions.None))
{
if (!string.IsNullOrEmpty(line))
{
column = 1;
pos = 0;
cell = string.Empty;
// Split each line by ',' to get each cell. A value wrapped in '"' can include a ','
while (pos < line.Length)
{
cell = string.Empty;
// Check the first character. If it is a '"' then we assume the cell is surrounded
// in '"' and do NOT include the '"' in the output to the excel cell.
if (line[pos] == '"')
{
readUntilChar = '"';
pos++;
}
else
{
readUntilChar = ',';
}
done = line[pos] == readUntilChar;
if (line[pos] == '"')
{
// Skip over second '"' for a blank ("")
pos++;
}
while (!done)
{
cell += line[pos++];
if (pos == line.Length || line[pos] == readUntilChar)
{
if (readUntilChar == '"')
{
// Skip the '"'
pos++;
}
done = true;
}
}
// Skip over the ','
pos++;
if (!string.IsNullOrEmpty(cell))
{
// Test the data to determine the type (check for decimal and DateTime).
if (decimal.TryParse(cell, out decimalTest))
{
values.Add(new Tuple<int, int, object>(row, column, decimalTest));
}
else if (DateTime.TryParse(cell, out dateTimeTest))
{
values.Add(new Tuple<int, int, object>(row, column, dateTimeTest));
}
else
{
// Write out the value as a string
values.Add(new Tuple<int, int, object>(row, column, cell));
}
}
column++;
}
}
row++;
}
}
using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress))
{
excelSheetName = GetExcelSheetNames(connectionString).Where(n => n.ToUpper().StartsWith(sheet.ToUpper())).FirstOrDefault();
//Set the connection string to recognize the header and to operate in Update mode(IMEX= 0)
using (OleDbConnection oleDbConnection = new OleDbConnection(connectionString.Replace("IMEX=1", "IMEX=0")))
{
oleDbConnection.Open();
oleDbCommand = new OleDbCommand();
oleDbCommand.Connection = oleDbConnection;
oleDbCommand.CommandType = CommandType.Text;
if (excelSheetName != null)
{
// Delete Sheet
oleDbCommand.CommandText = "DROP TABLE [" + sheet + "]";
status = oleDbCommand.ExecuteNonQuery();
}
else
{
excelSheetName = sheet + "$";
}
numColumns = values.Max(v => v.Item2);
oleDbCommand.CommandText = "CREATE TABLE [" + sheet + "](";
for (int index = 0; index < numColumns; index++)
{
oleDbCommand.CommandText += "Column" + index.ToString() + " CHAR(255), ";
}
oleDbCommand.CommandText = oleDbCommand.CommandText.Substring(0, oleDbCommand.CommandText.Length - 2) + ")";
status = oleDbCommand.ExecuteNonQuery();
}
using (OleDbConnection oleDbConnection = new OleDbConnection(connectionString.Replace("IMEX=1", "IMEX=0")))
{
oleDbConnection.Open();
oleDbCommand.Connection = oleDbConnection;
// Write out new values
foreach (Tuple<int, int, object> tuple in values)
{
try
{
columnName = GetExcelColumnName(tuple.Item2) + (tuple.Item1 + 1).ToString();
oleDbCommand.CommandText = "UPDATE [" + excelSheetName + columnName + ":" + columnName + "] SET " + "F1" + " = '" + tuple.Item3.ToString() + "'";
status = oleDbCommand.ExecuteNonQuery();
}
catch (OleDbException oledbex)
{
oleDbCommand.CommandText = "INSERT INTO [" + excelSheetName + "] VALUES ('" + tuple.Item3.ToString() + "')";
status = oleDbCommand.ExecuteNonQuery();
}
}
}
}
}
private static List<string> GetExcelSheetNames(string connectionString)
{
OleDbConnection oleDbConnection = null;
DataTable dataTable = null;
List<string> excelSheetNames = null;
using (oleDbConnection = new OleDbConnection(connectionString))
{
oleDbConnection.Open();
dataTable = oleDbConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
}
if (dataTable != null)
{
excelSheetNames = new List<string>(dataTable.Rows.Cast<DataRow>().Where(r => r["TABLE_NAME"].ToString().EndsWith("$") || r["TABLE_NAME"].ToString().EndsWith("$'")).Select(r => r["TABLE_NAME"].ToString().ToUpper()));
}
return excelSheetNames;
}
private static string CreateOleDbConnectionStringForExcel(string sourceFile)
{
var fileInfo = new FileInfo(sourceFile);
switch (fileInfo.Extension.ToUpper())
{
case ".XLS":
return string.Format("Provider=Microsoft.ACE.OLEDB.12.0;;Data Source='{0}';Extended Properties='Excel 8.0;HDR=No;IMEX=1'", sourceFile);
case ".XLSX":
case ".XLSM":
return string.Format("Provider=Microsoft.ACE.OLEDB.12.0;;Data Source='{0}';Extended Properties='Excel 12.0;HDR=No;IMEX=1'", sourceFile);
default:
throw new NotSupportedException("File type not supported.");
}
}
private static string GetExcelColumnName(int columnNumber)
{
string columnName = String.Empty;
int dividend = columnNumber;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
return columnName;
}
}
}