C# removing unicode character - c#

I'm attempting to insert text data from an Excel worksheet in to a MS SQL table using the C# sqlBulkCopy class. The problem I'm having is I get the notorious Received an invalid column length from the bcp client for colid 6 error. I later find out that the real problem is Excel Unicode formatting within the notes texts. if I just enter notes into the Excel cells the data insert works, otherwise it fails. Here is the code I'm attempting use in my C# script:
SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(DBconn.ConnectionString);
{
sqlBulkCopy.DestinationTableName = "##MasterFileTemp";
foreach (DataColumn dc in MasterFileTemp.Columns)
{
for (int j = 1; j < MasterFileTemp.Rows.Count - 1; j++)
{
if (MasterFileTemp.Rows[0][dc].ToString() == "Notes")
{
int pos = dc.Ordinal;
string dataText = Regex.Replace(MasterFileTemp.Rows[j][pos].ToString(), #"[^\u0000-\u007F]", string.Empty);
MasterFileTemp.Rows[j][pos] = dataText;
MasterFileTemp.AcceptChanges();
MessageBox.Show(MasterFileTemp.Rows[j][pos].ToString());
}
}
}
sqlBulkCopy.WriteToServer(MasterFileTemp);
This is what the Excel text data looks like, notice the leading and trailing double quotes generated by Excel:
" -If additional information is needed, contact the partner requester on the Service Order Tab within the work space. For any other operational issues, email James
**Service requests include Portfolio Management (Watch list), Foreclosure, Pre-Foreclosure, Other Real Estate Owned (OREO), Asset Valuation only (no loan)
"
string strCn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1;\";";
string GetExcelData = "Select * From [" + tabName + "A23:Z100]";
OleDbConnection cn = new OleDbConnection(strCn);
OleDbDataAdapter objAdapter2 = new OleDbDataAdapter(GetExcelData, cn);
DataSet ds2 = new DataSet();
objAdapter2.Fill(ds2, "dSheet1");
DataTable dt2 = ds2.Tables["dSheet1"];
Here the entired code:
namespace ST_426cda87cffe4ef6a10722ecf5f7fe65.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook excelBook = xlApp.Workbooks.Open(Dts.Variables["User::MasterFileTemplate"].Value.ToString(),
0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
String[] excelSheets = new String[excelBook.Worksheets.Count];
int z = 0;
foreach (Microsoft.Office.Interop.Excel.Worksheet wSheet in excelBook.Worksheets)
{
excelSheets[z] = wSheet.Name;
z++;
}
excelBook.Close(false, Dts.Variables["User::MasterFileTemplate"].Value.ToString(), Missing.Value);
xlApp.Quit();
process_worksheets(excelSheets);
}
public void process_worksheets(string[] wsheets)
{
int r;
string[] vars = new string[1];
string field;
string filePath = (Dts.Variables["User::MasterFileTemplate"].Value.ToString());
string DataServer = (Dts.Variables["User::DataServer"].Value.ToString());
string strCn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1;\";";
for (r=0; r < wsheets.Length; r++)
{
string tabName = wsheets[r].ToString() + "$";
string GetExcelDate = "Select * From [" + tabName + "A15:B16]"; //This is the Excel line number for Prod Completed date and Completed by
string GetExcelData = "Select * From [" + tabName + "A23:Z100]"; //This is the Excel line number where the header columns and data start
OleDbConnection cn = new OleDbConnection(strCn);
SqlConnection DBconn = new SqlConnection();
DBconn.ConnectionString = "Data Source="+DataServer + ";Initial Catalog=FNC;" + "Integrated Security=SSPI";
OleDbDataAdapter objAdapter = new OleDbDataAdapter(GetExcelDate, cn);
// This Dataset contains the header columns and data
DataSet ds = new DataSet();
objAdapter.Fill(ds, "dSheet1");
DataTable dt = ds.Tables["dSheet1"];
///**** Parse Excel Serial Date ***/
string dtt = (dt.Rows[0][1].ToString());
DateTime signoffDte = DateTime.Parse(dtt);
DateTime currentDte = System.DateTime.Today;
/// Check to see if Production sign-off date is less than current date and signed by is empty
if ((signoffDte > currentDte) || (dt.Rows[1][1].ToString() == ""))
{
// MessageBox.Show(tabName.ToString() + "Date requirment Failed..processing next");
continue; //Skip worksheet if Production signoff date or signature is invalid
}
else
{
//This Dataset contains the header columns and data
OleDbDataAdapter objAdapter2 = new OleDbDataAdapter(GetExcelData, cn);
DataSet ds2 = new DataSet();
objAdapter2.Fill(ds2, "dSheet1");
DataTable dt2 = ds2.Tables["dSheet1"];
DataTable dth = dt2.Clone();
dth.ImportRow(dt2.Rows[0]);
/*** Create Master File Temp Table from Excel Template source file ***/
CreateTempTableAndBulkCopyData(dt2,DBconn);
/*****************************************************************************/
/* Loop thru Excel Template File and only select the first row (Headers) */
/*****************************************************************************/
for (int i = 0; i < 1; i++) //Gets first row "A1:Z1" (column headers of excel spreadsheet)
{
// y=3 is static and must not be changed. This sets Partner_org_PK,Partner_ID,Partner_Name as key columns to perform SQL JOIN on
for (int y = 3; y < dth.Columns.Count; y++)
{
field = dth.Rows[0][y].ToString();
vars[0] = field;
UpdateMasterFileTable(DBconn, vars, dth); // Performs an update to the Partner Profile Table via a join on the Master File Temp table
}
UpdateValidation(DBconn, dth, tabName);
}
ds.Clear();
ds2.Clear();
dt.Clear();
dth.Clear();
cn.Close();
DBconn.Close();
Dts.TaskResult = (int)ScriptResults.Success;
}
MessageBox.Show("Processed......" + tabName.ToString());
System.Threading.Thread.Sleep(3000);
}
}
/**************************************************************************************************/
/* Creates Master File Global Temp Table ###MasterFileTemp and Bulk Copy Excel data into it */
/**************************************************************************************************/
public static void CreateTempTableAndBulkCopyData(DataTable dt2, SqlConnection DBconn)
{
DataTable MasterFileTemp = dt2;
string createTempTable = "CREATE TABLE ##MasterFileTemp(";
foreach (DataColumn dc in MasterFileTemp.Columns)
{
createTempTable += MasterFileTemp.Rows[0][dc] + " Varchar(255),";
}
createTempTable = createTempTable.Remove(createTempTable.Length - 1); //remove trailing, unecessary comma
createTempTable += ")"; // cap-off with ")" to complete the CREATE ##TEMP TABLE DDL
{
//Create temp table command
SqlCommand command = new SqlCommand(createTempTable, DBconn);
DBconn.Open();
command.ExecuteNonQuery();
MessageBox.Show(createTempTable.ToString());
//Copy the DataTable to SQL Server Table using SqlBulkCopy
SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(DBconn.ConnectionString);
{
sqlBulkCopy.DestinationTableName = "##MasterFileTemp";
foreach (DataColumn dc in MasterFileTemp.Columns)
{
for (int j = 1; j < MasterFileTemp.Rows.Count - 1; j++)
{
if (MasterFileTemp.Rows[0][dc].ToString() == "Notes")
{
int pos = dc.Ordinal;
string dataText = MasterFileTemp.Rows[j][pos].ToString().Replace("\r\n", String.Empty);
MasterFileTemp.Rows[j][pos] = dataText;
MasterFileTemp.AcceptChanges();
//MessageBox.Show(MasterFileTemp.Rows[j][pos].ToString());
}
}
}
sqlBulkCopy.WriteToServer(MasterFileTemp);
}
}
}
/**************************************************************************************************/
/* Performs an up to the Partner Profile Table via a UPDATE join on the Master File Temp table */
/**************************************************************************************************/
public void UpdateMasterFileTable(SqlConnection DBconn, string[] vars, DataTable dth)
{
string[] upvariable = vars;
string sqlUpate = "UPDATE [dbo].[xstg_Partner_Profile]" +
" SET [dbo].[xstg_Partner_Profile]." + upvariable[0] + "=##MasterFileTemp." + upvariable[0] +
" FROM ##MasterFileTemp" +
" WHERE [dbo].[xstg_Partner_Profile].Partner_Id= ##MasterFileTemp." + dth.Rows[0][1].ToString() +
" AND [dbo].[xstg_Partner_Profile].Partner_Name= ##MasterFileTemp." + dth.Rows[0][2].ToString();
SqlCommand command = new SqlCommand(sqlUpate, DBconn);
command.ExecuteNonQuery();
MessageBox.Show(sqlUpate.ToString());
}
/**************************************************************************************************/
/* Performs the update validation against production 90100 UI Report and creates Excel mismatch */
/* output for each worksheet tab in masterfileupdate template
/**************************************************************************************************/
public void UpdateValidation(SqlConnection DBconn, DataTable dth, string tabName)
{
string SelectSQL;
string SelectFields=null;
for (int x = 3; x < dth.Columns.Count; x++)
{
SelectFields += " p2." +dth.Rows[0][x]+ ", ";
}
SelectFields = SelectFields.Remove(SelectFields.Length - 2); //remove trailing comma
SelectSQL = "SELECT p2.Partner_ID, p2.Partner_Name,";
SelectSQL += SelectFields;
string ValidationSQL = " FROM (select * from dbo.Partner_Profile_CMS_Settings) p1" +
" FULL OUTER JOIN (Select * from dbo.xstg_Partner_Profile) p2" +
" ON p1.Partner_ID = p2.Partner_ID and p1.Partner_Name=p2.Partner_Name" +
" WHERE";
SelectSQL += ValidationSQL; //Append select statement as one
string ValidationSQLWhere=null;
for (int y = 3; y < dth.Columns.Count; y++) //loop through data columns to get columns for update - mismatch. This is dynamic and makes up the Where clause
{
ValidationSQLWhere += " (P1."+dth.Rows[0][y]+" <> p2."+dth.Rows[0][y]+") OR";
}
ValidationSQLWhere = ValidationSQLWhere.Remove(ValidationSQLWhere.Length - 2); //Remove "OR" two characters from the select statement where clause
SelectSQL += ValidationSQLWhere; //Append Where clause string to main Select string
MessageBox.Show("Validating... " + tabName); //Display entire string
//Build SQL connection to run mismatch query, passing in SELECT statement above
SqlDataAdapter VSAdapter = new SqlDataAdapter(SelectSQL, DBconn);
// This Dataset contains Vaildate data
DataSet validateDs = new DataSet();
VSAdapter.Fill(validateDs, "VSheet1");
DataTable validationTemp = validateDs.Tables["VSheet1"];
String currentDate = DateTime.Now.ToString("MMddyyyy");
String outputStatus="Validation is 100% accurate";
/* Set up Excel workbook instance and loop through each worksheet avaialble file output */
/****************************************************************************************/
Excel.Application oXL = new Excel.ApplicationClass();
oXL.DisplayAlerts = false;
Excel.Workbooks oWBs = oXL.Workbooks;
Excel.Workbook oWB = null;
Excel.Worksheet oSheet;
tabName = tabName.Remove(tabName.Length-1); //remove training '$' from mismatch worksheets
/* If the mismatch output file does not exist, create mismatch file and write out first worksheet */
if (!File.Exists(Dts.Variables["User::MismatchOutputFile"].Value.ToString()))
{
oWB = oXL.Workbooks.Add(Missing.Value);
// Get the active sheet
oSheet = (Excel.Worksheet)oWB.Worksheets.get_Item(1);
oSheet.Name = tabName;
int rowCount = 0;
if (validationTemp.Rows.Count >= 1)
{
foreach (DataRow dr in validationTemp.Rows)
{
rowCount += 1;
for (int i = 1; i < validationTemp.Columns.Count + 1; i++)
{
// Add the header time first only
if (rowCount == 2)
{
oSheet.Cells[1, i] = validationTemp.Columns[i - 1].ColumnName;
}
oSheet.Cells[rowCount, i] = dr[i - 1].ToString();
}
}
}
else
{
// MessageBox.Show("Validation is 100% accurate");
oSheet.Cells[rowCount, 2] = outputStatus.ToString();
}
oWB.SaveAs(Dts.Variables["User::MismatchOutputFile"].Value.ToString(), Excel.XlFileFormat.xlWorkbookNormal,
Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Excel.XlSaveAsAccessMode.xlShared,
Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value);
}
else /* If mismatch file already exists, loop thru and append additional worksheets */
{
System.Threading.Thread.Sleep(1000);
try
{
oXL.DisplayAlerts = false;
Excel.Sheets xlSheets = null;
oWB = oXL.Workbooks.Open(Dts.Variables["User::MismatchOutputFile"].Value.ToString(),
Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value, Missing.Value);
xlSheets = (Excel.Sheets)oWB.Sheets;
oSheet = (Excel.Worksheet)xlSheets.Add(Type.Missing, xlSheets[1], Type.Missing, Type.Missing);
oSheet.Name = tabName;
int rowCount = 0;
if (validationTemp.Rows.Count > 1)
{
foreach (DataRow dr in validationTemp.Rows)
{
rowCount += 1;
for (int i = 1; i < validationTemp.Columns.Count + 1; i++)
{
// Add the header time first only
if (rowCount == 2)
{
oSheet.Cells[1, i] = validationTemp.Columns[i - 1].ColumnName;
}
oSheet.Cells[rowCount, i] = dr[i - 1].ToString();
}
}
}else
{
// MessageBox.Show("Validation is 100% accurate");
oSheet.Cells[rowCount, 2] = outputStatus.ToString();
}
oWB.SaveAs(Dts.Variables["User::MismatchOutputFile"].Value.ToString(), Excel.XlFileFormat.xlWorkbookNormal,
Missing.Value, Missing.Value, Missing.Value, Missing.Value,
Excel.XlSaveAsAccessMode.xlExclusive,
Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value);
oWB.Close(true, Dts.Variables["User::MismatchOutputFile"].Value.ToString(), Type.Missing);
oWBs.Close();
oXL.Quit();
Marshal.ReleaseComObject(oXL);
}
finally
{
}
}
}
}
}

