My task is to take an Access Database and create an Excel file, but I can not seem to CREATE the Excel file that OleDb will use.
The Excel file name will be provided by the Engineer running the tool. Each Data Table in the Access Database will become a WorkSheet in the Excel file.
Right now, I have one hurtle I can not get over: If the Excel file does not exist, I cannot create it!
internal const string XL_FMT = "Provider=Microsoft.{0}.OLEDB.{1};Data Source={2};Mode=ReadWrite;Extended Properties="Excel {1};HDR={3};IMEX=1;"";
internal DataTable tableNames;
internal OleDbConnection oleCon;
private string conStr;
public OleBase(string connectionString) {
conStr = connectionString;
// Using the debugger, conStr is:
// "Provider=Microsoft.ACE.OLEDB.12.0;" +
// "Data Source=C:\Users\cp-jpool\Documents\Ecat5.xlsx;" +
// "Mode=ReadWrite;Extended Properties="Excel 12.0;HDR=Yes;IMEX=1;""
object[] param = new object[] { null, null, null, "TABLE" };
oleCon = new OleDbConnection(conStr);
oleCon.Open();
tableNames = oleCon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, param);
}
If the Excel file does NOT exist, whenever I call Open()
I get the following OleDbException:
"The Microsoft Access database engine could not find the object 'C:Userscp-jpoolDocumentsEcat5.xlsx'. Make sure the object exists and that you spell its name and the path name correctly. If 'C:Userscp-jpoolDocumentsEcat5.xlsx' is not a local object, check your network connection or contact the server administrator."
So, the file does not exist, huh? Well, I tried creating it by modifying my CTor()
to be:
public OleBase(string connectionString) {
conStr = connectionString;
object[] param = new object[] { null, null, null, "TABLE" };
oleCon = new OleDbConnection(conStr);
if (-1 < conStr.IndexOf(";IMEX=1;")) {
string dsString = "Data Source=";
int dsIndex = conStr.IndexOf(dsString);
string conSub = conStr.Substring(dsIndex + dsString.Length);
int firstCol = conSub.IndexOf(';');
string xlPath = conSub.Substring(0, firstCol);
if (!File.Exists(xlPath)) {
File.Create(xlPath);
}
}
oleCon.Open();
tableNames = oleCon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, param);
}
Now whenever this code attempts to call the Open()
method of the OleDbConnection, I get this different OleDbException:
"The Microsoft Access database engine cannot open or write to the file ''. It is already opened exclusively by another user, or you need permission to view and write its data."
I even tried creating the Excel file using a StreamWriter to populate it with basic headers:
public OleBase(string connectionString) {
conStr = connectionString;
object[] param = new object[] { null, null, null, "TABLE" };
oleCon = new OleDbConnection(conStr);
if (-1 < conStr.IndexOf(";IMEX=1;")) {
string dsString = "Data Source=";
int dsIndex = conStr.IndexOf(dsString);
string conSub = conStr.Substring(dsIndex + dsString.Length);
int firstCol = conSub.IndexOf(';');
string xlPath = conSub.Substring(0, firstCol);
using (StreamWriter xls = new StreamWriter(xlPath, false, Encoding.UTF8)) {
xls.WriteLine("<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?>");
xls.WriteLine("<ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" ");
xls.WriteLine("xmlns:o="urn:schemas-microsoft-com:office:office" ");
xls.WriteLine("xmlns:x="urn:schemas-microsoft-com:office:excel" ");
xls.WriteLine("xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">");
xls.WriteLine("<ss:Styles>");
xls.WriteLine("<ss:Style ss:ID="Default" ss:Name="Normal"><ss:Alignment ss:Vertical="Bottom"/><ss:Borders/><ss:Font/><ss:Interior/><ss:NumberFormat/><ss:Protection/></ss:Style>");
xls.WriteLine("<ss:Style ss:ID="BoldColumn"><ss:Font x:Family="Swiss" ss:Bold="1"/></ss:Style>");
xls.WriteLine("<ss:Style ss:ID="StringLiteral"><ss:NumberFormat ss:Format="@"/></ss:Style>");
xls.WriteLine("<ss:Style ss:ID="Decimal"><ss:NumberFormat ss:Format="0.0000"/></ss:Style>");
xls.WriteLine("<ss:Style ss:ID="Integer"><ss:NumberFormat ss:Format="0"/></ss:Style>");
xls.WriteLine("<ss:Style ss:ID="DateLiteral"><ss:NumberFormat ss:Format="mm/dd/yyyy;@"/></ss:Style>");
xls.WriteLine("</ss:Styles>");
xls.WriteLine("</ss:Workbook>");
xls.Flush();
xls.Close();
}
}
oleCon.Open();
tableNames = oleCon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, param);
}
This code generated yet another OleDbException message:
"External table is not in the expected format."
That I can see, OleDbConnection does not have a method of creating the file, so how do I CREATE this Excel file so that I can use it?
See Question&Answers more detail:os