You are saying Excel, but your code is using a DataTable. Why wouldn't you directly SqlBulkCopy from the Excel itself?
Instead of using a global temp table, you could SqlBulkCopy to a local temp table, setting the text fields' datatype to NVarchar(max) and you shouldn't have a problem. SQL server supports unicode.
Edit: Ahha, I think now I see where you are going wrong. "Excel generated text data" you say. Is that a CSV file? Excel doesn't know how to save a legal CSV in the first place. Don't save to a text file. If you do, then there isn't an 'importer' that could read that data back right. Instead directly SqlBulkCopy from Excel without using any other intermediate text file or datatable.

Issue resolved. I identified that the column sizes where too small to accomodate the sqlBlkCopy operation. Change the size from varchar(255) to varchar(2000)

Related

How can I add Arabic content from Excel file into SQL Server database? [duplicate]

This question already has answers here:
store arabic in SQL database
(9 answers)
Closed 5 years ago.
I have an issue about how SQL Server doesn't recognize Arabic language even if I have field as nvarchar(MAX) and even if I add N' before value in my SQL query.
This is my table in database:
Id_Test : int
Arabic : nvarchar(MAX)
and after importing my Excel file containing Arabic, this what I have get:
Id_Test | Arabic
--------+-----------------------
1 | ?????????????????????
Here is my code:
private void Button_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openfile = new OpenFileDialog();
openfile.DefaultExt = ".xlsx";
openfile.Filter = "(.xlsx)|*.xlsx";
//openfile.ShowDialog();
var browsefile = openfile.ShowDialog();
if (browsefile == true)
{
txtFilePath2.Text = openfile.FileName;
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
//Static File From Base Path...........
//Microsoft.Office.Interop.Excel.Workbook excelBook = excelApp.Workbooks.Open(AppDomain.CurrentDomain.BaseDirectory + "TestExcel.xlsx", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
//Dynamic File Using Uploader...........
Microsoft.Office.Interop.Excel.Workbook excelBook = excelApp.Workbooks.Open(txtFilePath2.Text.ToString(), 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
Microsoft.Office.Interop.Excel.Worksheet excelSheet = (Microsoft.Office.Interop.Excel.Worksheet)excelBook.Worksheets.get_Item(1); ;
Microsoft.Office.Interop.Excel.Range excelRange = excelSheet.UsedRange;
string strCellData = "";
double douCellData;
int rowCnt = 0;
int colCnt = 0;
DataTable dt = new DataTable();
for (colCnt = 1; colCnt <= excelRange.Columns.Count; colCnt++)
{
string strColumn = "";
strColumn = (string)(excelRange.Cells[1, colCnt] as Microsoft.Office.Interop.Excel.Range).Value2;
dt.Columns.Add(strColumn, typeof(string));
}
for (rowCnt = 2; rowCnt <= excelRange.Rows.Count; rowCnt++)
{
string strData = "";
for (colCnt = 1; colCnt <= excelRange.Columns.Count; colCnt++)
{
try
{
strCellData = (string)(excelRange.Cells[rowCnt, colCnt] as Microsoft.Office.Interop.Excel.Range).Value2;
strData += strCellData + "|";
}
catch (Exception ex)
{
douCellData = (excelRange.Cells[rowCnt, colCnt] as Microsoft.Office.Interop.Excel.Range).Value2;
strData += douCellData.ToString() + "|";
}
}
strData = strData.Remove(strData.Length - 1, 1);
dt.Rows.Add(strData.Split('|'));
}
dtGrid2.ItemsSource = dt.DefaultView;
string sql = "";
for (int i = 0; i < dt.Rows.Count; i++)
{
sql = sql + "insert into Test (Arabic) values('"
+ dt.Rows[i]["Arabic"].ToString().Replace("'", "''") + "')";
}
using (SqlConnection connection = new SqlConnection(_ConnectionString))
{
connection.Open();
//if (_serv.ServeurID == 0) throw new Exception("record does not exist in dataserveur table.");
SqlCommand cmd = new SqlCommand(sql, connection);
cmd.ExecuteNonQuery();
connection.Close();
}
excelBook.Close(true, null, null);
excelApp.Quit();
}
}
This is what I have changed before but it's not working:
+ dt.Rows[i]["Arabic"].ToString().Replace("N'", "''") + "')";
Thank you.
if the column is to always have arabic in it, then you need to adjust the columns collation to
Arabic_CI_AI_KS_WS

how can we avoid readonly of the excel file during the writestream to excel from c# , if the excel file is open?

during writing values to an excel from c#, at the same time the excel file is open it shows the error that the file is in readonly , so how can we able to avoid that error during write stream from c# to the Excel
//Get all the sheets in the workbook
mWorkSheets = mWorkBook.Worksheets;
//Get the allready exists sheet
mWSheet1 = (Microsoft.Office.Interop.Excel.Worksheet)mWorkSheets.get_Item("Sheet1");
Microsoft.Office.Interop.Excel.Range range = mWSheet1.UsedRange;
int colCount = range.Columns.Count;
int rowCount = range.Rows.Count+1;
for (int index = 0; index < NoOfRecords; index++)
{
for (int j = 0; j < colCount; j++)
{
mWSheet1.Cells[(rowCount) + index, j + 1] ="'"+Convert.ToString(ResultsData.Rows[index][j].ToString());
}
}
mWorkBook.SaveAs(path, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal,
Missing.Value, Missing.Value, Missing.Value, Missing.Value, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive,
Missing.Value, Missing.Value, Missing.Value,
Missing.Value, Missing.Value);
mWorkBook.Close(Missing.Value, Missing.Value, Missing.Value);
The easiest way is to SAVEAS to a different file name, then delete the original file on successful save. Like open MySheet.XLSX and save MySheet_Updated.XLSX
string newPath = path.Replace(Path.GetFileNameWithoutExtension(path),Path.GetFileNameWithoutExtension(path)+"_Updated)";
try{
mWorkBook.SaveAs(newPath,Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive,Missing.Value,Missing.Value,Missing.Value,Missing.Value, Missing.Value);
mWorkBook.Close(Missing.Value, Missing.Value, Missing.Value);
File.Delete(path);
File.Move(newPath,path);
}
catch(Exception e){
Console.WriteLine(e.Message+"\n"+e.Source);
}
public System.Data.DataTable CorruptedExcel(string path, string savedFile) {
try
{
Missing missing = Missing.Value;
Excel.Application excel = new Excel.Application();
Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Open(path, CorruptLoad: Microsoft.Office.Interop.Excel.XlCorruptLoad.xlRepairFile);
var connectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + path + ";Extended Properties=\"Excel 8.0;HDR=YES;TypeGuessRows=0;ImportMixedTypes=Text\"";
//var connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=\"Excel 12.0;IMEX=1;HDR=NO;TypeGuessRows=0;ImportMixedTypes=Text\""; ;
using (var conn = new OleDbConnection(connectionString))
{
conn.Open();
var sheets = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT * FROM [" + sheets.Rows[0]["TABLE_NAME"].ToString() + "] ";
var adapter = new OleDbDataAdapter(cmd);
adapter.Fill(dt);
}
}
return dt;
}
catch (Exception e)
{
throw new Exception("ReadingExcel: Excel file could not be read! Check filepath.\n"
+ e.Message + e.StackTrace);
}
}

Saving data from SQL query in excel in C# console app

I have a c# program.cs code which is created to save results from sql query to xls file, the problem is that I have two sql query and there are two result sets which need to written to the excel file, I am able to write the 1st result through the below code but not able to write the second result, can you please help on this? Please see my code below, I am using same code block for both the queries but always seem to get results from 1st query.
static void Main(string[] args)
{
//SqlConnection cnn;
//string connectionstring = null;
string connectionstring = "Integrated Security = SSPI;Initial Catalog=Database; Data Source=<Instance Name>;";
string sql1 = null;
string sql2 = null;
string data = null;
string data1 = null;
int i = 0;
int j = 0;
string Filename = #"E:\file\testfile.xls";
if (!File.Exists(Filename))
{
File.Create(Filename).Dispose();
using (TextWriter tw = new StreamWriter(Filename))
{
tw.WriteLine("The very first line!");
tw.Close();
}
}
////*** Preparing excel Application
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
///*** Opening Excel application
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(Filename);
xlWorkSheet = (Excel.Worksheet)(xlWorkBook.ActiveSheet as Excel.Worksheet);
xlApp.DisplayAlerts = false;
SqlConnection conn = new SqlConnection(connectionstring);
//cnn = new SqlConnection(connectionstring);
conn.Open();
////** Write your Sql Query here
sql1 = "Select top 5 DocumentId, DocFileName from <table> order by CreateDate desc";
sql2 = "Select top 5 DocID, Title from <Table> order by CreateDate desc";
///*** Preparing to retrieve value from the database
SQL.DataTable dtable = new SQL.DataTable();
SqlDataAdapter dscmd = new SqlDataAdapter(sql1, conn);
SQL.DataSet ds = new SQL.DataSet();
dscmd.Fill(dtable);
////*** Generating the column Names here
string[] colNames = new string[dtable.Columns.Count];
int col = 0;
foreach (SQL.DataColumn dc in dtable.Columns)
colNames[col++] = dc.ColumnName;
char lastColumn = (char)(65 + dtable.Columns.Count - 1);
xlWorkSheet.get_Range("A1", lastColumn + "1").Value2 = colNames;
xlWorkSheet.get_Range("A1", lastColumn + "1").Font.Bold = true;
xlWorkSheet.get_Range("A1", lastColumn + "1").VerticalAlignment
= Excel.XlVAlign.xlVAlignCenter;
/////*** Inserting the Column and Values into Excel file
for (i = 0; i <= dtable.Rows.Count - 1; i++)
{
for (j = 0; j <= dtable.Columns.Count - 1; j++)
{
data = dtable.Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[i + 2, j + 1] = data;
xlWorkBook.Save();
}
}
//Enter new block in Excel -- for the second query, I need help here below
SQL.DataTable dtable1 = new SQL.DataTable();
SqlDataAdapter dscmd1 = new SqlDataAdapter(sql2, conn);
SQL.DataSet ds1 = new SQL.DataSet();
dscmd1.Fill(dtable1);
////*** Generating the column Names here
string[] colNames1 = new string[dtable1.Columns.Count];
int col1 = 0;
foreach (SQL.DataColumn dc in dtable1.Columns)
colNames1[col1++] = dc.ColumnName;
char lastColumn1 = (char)(68 + dtable1.Columns.Count - 1);
xlWorkSheet.get_Range("D1", lastColumn1 + "1").Value2 = colNames1;
xlWorkSheet.get_Range("D1", lastColumn1 + "1").Font.Bold = true;
xlWorkSheet.get_Range("D1", lastColumn1 + "1").VerticalAlignment
= Excel.XlVAlign.xlVAlignCenter;
/////*** Inserting the Column and Values into Excel file
for (i = 0; i <= dtable1.Rows.Count - 1; i++)
{
for (j = 0; j <= dtable1.Columns.Count - 1; j++)
{
data1 = dtable1.Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[i + 2, j + 1] = data1;
xlWorkBook.Save();
}
}
//end of block
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
}
Image from Excel result

How to convert datatype before Importing Excel file to Sql database

Here I have this Import from excel file to sql database class. It was working correctly till now but as my excel file cells are all strings type , So when Importing , the datatype does not match as sql database. How to convert it to their respective datatype before importing?
public static void ImportToSql(string excelfilepath)
{
string myexceldataquery = "select LocalSKU,ItemName, QOH,Price,Discontinued,Barcode,Integer2,Integer3,SalePrice,SaleOn,Price2 from [sheet1$]";
try
{
string sexcelconnectionstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source =" + excelfilepath + "; Extended Properties=\"Excel 12.0; HDR=Yes; IMEX=2\"";
string ssqlconnectionstring = "Data Source=DELL\\SQLSERVER1;Trusted_Connection=True;DATABASE=Test;CONNECTION RESET=FALSE";
SqlConnection sqlconn = new SqlConnection(ssqlconnectionstring);
//series of commands to bulk copy data from the excel file into our sql table
OleDbConnection oledbconn = new OleDbConnection(sexcelconnectionstring);
OleDbCommand oledbcmd = new OleDbCommand(myexceldataquery, oledbconn);
oledbconn.Open();
OleDbDataReader dr = oledbcmd.ExecuteReader();
SqlCommand sqlcmd = new SqlCommand(#"MERGE Inventory AS target
USING (select LocalSKU,ItemName, QOH,Price,Discontinued,Barcode,Integer2,Integer3,SalePrice,SaleOn,Price2 from #source) as source
ON (source.LocalSKU = target.LocalSKU)
WHEN MATCHED THEN
UPDATE SET ItemName=source.ItemName,Price=source.Price,Discontinued=source.Discontinued,Barcode=source.Barcode,Integer2=source.Integer2,Integer3 = source.QOH,SalePrice=source.SalePrice,SaleOn=source.SaleOn,Price2=source.Price2;", sqlconn);
SqlParameter param;
param = sqlcmd.Parameters.AddWithValue("#source",dr);
param.SqlDbType = SqlDbType.Structured;
param.TypeName = "dbo.InventoryType";
sqlconn.Open();
sqlcmd.ExecuteNonQuery();
sqlconn.Close();
while (dr.Read())
{
}
oledbconn.Close();
Console.WriteLine(".xlsx file imported succssessfully into database.");
}
The easiest thing to do would be to convert them in your SQL statement by using CAST:
SqlCommand sqlcmd = new SqlCommand(
#"MERGE Inventory AS target
USING (select LocalSKU, ItemName, QOH = CAST(QOH AS int)
, Price = CAST(Price AS decimal(10,2)), Discontinued = CAST(Discontinued AS bit)
, Barcode, Integer2 = CAST(Integer2 AS int)
, Integer3 = CAST(Integer3 AS int), SalePrice = CAST(SalePrice AS decimal(10,2))
, SaleOn, Price2 = CAST(Price2 AS decimal(10,2)) from #source) as source
ON (source.LocalSKU = target.LocalSKU)
WHEN MATCHED THEN
UPDATE (. . . )
I'm guessing on some of the conversions, but you get the idea. You'll need to make sure that the data in the spreadsheet all match the datatypes you want to convert them to, as one mistake will cause the whole statement to fail. Something more robust will take a lot more code.
First browse the excel file and put data in datagrid and then read datagrid row one by one.
i give you 2 function for that. one is browse the excel file and put data in datagrid and second one is read datagrid and put record in database
Excel Export Function
private void export_btn_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel.Application ExcelApp =
new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook ExcelBook;
Microsoft.Office.Interop.Excel._Worksheet ExcelSheet;
int i = 0;
int j = 0;
//create object of excel
ExcelBook = (Microsoft.Office.Interop.Excel._Workbook)ExcelApp.Workbooks.Add(1);
ExcelSheet = (Microsoft.Office.Interop.Excel._Worksheet)ExcelBook.ActiveSheet;
//export header
for (i = 1; i <= this.dataGridView1.Columns.Count; i++)
{
ExcelSheet.Cells[1, i] = this.dataGridView1.Columns[i - 1].HeaderText;
}
//export data
for (i = 1; i <= this.dataGridView1.RowCount; i++)
{
for (j = 1; j <= dataGridView1.Columns.Count; j++)
{
ExcelSheet.Cells[i + 1, j] = dataGridView1.Rows[i - 1].Cells[j - 1].Value;
}
}
ExcelApp.Visible = true;
//set font Khmer OS System to data range
Microsoft.Office.Interop.Excel.Range myRange = ExcelSheet.get_Range(
ExcelSheet.Cells[1, 1],
ExcelSheet.Cells[this.dataGridView1.RowCount + 1,
this.dataGridView1.Columns.Count]);
Microsoft.Office.Interop.Excel.Font x = myRange.Font;
x.Name = "Arial";
x.Size = 10;
//set bold font to column header
myRange = ExcelSheet.get_Range(ExcelSheet.Cells[1, 1],
ExcelSheet.Cells[1, this.dataGridView1.Columns.Count]);
x = myRange.Font;
x.Bold = true;
//autofit all columns
myRange.EntireColumn.AutoFit();
ExcelApp.ActiveWorkbook.SaveCopyAs("E:\\reports.xlsx");
ExcelApp.ActiveWorkbook.Saved = true;
ExcelApp.Quit();
MessageBox.Show("Excel file created,you can find the file E:\\reports.xlsx");
//
ExcelSheet = null;
ExcelBook = null;
ExcelApp = null;
}
Read Datagrid
public void readDataGrid()
{
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
try
{
//Here read one by one cell and convert it into your required datatype and store it in
String rowcell1 = dataGridView1.Rows[i].Cells[0].Value.ToString();
}
catch (Exception err)
{
}
count++;
}
}
I this is help you.

Import image from Excel sheet into SQL Server table C#

Here I want to insert all the data from my excel sheet into the SQL Server Table using C# code
I have the Excel sheet with data like this
ID Name Designation ProfilePicture
--------------------------------------------
1 ABC Manager C:\Pictures\1.jpg
2 DEF Asst.Manager C:\Pictures\2.jpg
And I have the Code to Insert the Datas into the Table
String filePath = filePathText.Text;
String fileExtension = "Excel 12.0";
if (filePath != null)
{
String xlsConnection = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=" + "\"" + fileExtension + ";HDR=YES;\"";
String sqlConnection = "Your Connection String";
//Connection to Excel work book
OleDbConnection xlsConnectionString = new OleDbConnection(xlsConnection);
//Fetch data from Excel
OleDbCommand cmd = new OleDbCommand("Select [ID],[Name],[Designation],[ProfilePicture] from [Sheet1$]", xlsConnectionString);
xlsConnectionString.Open();
OleDbDataReader dReader;
dReader = cmd.ExecuteReader();
SqlBulkCopy sqlBulk = new SqlBulkCopy(sqlConnection);
//Destination table name
sqlBulk.DestinationTableName = "EXCEL_DATA";
sqlBulk.WriteToServer(dReader);
xlsConnectionString.Close();
}
This piece of code is run, if I click the button.
My Question is, How can I upload the picture from Excel Sheet (Sheet have the path of the image). to SQL Server Table. I want to get the picture by using the Imagepath provided in Excel Sheet and store it as varbinary(MAX) in SQL Server.
Thanks for the guys who really works to post the answer. Finally I got the solution to the problem myself.
Here is the code that helps to insert the images into the SQL Server by using the Path provided in Excel sheet.
private void insert_Click(object sender, EventArgs e)
{
UInt64 ID = 0;
String Name = String.Empty;
String Designation = String.Empty;
String ProfilePicture = String.Empty;
String filePath = filePathText.Text;
Excel.Application xlApp = null;
Excel.Workbook xlWorkbook = null;
Excel._Worksheet xlWorksheet = null;
Excel.Range xlRange = null;
String sqlConnectionString = "Your Connection String goes here";
String insertRecord = "INSERT_USER_RECORDS";
SqlConnection sqlConnection = new SqlConnection(sqlConnectionString);
SqlCommand sqlCommand = new SqlCommand(insertRecord, sqlConnection);
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlConnection.Open();
if (filePath != null)
{
try
{
xlApp = new Excel.Application();
xlWorkbook = xlApp.Workbooks.Open(filePath);
xlWorksheet = (Excel._Worksheet)xlWorkbook.Sheets[1];
xlRange = xlWorksheet.UsedRange;
int rowCount = xlRange.Rows.Count;
int colCount = xlRange.Columns.Count;
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= colCount; col++)
{
MessageBox.Show((xlRange.Cells[row, col] as Microsoft.Office.Interop.Excel.Range).Value2.ToString());
// Check xlRange for Every run. And assign values to local variables. Here I just show the values using MsgBox
// If you get the Path of Image then call the function to Convert Image into byte
// Convert Image to Byte Function definition.
/* System.IO.FileStream fs = new System.IO.FileStream(ProfilePicture, System.IO.FileMode.Open);
Byte[] imageAsBytes = new Byte[fs.Length];
fs.Read(imageAsBytes, 0, imageAsBytes.Length);
fs.Close();
return imageAsBytes; */
}
sqlCommand.Parameters.Clear();
sqlCommand.Parameters.Add("#Name", SqlDbType.NVarChar).Value = FirstName;
sqlCommand.Parameters.Add("#Designation", SqlDbType.NVarChar).Value = LastName;
sqlCommand.Parameters.Add("#ProfilePicture", SqlDbType.VarBinary).Value = imageAsBytes;
sqlCommand.Parameters.Add("#ID", SqlDbType.BigInt).Value = ID;
sqlCommand.ExecuteNonQuery();
}
MessageBox.Show(Path.GetFileName(filePath) + "is Successfully imported to SQL Server", "Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
//Release All objects and close the Connection to prevent the Excel file from lock.
sqlConnection.Close();
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.FinalReleaseComObject(xlRange);
Marshal.FinalReleaseComObject(xlWorksheet);
xlWorkbook.Close(Type.Missing, Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(xlWorkbook);
xlApp.Quit();
Marshal.FinalReleaseComObject(xlApp);
}
}
else
{
MessageBox.Show("Please Select the Valid file to import");
}
}
This code works fine and helps me to insert the image into the SQL database from Excel.
No matter about the version of excel file.

Categories